Пример #1
0
        private KeyValuePair<Point?, double?> FindPointSlopeAtHour(Position pos,
		                                                          UTCDate dt)
        {
            UTCDate[] dts = new UTCDate[] {dt.AddHours(-1), dt, dt.AddHours(1)};
            List<Point?> pts = FindPoints(pos, dts);

            Point? prev = pts[0];
            Point? point = pts[1];
            Point? next = pts[2];
            double? slope = null;

            Point? a = null;
            Point? b = null;
            if (point != null) {
                if ((prev != null) && (next != null)) {
                    a = new Nullable<Point>(prev.Value);
                    b = new Nullable<Point>(next.Value);
                } else if ((prev == null) && (next != null)) {
                    a = new Nullable<Point>(point.Value);
                    b = new Nullable<Point>(next.Value);
                } else if ((prev != null) && (next == null)) {
                    a = new Nullable<Point>(prev.Value);
                    b = new Nullable<Point>(point.Value);
                }
            }

            if ((a != null) && (b != null)) {
                slope = ComputeSlope(a.Value, b.Value);
            }
            return new KeyValuePair<Point?,double?>(point, slope);
        }
Пример #2
0
 private static string FormatFilename(string loc, Position pos, UTCDate dt)
 {
     string dt_s = String.Format("{0:0000}-{1:00}-{2:00}",
                                 dt.Year, dt.Month, dt.Day);
     string tm_s = String.Format("{0:00}-{1:00}-{2:00}",
                                 dt.Hour, dt.Minute, dt.Second);
     string loc_s = loc;
     if (loc == String.Empty) {
         string latdir_s = (pos.LatitudeDegree.Direction
                 == PositionDirection.North) ? "N" : "S";
         string lat_s = String.Format("{0}{1:00}-{2:00}-{3:00}",
                                      latdir_s,
                                      pos.LatitudeDegree.Deg,
                                      pos.LatitudeDegree.Min,
                                      pos.LatitudeDegree.Sec);
         string londir_s = (pos.LongitudeDegree.Direction
                 == PositionDirection.East) ? "E" : "W";
         string lon_s = String.Format("{0}{1:00}-{2:00}-{3:00}",
                                      londir_s,
                                      pos.LongitudeDegree.Deg,
                                      pos.LongitudeDegree.Min,
                                      pos.LongitudeDegree.Sec);
         loc_s = String.Format("{0} {1}", lat_s, lon_s);
     }
     string s = String.Format("{0} - {1} {2}", loc_s, dt_s, tm_s);
     return s;
 }
Пример #3
0
        public static void GenerateBitmap(int dim, string path)
        {
            string loc = "Equator";

            // loc: Equator
            Position pos = new Position(Position.LATITUDE_POS,
                                        0, 0, 0,
                                        Position.LONGITUDE_POS,
                                        0, 0, 0);
            // time: Now
            DateTime dt = DateTime.Now;
            UTCDate udt = new UTCDate(0, null,
                                     dt.Year, dt.Month, dt.Day,
                                     dt.Hour, dt.Minute, dt.Second);

            // set up constants
            Colors colors = new Colors();
            string font_face = "Arial";

            // generate base image
            GraphBitmap grbit = new GraphBitmap(true, dim, colors, font_face);
            Bitmap bitmap_plain = grbit.RenderBaseImage(pos, udt);

            // render current day
            Bitmap bitmap = grbit.RenderCurrentDay(bitmap_plain, pos, udt);

            // render caption
            CaptionInfo ci = new CaptionInfo(loc, pos, udt);
            bitmap = grbit.RenderCaption(ci);

            // save
            grbit.SaveBitmap(bitmap, path);
        }
Пример #4
0
 public static string FormatCaptionPosition(Position pos)
 {
     string lat = pos.LatitudeDegree.Print();
     string lon = pos.LongitudeDegree.Print();
     string s = string.Format("coordinates: {0}  {1}", lat, lon);
     return s;
 }
