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); }
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; }
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); }
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; }
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); }
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; }
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; }
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); } } }
public void Update(string location, Position pos) { this.position = pos; this.location = location; NullifyFinalizedBitmap(); RePaint(); }
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; }
public void ReRender(Position pos, UTCDate date) { this.position = pos; this.date = date; NullifyBaseImageBitmap(); NullifyFinalizedBitmap(); RePaint(); }
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; }
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; }
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); }
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; }
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; }
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); } }
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); }
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); }
/** * 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); }
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); } } }
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)); }
public void Update(string name, string timezone, Position pos) { locations[name] = new Location(name, pos, timezone); }
private static double Compute(Position pos, UTCDate udt) { SolarPosition sp = Orbit.CalcSolarPosition(pos, udt); return sp.Elevation; }
public static string FormatTxtFilename(string loc, Position pos, UTCDate dt) { return FormatFilename(loc, pos, dt) + Constants.TextFileExtension; }
public void Add(string name, string timezone, Position pos) { Location loc = new Location(name, pos, timezone); locations.Add(name, loc); }
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); }
public void AddLocation(string name, string timezone, Position pos) { list.Add(name, timezone, pos); }
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; }
public void UpdateLocation(string name, string timezone, Position pos) { list.Update(name, timezone, pos); }