Пример #5
0
        private Point FindMapPoint(Position pos)
        {
            Degree latd = pos.LatitudeDegree;
            Degree lond = pos.LongitudeDegree;

            double lon_val = Position.CollapsePositionUnits(lond.Direction,
                                                            lond.Deg, lond.Min, lond.Sec);
            double lat_val = Position.CollapsePositionUnits(latd.Direction,
                                                            latd.Deg, latd.Min, latd.Sec);

            // handle pivot
            double lon = (lon_val / 3600);
            double lat = -1 * lat_val / 3600;

            if (lon < (-180 + lon_pivot)) {
                lon = (180.0 - lon_pivot) + (180.0 - Math.Abs(lon));
            } else {
                lon -= lon_pivot;
            }

            int px = (int) (map.Origin.X + ((lon / 360.0) * map.Dx));
            int py = (int) (map.Origin.Y + ((lat / 180.0) * map.Dy));

            return new Point(px, py);
        }
Пример #6
0
        private static UTCDate? FindPoint(Position pos, 
		                                  UTCDate? nudt, UTCDate bound, 
		                                  double target, double inc)
        {
            if (nudt != null) {
                UTCDate udt_s = nudt.Value;

                // invariant delta < delta_p ensures convergence
                double delta_p = double.MaxValue;
                double delta = delta_p / 2;

                UTCDate udt = udt_s;
                while (WithinBound(bound, udt, inc) && (delta < delta_p)) {
                    udt = udt.AddSeconds(inc);

                    delta_p = delta;
                    delta = Math.Abs(Compute(pos, udt) - target);
                    inc = (inc > 0 ? 1 : -1) * Math.Max(3, (delta * 150));

                    if (delta < 0.01) {
                        return udt;
                    }
                }
            }
            return null;
        }
Пример #7
0
 public static string FormatPosition(Position pos)
 {
     string lat = pos.LatitudeDegree.Print();
     if (lat.StartsWith(" ")) lat = lat.Remove(0, 1); // leading space
     string lon = pos.LongitudeDegree.Print();
     string s = string.Format("{0}  {1}", lat, lon);
     return s;
 }
Пример #8
0
        private void PlotPositionCursor(Graphics g, 
		                               string location, Position pos, Point point)
        {
            DrawCursor(g, point);

            // print strings
            float font_size = GetCursorFontSize();
            using (SolidBrush brush = new SolidBrush(colors.Text))
            using (Font font = new Font(font_face, font_size, GraphicsUnit.Pixel)) {

                List<string> stack = new List<string>();
                stack.Add(pos.LongitudeDegree.Print());
                stack.Add(pos.LatitudeDegree.Print());
                if ((location != null) && (location != string.Empty)) stack.Add(location);

                // find longest string
                int w = 0;
                foreach (string s in stack) {
                    float wx = g.MeasureString(s, font).Width;
                    if (wx > w) w = (int) wx;
                }

                // font padding
                int margin = (int) ((double) font_size * 0.3);
                int h = (int) font_size * stack.Count;

                // default: upper right
                int da = margin;
                int db = -margin;

                // try lower left
                if (!WithinXBound(point.X, da, w) || !WithinYBound(point.Y, db, h)) {
                    da = -w - margin;
                    db = h + margin;
                }

                // try lower right
                if (!WithinXBound(point.X, da, w) || !WithinYBound(point.Y, db, h)) {
                    da = margin;
                    db = h + margin;
                }

                // try upper left
                if (!WithinXBound(point.X, da, w) || !WithinYBound(point.Y, db, h)) {
                    da = -w - margin;
                    db = -margin;
                }

                // print
                int i = 0;
                foreach (string s in stack) {
                    ++i;
                    g.DrawString(s, font, brush,
                                 point.X + da,
                                 point.Y + db - font_size*i);
                }
            }
        }
Пример #9
0
        public void Update(string location, Position pos)
        {
            this.position = pos;
            this.location = location;

            NullifyFinalizedBitmap();

            RePaint();
        }
Пример #10
0
        public Bitmap RenderBaseImage(Position pos, UTCDate udt)
        {
            bitmap = new Bitmap(dimensions, titleheight+dimensions+captionheight);

            grapher = new Grapher(0, titleheight, dimensions, titleheight+dimensions,
                                  colors, font_face);

            using (Graphics g = Graphics.FromImage(bitmap)) {

                // paint backdrop coordinate system
                grapher.PaintBackdrop(g);

                // plot milestone dates
                int[] days = new int[] {
                     1, 1,    4, 2,    6, 3,    5, 4,    5, 5,     4, 6,
                    21, 6,   21, 7,   20, 8,   19, 9,   19, 10,   18, 11,   21, 12,
                };

                for (int i=0, j=1; j<days.Length; i+=2, j+=2) {
                    UTCDate udt_n = udt.SetDate(days[i], days[j]);

                    // first half
                    Color color = colors.YearFstHalf;
                    if (udt_n.HasDST)
                        color = udt_n.IsDST ? colors.YearFstHalfDst : colors.YearFstHalfStd;
                    // second half
                    if (udt_n >= udt.SetDate(7, 6)) {
                        color = colors.YearSndHalf;
                        if (udt_n.HasDST)
                            color = udt_n.IsDST ? colors.YearSndHalfDst : colors.YearSndHalfStd;
                    }

                    grapher.PlotMilestoneDay(g, color, pos, udt_n);
                }

                // plot analemma curves
                for (int i = 0; i < 24; i++) {
                    grapher.PlotAnalemma(g,
                                         colors.YearFstHalf, colors.YearSndHalf,
                                         colors.YearFstHalfStd, colors.YearFstHalfDst,
                                         colors.YearSndHalfStd, colors.YearSndHalfDst,
                                         pos, udt.SetHour(i));
                }

                // print milestone day labels
                grapher.PrintMilestoneDayLabels(g);

                // print analemma labels
                for (int i = 0; i < 24; i++) {
                    grapher.PrintAnalemmaLabel(g, colors.GraphFg,
                                               pos, udt.SetHour(i));
                }
            }

            return this.bitmap;
        }
Пример #11
0
        public void ReRender(Position pos, UTCDate date)
        {
            this.position = pos;
            this.date = date;

            NullifyBaseImageBitmap();
            NullifyFinalizedBitmap();

            RePaint();
        }
Пример #12
0
 private List<Point?> FindPoints(Position pos, UTCDate[] dts)
 {
     List<Point?> pts = new List<Nullable<Point>>();
     foreach (UTCDate dt in dts)
     {
         SolarPosition sp = Orbit.CalcSolarPosition(pos, dt);
         Point? pt = FindPoint(sp.Azimuth, sp.Elevation);
         pts.Add(pt);
     }
     return pts;
 }
Пример #13
0
        public SolarPosition(Position pos, UTCDate dt, 
							 double jc, double eqtime, double decl, 
							 double az, double el)
        {
            this.pos = pos;
            this.dt = dt;
            this.jc = jc;
            this.eqtime = eqtime;
            this.decl = decl;
            this.az = az;
            this.el= el;
        }
Пример #14
0
        public void TestPositionCoordinateConversion()
        {
            // upper 89 59 59
            int ladeg = Rand.GetInt(0, 89);
            int lamin = Rand.GetInt(0, 59);
            int lasec = Rand.GetInt(0, 59);
            // upper 179 59 59
            int lodeg = Rand.GetInt(0, 179);
            int lomin = Rand.GetInt(0, 59);
            int losec = Rand.GetInt(0, 59);

            PositionDirection ladir;
            if ( Rand.GetBool() ) {
                ladir = Position.LATITUDE_POS;
            } else {
                ladir = Position.LATITUDE_NEG;
            }

            PositionDirection lodir;
            if ( Rand.GetBool() ) {
                lodir = Position.LONGITUDE_POS;
            } else {
                lodir = Position.LONGITUDE_NEG;
            }

            Position pos = new Position(ladir, ladeg, lamin, lasec,
                                        lodir, lodeg, lomin, losec);

            Degree dla = pos.LatitudeDegree;
            Degree dlo = pos.LongitudeDegree;
            /*
            Console.WriteLine("ladir : {0}", ladir);
            Console.WriteLine("ladeg : {0}", ladeg);
            Console.WriteLine("lamin : {0}", lamin);
            Console.WriteLine("lasec : {0}", lasec);
            Console.WriteLine("\nlodir : {0}", lodir);
            Console.WriteLine("lodeg : {0}", lodeg);
            Console.WriteLine("lomin : {0}", lomin);
            Console.WriteLine("losec : {0}", losec);

            Console.WriteLine("\nrandom latitude  : " + pos.PrintLatitude());
            Console.WriteLine("random longitude : " + pos.PrintLongitude());
            */
            Assert.AreEqual(dla.Direction, ladir);
            Assert.AreEqual(dla.Deg, Math.Abs(ladeg) );
            Assert.AreEqual(dla.Min, lamin);
            Assert.AreEqual(dla.Sec, lasec);

            Assert.AreEqual(dlo.Direction, lodir);
            Assert.AreEqual(dlo.Deg, Math.Abs(lodeg) );
            Assert.AreEqual(dlo.Min, lomin);
            Assert.AreEqual(dlo.Sec, losec);
        }
Пример #15
0
        public SolarTimes(Position pos, UTCDate dt, 
		                  double jc, double eqtime, double decl, 
		                  UTCDate? sunrise, UTCDate noon, UTCDate? sunset)
        {
            this.pos = pos;
            this.dt = dt;
            this.jc = jc;
            this.eqtime = eqtime;
            this.decl = decl;
            this.sunrise = sunrise;
            this.noon = noon;
            this.sunset = sunset;
        }
Пример #16
0
        public CaptionInfo(string loc, Position pos, UTCDate udt)
        {
            this.loc = loc;
            this.pos = pos;
            this.dst = udt.GetDST();
            this.udt = udt;
            this.sp = Orbit.CalcSolarPosition(pos, udt);
            this.st = Orbit.CalcSolarTimes(pos, udt);

            SolarTimes st_ss = PointFinder.FindDawnDusk(pos, udt);
            this.dawn = st_ss.Sunrise;
            this.dusk = st_ss.Sunset;
        }
Пример #17
0
        public void PlotPosition(Graphics g, string location, Position pos)
        {
            Point point = FindMapPoint(pos);
            float font_size = GetCursorFontSize();

            // draw cursor, font is readable
            if (font_size > 10) {
                PlotPositionCursor(g, location, pos, point);

            // draw dot
            } else {
                PlotPositionDot(g, point);
            }
        }
Пример #18
0
        public const double NAUTICAL_TWIGHLIGHT = -12.0; /**< elevation angle (deg) */

        #endregion Fields

        #region Methods

        /**
         * Calculate solar position for location and date.
         * @param dt datetime in UTC
         * @return solar positions in degrees
         */
        public static SolarPosition CalcSolarPosition(Position pos, UTCDate dt)
        {
            double jc = JulianDate.CalcJulianCentury(dt.Year, dt.Month, dt.Day,
                                                     dt.Hour, dt.Minute, dt.Second);
            double eqtime = CalcEquationOfTime(jc);
            double decl = CalcSunDeclination(jc);
            double hour_ang = CalcHourAngle(eqtime, pos.Longitude,
                                            dt.Hour, dt.Minute, dt.Second);
            double zenith = CalcSolarZenithAngle(pos.Latitude, decl, hour_ang);

            // calculate end products
            double azimuth = CalcAzimuth(pos.Latitude, zenith, decl, hour_ang);
            double elevation = CalcSolarElevation(zenith);

            return new SolarPosition(pos, dt, jc, eqtime, decl, azimuth, elevation);
        }
Пример #19
0
        public static SolarTimes FindDawnDusk(Position pos, UTCDate udt)
        {
            UTCDate? dawn_s, dusk_s;
            SolarTimes st = Orbit.CalcSolarTimes(pos, udt);

            dawn_s = st.Sunrise;
            dusk_s = st.Sunset;

            // set wide bounds
            UTCDate lower = st.Noon.AtStartOfUTCDay().AddDays(-1);
            UTCDate upper = lower.AddDays(3);

            dawn_s = FindPoint(pos, dawn_s, lower, Orbit.CIVIL_TWIGHLIGHT, -1);
            dusk_s = FindPoint(pos, dusk_s, upper, Orbit.CIVIL_TWIGHLIGHT, 1);

            return new SolarTimes(pos, udt, 0, 0, 0, dawn_s, st.Noon, dusk_s);
        }
Пример #20
0
        /**
         * Calculate solar sunrise, noon and sunset.
         * @param dt datetime in UTC
         * @return solar times in UTC
         */
        public static SolarTimes CalcSolarTimes(Position pos, UTCDate dt)
        {
            // reset time to start of day as solar times are given in increments
            // from the beginning of the day
            dt = dt.AtStartOfUTCDay();

            double jc = JulianDate.CalcJulianCentury(dt.Year, dt.Month, dt.Day,
                                                     dt.Hour, dt.Minute, dt.Second);
            double solar_noon = CalcSolarNoon(jc, pos.Longitude);
            UTCDate d_noon = dt.AddMinutes(solar_noon);

            UTCDate? d_rise;
            try {
                double sunrise = CalcSunriseSunset(true, solar_noon, jc,
                                                   pos.Longitude, pos.Latitude);
                d_rise = dt.AddMinutes(sunrise);
            } catch (ArgumentException) {
                d_rise = null;
            }

            UTCDate? d_set;
            try {
                double sunset = CalcSunriseSunset(false, solar_noon, jc,
                                                  pos.Longitude, pos.Latitude);
                d_set = dt.AddMinutes(sunset);
            } catch (ArgumentException) {
                d_set = null;
            }

            // <diag>
            double jd = JulianDate.CalcJulianDay(jc)
                - 0.5 + solar_noon / 1440.0;
            double jc_noon = JulianDate.CalcJulianCentury(jd);

            double eqtime = CalcEquationOfTime(jc_noon);
            double decl = CalcSunDeclination(jc_noon);
            // </diag>

            return new SolarTimes(pos, dt, jc, eqtime, decl, d_rise, d_noon, d_set);
        }
Пример #21
0
        public void PlotAnalemma(Graphics g, 
		                         Color col_fst, Color col_snd,
		                         Color col_fst_std, Color col_fst_dst, 
		                         Color col_snd_std, Color col_snd_dst,
		                         Position pos, UTCDate udt)
        {
            UTCDate dt = new UTCDate(udt.Timezone, udt.DST,
                                     udt.Year, 1, 1,
                                     udt.Hour, 0, 0);

            using (SolidBrush br_fst = new SolidBrush(col_fst))
            using (SolidBrush br_snd = new SolidBrush(col_snd))
            using (SolidBrush br_fst_std = new SolidBrush(col_fst_std))
            using (SolidBrush br_fst_dst = new SolidBrush(col_fst_dst))
            using (SolidBrush br_snd_std = new SolidBrush(col_snd_std))
            using (SolidBrush br_snd_dst = new SolidBrush(col_snd_dst)) {
                double step = Math.Max(1, GetResolutionStep(yeardays));
                for (double cursor = 0; cursor < yeardays; cursor+=step)
                {
                    UTCDate dt_new = dt.AddDays(cursor);

                    SolarPosition sp = Orbit.CalcSolarPosition(pos, dt_new);

                    // first half
                    Brush br = br_fst;
                    if (dt_new.HasDST)
                        br = dt_new.IsDST ? br_fst_dst : br_fst_std;
                    // second half
                    if (cursor >= yeardays / 2) {
                        br = br_snd;
                        if (dt_new.HasDST)
                            br = dt_new.IsDST ? br_snd_dst : br_snd_std;
                    }

                    PlotPoint(g, br, sp.Azimuth, sp.Elevation);
                }
            }
        }
Пример #22
0
        public static void SetDetails(string location, Position pos, UTCDate udt)
        {
            SetValue(registry[Id.DETAIL_LOCATION], location);
            SetValue(registry[Id.DETAIL_POSITION], Formatter.FormatPosition(pos));
            SetValue(registry[Id.DETAIL_TIMEZONE], Formatter.FormatTimezone(udt.Timezone,
                                                                            udt.Timezone + udt.GetDST()));
            SetValue(registry[Id.DETAIL_DATE], udt.PrintDate());
            SetValue(registry[Id.DETAIL_TIME], Formatter.FormatTimeLong(udt, true));

            SolarPosition sp = Orbit.CalcSolarPosition(pos, udt);
            SetValue(registry[Id.DETAIL_ELEVATION], Formatter.FormatAngle(sp.Elevation));
            SetValue(registry[Id.DETAIL_AZIMUTH], Formatter.FormatAngle(sp.Azimuth));

            SolarTimes st_ss = Orbit.CalcSolarTimes(pos, udt);
            SetValue(registry[Id.DETAIL_SUNRISE], Formatter.FormatMaybeTimeLong(st_ss.Sunrise, false));
            SetValue(registry[Id.DETAIL_SOLARNOON], Formatter.FormatTimeLong(st_ss.Noon, false));
            SetValue(registry[Id.DETAIL_SUNSET], Formatter.FormatMaybeTimeLong(st_ss.Sunset, false));
            SetValue(registry[Id.DETAIL_SOLARDAYLENGTH], Formatter.FormatDayLength(st_ss, sp));

            SolarTimes st_dd = PointFinder.FindDawnDusk(pos, udt);
            SetValue(registry[Id.DETAIL_DAWN], Formatter.FormatMaybeTimeLong(st_dd.Sunrise, false));
            SetValue(registry[Id.DETAIL_DUSK], Formatter.FormatMaybeTimeLong(st_dd.Sunset, false));
            SetValue(registry[Id.DETAIL_DAYLENGTH], Formatter.FormatDayLength(st_dd, sp));
        }
Пример #23
0
 public void Update(string name, string timezone, Position pos)
 {
     locations[name] = new Location(name, pos, timezone);
 }
Пример #24
0
 private static double Compute(Position pos, UTCDate udt)
 {
     SolarPosition sp = Orbit.CalcSolarPosition(pos, udt);
     return sp.Elevation;
 }
Пример #25
0
 public static string FormatTxtFilename(string loc, Position pos, UTCDate dt)
 {
     return FormatFilename(loc, pos, dt) + Constants.TextFileExtension;
 }
Пример #26
0
 public void Add(string name, string timezone, Position pos)
 {
     Location loc = new Location(name, pos, timezone);
     locations.Add(name, loc);
 }
Пример #27
0
        public static int GetGeographicTimezoneOffset(Position pos)
        {
            Degree v = pos.LongitudeDegree;
            double lon = (double) CollapsePositionUnits(v.Direction,
                                                        v.Deg,
                                                        v.Min,
                                                        v.Sec) / 3600.0;

            // center around 0
            if (lon >= 0) lon = lon + 7.5;
            else lon = lon - 7.5;

            return (int) (lon / 15.0);
        }
Пример #28
0
 public void AddLocation(string name, string timezone, Position pos)
 {
     list.Add(name, timezone, pos);
 }
Пример #29
0
        private static Position ReadPosition()
        {
            string ilodir = GetValue(registry[Id.LONGITUDE_DIRECTION]);
            PositionDirection lodir =
                (PositionDirection) Enum.Parse(typeof(PositionDirection), ilodir);
            string iladir = GetValue(registry[Id.LATITUDE_DIRECTION]);
            PositionDirection ladir =
                (PositionDirection) Enum.Parse(typeof(PositionDirection), iladir);

            int lodeg = GetInt(GetValue(registry[Id.LONGITUDE_DEGS]));
            int lomin = GetInt(GetValue(registry[Id.LONGITUDE_MINS]));
            int losec = GetInt(GetValue(registry[Id.LONGITUDE_SECS]));

            int ladeg = GetInt(GetValue(registry[Id.LATITUDE_DEGS]));
            int lamin = GetInt(GetValue(registry[Id.LATITUDE_MINS]));
            int lasec = GetInt(GetValue(registry[Id.LATITUDE_SECS]));

            Position pos = null;
            // try to instantiate type, otherwise mark inputs as erroneous
            try {
                pos = new Position(ladir, ladeg, lamin, lasec,
                                   lodir, lodeg, lomin, losec);
            } catch (ArgumentException) {
                MarkError(ins_position);
            }
            return pos;
        }
Пример #30
0
 public void UpdateLocation(string name, string timezone, Position pos)
 {
     list.Update(name, timezone, pos);
 }