/// <summary> /// Encode the given latitude and longitude as geohash. /// </summary> /// <param name="Latitude">The latitude.</param> /// <param name="Longitude">The longitude.</param> /// <param name="Precision">An optional precision aka number of characters of the resulting geohash.</param> /// <returns>The latitude and longitude encoded as geohash.</returns> private static String Encode(Latitude Latitude, Longitude Longitude, Byte Precision = 12) { var even = true; var bit = 0; var character = 0; var GeoHash = new StringBuilder(); var bitmask = 16; Double midLat, midLon; var _MinLatitude = GeoCoordinate.MinLatitude.Value; var _MaxLatitude = GeoCoordinate.MaxLatitude.Value; var _MinLongitude = GeoCoordinate.MinLongitude.Value; var _MaxLongitude = GeoCoordinate.MaxLongitude.Value; if (Precision < 1 || Precision > 20) { Precision = 12; } for (var i = 0; i < 5 * Precision; i++) { if (even) { midLon = (_MinLongitude + _MaxLongitude) / 2; if (Longitude.Value > midLon) { // Set 1! character |= bitmask; _MinLongitude = midLon; } else { // Set 0! _MaxLongitude = midLon; } } else { midLat = (_MinLatitude + _MaxLatitude) / 2; if (Latitude.Value > midLat) { // Set 1! character |= bitmask; _MinLatitude = midLat; } else { // Set 0! _MaxLatitude = midLat; } } even = !even; if (bit == 4) { GeoHash.Append(GeoHashAlphabet[character]); bit = 0; bitmask = 16; character = 0; } else { bit++; bitmask >>= 1; } } return(GeoHash.ToString()); }
/// <summary> /// Encode the given latitude and longitude as geohash. /// </summary> /// <param name="Latitude">The latitude.</param> /// <param name="Longitude">The longitude.</param> /// <param name="Precision">An optional precision aka number of bits of the resulting geohash.</param> /// <returns>The latitude and longitude encoded as geohash.</returns> private static UInt32 Encode(Latitude Latitude, Longitude Longitude, Byte Precision = 16) { var _GeoHash = 0U; var _MidLatitude = 0.0; var _MidLongitude = 0.0; var _MinLatitude = -90.0; var _MaxLatitude = 90.0; var _MinLongitude = -180.0; var _MaxLongitude = 180.0; if (Precision > 16) { Precision = 16; } for (var i = 0; i < Precision; i++) { // Shrink latitude intervall if (_MinLatitude < _MaxLatitude) { _MidLatitude = (_MinLatitude + _MaxLatitude) / 2; if (Latitude.Value > _MidLatitude) { _GeoHash |= 1; _MinLatitude = _MidLatitude; } else { _MaxLatitude = _MidLatitude; } } _GeoHash <<= 1; // Shrink longitude intervall if (_MinLongitude < _MaxLongitude) { _MidLongitude = (_MinLongitude + _MaxLongitude) / 2; if (Longitude.Value > _MidLongitude) { _GeoHash |= 1; _MinLongitude = _MidLongitude; } else { _MaxLongitude = _MidLongitude; } } if (i < Precision - 1) { _GeoHash <<= 1; } } return(_GeoHash); }
/// <summary> /// Create a new base32-encoded alphanumeric geohash. /// </summary> /// <param name="Latitude">The latitude.</param> /// <param name="Longitude">The longitude.</param> /// <param name="Precision">An optional precision aka number of characters of the resulting geohash.</param> public GeoHash(Latitude Latitude, Longitude Longitude, Byte Precision = 12) : this(Encode(Latitude, Longitude, Precision)) { }
/// <summary> /// Create a new geographical coordinate or position on a map. /// </summary> /// <param name="Latitude">The Latitude (south to nord).</param> /// <param name="Longitude">The Longitude (parallel to equator).</param> /// <param name="Altitude">The (optional) Altitude.</param> public static GeoCoordinate Create(Latitude Latitude, Longitude Longitude, Altitude?Altitude = null) => new GeoCoordinate(Latitude, Longitude, Altitude);
/// <summary> /// Encode the given latitude and longitude as geohash. /// </summary> /// <param name="Latitude">The latitude.</param> /// <param name="Longitude">The longitude.</param> /// <param name="Precision">An optional precision aka number of bits of the resulting geohash (1-32 bit).</param> /// <returns>The latitude and longitude encoded as geohash.</returns> private static UInt64 Encode(Latitude Latitude, Longitude Longitude, Byte Precision = 32) { var _GeoHash = 0UL; var _MidLatitude = 0.0; var _MidLongitude = 0.0; var _MinLatitude = GeoCoordinate.MinLatitude.Value; var _MaxLatitude = GeoCoordinate.MaxLatitude.Value; var _MinLongitude = GeoCoordinate.MinLongitude.Value; var _MaxLongitude = GeoCoordinate.MaxLongitude.Value; if (Precision > 32) { Precision = 32; } for (var i = 0; i < Precision; i++) { // Shrink latitude intervall if (_MinLatitude < _MaxLatitude) { _MidLatitude = (_MinLatitude + _MaxLatitude) / 2; if (Latitude.Value > _MidLatitude) { _GeoHash |= 1; _MinLatitude = _MidLatitude; } else { _MaxLatitude = _MidLatitude; } } _GeoHash <<= 1; // Shrink longitude intervall if (_MinLongitude < _MaxLongitude) { _MidLongitude = (_MinLongitude + _MaxLongitude) / 2; if (Longitude.Value > _MidLongitude) { _GeoHash |= 1; _MinLongitude = _MidLongitude; } else { _MaxLongitude = _MidLongitude; } } if (i < Precision - 1) { _GeoHash <<= 1; } } return(_GeoHash); }
/// <summary> /// Checks if and where the given lines intersect. /// </summary> /// <param name="Line">A line.</param> /// <param name="IntersectionGeoCoordinate">The intersection of both lines.</param> /// <param name="InfiniteLines">Whether the lines should be treated as infinite or not.</param> /// <returns>True if the lines intersect; False otherwise.</returns> public Boolean IntersectsWith(GeoLine Line, out GeoCoordinate IntersectionGeoCoordinate, Boolean InfiniteLines = false, Boolean ExcludeEdges = false) { #region Initial Checks if (Line == null) { IntersectionGeoCoordinate = default(GeoCoordinate); return(false); } #endregion // Assume both lines are infinite in order to get their intersection... #region This line is just a pixel if (this.IsJustAPixel()) { if (Line.Contains(P1)) { IntersectionGeoCoordinate = P1; return(true); } IntersectionGeoCoordinate = default(GeoCoordinate); return(false); } #endregion #region The given line is just a pixel else if (Line.IsJustAPixel()) { if (this.Contains(Line.P1)) { IntersectionGeoCoordinate = Line.P1; return(true); } IntersectionGeoCoordinate = default(GeoCoordinate); return(false); } #endregion #region Both lines are parallel else if (this.Gradient == Line.Gradient) { IntersectionGeoCoordinate = default(GeoCoordinate); return(false); } #endregion #region Both lines are antiparallel else if (this.Gradient == -1 * Line.Gradient) { IntersectionGeoCoordinate = default(GeoCoordinate); return(false); } #endregion #region This line is parallel to the y-axis else if (Double.IsInfinity(Gradient)) { IntersectionGeoCoordinate = new GeoCoordinate( Latitude.Parse(Line.Gradient * P1.Longitude.Value + Line.YIntercept), P1.Longitude ); } #endregion #region The given line is parallel to the y-axis else if (Double.IsInfinity(Line.Gradient)) { IntersectionGeoCoordinate = new GeoCoordinate( Latitude.Parse(Gradient * Line.P1.Longitude.Value + YIntercept), Line.P1.Longitude ); } #endregion #region There is a real intersection else { //IntersectionGeoCoordinate = null; //// this Line //var A1 = this.P2.Latitude. Value - this.P1.Latitude. Value; //var B1 = this.P2.Longitude.Value - this.P1.Longitude.Value; //var C1 = A1 * this.P1.Longitude.Value + B1 * this.P1.Latitude.Value; //// Line2 //var A2 = Line.P2.Latitude. Value - Line.P1.Latitude. Value; //var B2 = Line.P2.Longitude.Value - Line.P1.Longitude.Value; //var C2 = A2 * Line.P1.Longitude.Value + B2 * Line.P1.Latitude.Value; //var det = A1 * B2 - A2 * B1; //if (det == 0) //{ // //parallel lines //} //else //{ // var x = (B2 * C1 - B1 * C2) / det; // var y = (A1 * C2 - A2 * C1) / det; // IntersectionGeoCoordinate = new GeoCoordinate(new Latitude (y), // new Longitude(x)); //} IntersectionGeoCoordinate = new GeoCoordinate( Latitude.Parse((this.YIntercept * Line.Gradient - Line.YIntercept * this.Gradient) / (Line.Gradient - this.Gradient)), Longitude.Parse((Line.YIntercept - this.YIntercept) / (this.Gradient - Line.Gradient)) ); } #endregion if (InfiniteLines) { return(true); } else if (!ExcludeEdges) { return(this.Contains(IntersectionGeoCoordinate)); } else { if (this.Contains(IntersectionGeoCoordinate)) { if (IntersectionGeoCoordinate.Equals(P1) || IntersectionGeoCoordinate.Equals(P2) || IntersectionGeoCoordinate.Equals(Line.P1) || IntersectionGeoCoordinate.Equals(Line.P2)) { return(false); } return(true); } return(false); } }
public static Double ToDegree(this Longitude Longitude) { return(Longitude.Value * (180 / Math.PI)); }
public static Double ToRadians(this Longitude Longitude) { return(Longitude.Value * (Math.PI / 180)); }
public static ShapeInfo Polyfile2ShapeInfo(IEnumerable <String> InputData, UInt32 min_resolution, UInt32 max_resolution) { #region Init var Integer = 1U; var ShapeNumber = 1U; var IsFirstLine = true; var Description = String.Empty; var min_lat = Double.MaxValue; var min_lng = Double.MaxValue; var max_lat = Double.MinValue; var max_lng = Double.MinValue; var Shapes = new Dictionary <UInt32, Tuple <List <GeoCoordinate>, Dictionary <UInt32, Tuple <List <ScreenXY>, StringBuilder> > > >(); GeoCoordinate GeoCoordinate = default(GeoCoordinate); #endregion foreach (var Line in InputData) { #region Process first line if (IsFirstLine) { Description = Line; IsFirstLine = false; } #endregion #region A single Integer on a line indicates the start of a new shape else if (UInt32.TryParse(Line, out Integer)) { ShapeNumber = Integer; Shapes.Add(ShapeNumber, new Tuple <List <GeoCoordinate>, Dictionary <UInt32, Tuple <List <ScreenXY>, StringBuilder> > >( new List <GeoCoordinate>(), new Dictionary <UInt32, Tuple <List <ScreenXY>, StringBuilder> >())); } #endregion #region "END" indicates the end of a shape else if (Line == "END") { continue; } #endregion #region The rest of the file are "Longitude Latitude" encoded geo coordinates else if (GeoCoordinate.TryParseString(Line, out GeoCoordinate)) { // Polyfiles store "Longitude Latitude"!!! Shapes[ShapeNumber].Item1.Add(new GeoCoordinate( Latitude.Parse(GeoCoordinate.Longitude.Value), Longitude.Parse(GeoCoordinate.Latitude.Value) )); if (min_lat > GeoCoordinate.Longitude.Value) { min_lat = GeoCoordinate.Longitude.Value; } if (min_lng > GeoCoordinate.Latitude.Value) { min_lng = GeoCoordinate.Latitude.Value; } if (max_lat < GeoCoordinate.Longitude.Value) { max_lat = GeoCoordinate.Longitude.Value; } if (max_lng < GeoCoordinate.Latitude.Value) { max_lng = GeoCoordinate.Latitude.Value; } } #endregion #region Unknown data found... else { throw new Exception("Unknown data found!"); } #endregion } //var Output1 = new StreamWriter("PolyfileReader/" + Filename.Name.Replace(".poly", ".data")); //var Array = new StringBuilder(); //var Output2 = new StreamWriter("PolyfileReader/" + "ghjk".Replace(".poly", ".geo")); //var Language = new StringBuilder(); //Shapes.ForEach((shape) => //{ // Array.AppendLine(shape.Key.ToString()); // shape.Value.Item1.ForEach(c => // { // Array.AppendLine(" { " + c.Latitude.ToString("00.000000").Replace(",", ".") + ", " + c.Longitude.ToString("00.000000").Replace(",", ".") + " },"); // }); //}); //Output1.WriteLine(Array.ToString()); //Output1.Flush(); //Output1.Close(); var diff_lat = Math.Abs(min_lat - max_lat); var diff_lng = Math.Abs(min_lng - max_lng); //Output2.WriteLine("From: " + max_lat.ToString("00.000000").Replace(",", ".") + ", " + min_lng.ToString("00.000000").Replace(",", ".")); //Output2.WriteLine("To: " + min_lat.ToString("00.000000").Replace(",", ".") + ", " + max_lng.ToString("00.000000").Replace(",", ".")); //Output2.WriteLine("Diff: " + diff_lat.ToString("00.000000").Replace(",", ".") + ", " + diff_lng.ToString("00.000000").Replace(",", ".")); //Output2.WriteLine("Resolution: " + min_resolution + " -> " + max_resolution); Shapes.ForEach(shape => { for (var resolution = min_resolution; resolution <= max_resolution; resolution++) { shape.Value.Item2.Add(resolution, new Tuple <List <ScreenXY>, StringBuilder>(new List <ScreenXY>(), new StringBuilder())); shape.Value.Item1.ForEach(GeoCoord => shape.Value.Item2[resolution].Item1.Add(GeoCalculations.GeoCoordinate2ScreenXY(GeoCoord, resolution)) ); } }); var min_x = 0L; var min_y = 0L; for (var resolution = min_resolution; resolution <= max_resolution; resolution++) { min_x = Int64.MaxValue; min_y = Int64.MaxValue; Shapes.ForEach((shape) => { shape.Value.Item2[resolution].Item1.ForEach(XY => { if (XY.X < min_x) { min_x = XY.X; } if (XY.Y < min_y) { min_y = XY.Y; } }); }); Shapes.ForEach((shape) => { var Char = "M "; shape.Value.Item2[resolution].Item1.ForEach(XY => { shape.Value.Item2[resolution].Item2.Append(Char + (XY.X - min_x) + " " + (XY.Y - min_y) + " "); if (Char == "L ") { Char = ""; } if (Char == "M ") { Char = "L "; } }); shape.Value.Item2[resolution].Item2.Append("Z "); }); } var ShapeLanguage = String.Empty; var ShapeDic = new Dictionary <UInt32, String>(); for (var resolution = min_resolution; resolution <= max_resolution; resolution++) { ShapeLanguage = "\""; Shapes.ForEach((shape) => ShapeLanguage += shape.Value.Item2[resolution].Item2.ToString().Trim() + " "); ShapeDic.Add(resolution, ShapeLanguage.TrimEnd() + "\","); } return(new ShapeInfo(Description, max_lat, max_lng, min_lat, min_lng, ShapeDic)); }
public GeoCoordinate Transform(Double Hochwert, Double Rechtswert, Double Hoehe, String Bezugsmeridian = "Automatische Ermittlung") { // Based on: GK_in_WGS84.cs // Copyright (c) 2008 by Ingo Peczynski // http://www.sky-maps.de // [email protected] // Compare to http://calc.gknavigation.de/ #region Konstante Parameter // WGS84 Ellipsoid var WGS84_a = 6378137.0; // große Halbachse var WGS84_b = 6356752.3141; // kleine Halbachse var WGS84_e2 = (Math.Pow(WGS84_a, 2) - Math.Pow(WGS84_b, 2)) / Math.Pow(WGS84_a, 2); // 1.Numerische Exzentrität var WGS84_f = (WGS84_a - WGS84_b) / WGS84_a; // Abplattung 1: fW // Bessel Ellipsoid var Bessel_a = 6377397.155; var Bessel_b = 6356078.962; var Bessel_e2 = (Bessel_a * Bessel_a - Bessel_b * Bessel_b) / (Bessel_a * Bessel_a); #endregion #region MeridianUmrechnung Int32 Meridianneu; if (Bezugsmeridian == "Automatische Ermittlung") { Meridianneu = 3 * Convert.ToInt32(Rechtswert.ToString().Substring(0, 1)); } else { Meridianneu = Convert.ToInt32(Bezugsmeridian); } #endregion #region GK nach BL // Bessel Ellipsoid var n = (Bessel_a - Bessel_b) / (Bessel_a + Bessel_b); var alpha = (Bessel_a + Bessel_b) / 2.0 * (1.0 + 1.0 / 4.0 * n * n + 1.0 / 64.0 * Math.Pow(n, 4)); var beta = 3.0 / 2.0 * n - 27.0 / 32.0 * Math.Pow(n, 3) + 269.0 / 512.0 * Math.Pow(n, 5); var gamma = 21.0 / 16.0 * n * n - 55.0 / 32.0 * Math.Pow(n, 4); var delta = 151.0 / 96.0 * Math.Pow(n, 3) - 417.0 / 128.0 * Math.Pow(n, 5); var epsilon = 1097.0 / 512.0 * Math.Pow(n, 4); var y0 = Meridianneu / 3.0; var y = Rechtswert - y0 * 1000000 - 500000; var B0 = Hochwert / alpha; var Bf = B0 + beta * Math.Sin(2 * B0) + gamma * Math.Sin(4 * B0) + delta * Math.Sin(6 * B0) + epsilon * Math.Sin(8 * B0); var Nf = Bessel_a / Math.Sqrt(1.0 - Bessel_e2 * Math.Pow(Math.Sin(Bf), 2)); var ETAf = Math.Sqrt((Bessel_a * Bessel_a) / (Bessel_b * Bessel_b) * Bessel_e2 * Math.Pow(Math.Cos(Bf), 2)); var tf = Math.Tan(Bf); var b1 = tf / 2.0 / (Nf * Nf) * (-1.0 - (ETAf * ETAf)) * (y * y); var b2 = tf / 24.0 / Math.Pow(Nf, 4) * (5.0 + 3.0 * (tf * tf) + 6.0 * (ETAf * ETAf) - 6.0 * (tf * tf) * (ETAf * ETAf) - 4.0 * Math.Pow(ETAf, 4) - 9.0 * (tf * tf) * Math.Pow(ETAf, 4)) * Math.Pow(y, 4); var g_B = (Bf + b1 + b2) * 180 / Math.PI; var l1 = 1.0 / Nf / Math.Cos(Bf) * y; var l2 = 1.0 / 6.0 / Math.Pow(Nf, 3) / Math.Cos(Bf) * (-1.0 - 2.0 * (tf * tf) - (ETAf * ETAf)) * Math.Pow(y, 3); var g_L = Meridianneu + (l1 + l2) * 180 / Math.PI; #endregion #region Ellipsoid Vektoren in DHDN // Querkrümmunsradius var N = Bessel_a / Math.Sqrt(1.0 - Bessel_e2 * Math.Pow(Math.Sin(g_B / 180 * Math.PI), 2)); // Ergebnis Vektoren var Bessel_x = (N + Hoehe) * Math.Cos(g_B / 180 * Math.PI) * Math.Cos(g_L / 180 * Math.PI); var Bessel_y = (N + Hoehe) * Math.Cos(g_B / 180 * Math.PI) * Math.Sin(g_L / 180 * Math.PI); var Bessel_z = (N * (Bessel_b * Bessel_b) / (Bessel_a * Bessel_a) + Hoehe) * Math.Sin(g_B / 180 * Math.PI); #endregion #region Parameter HelmertTransformation Double g_dx; Double g_dy; Double g_dz; Double g_ex; Double g_ey; Double g_ez; Double g_m; // HelmertTransformation switch (HelmerttransformationsArt) { // Deutschland von WGS84 nach DNDH/Potsdamm2001 default: g_dx = 598.1; // Translation in X g_dy = 73.7; // Translation in Y g_dz = 418.2; // Translation in Z g_ex = -0.202; // Drehwinkel in Bogensekunden un die x-Achse g_ey = -0.045; // Drehwinkel in Bogensekunden un die y-Achse g_ez = 2.455; // Drehwinkel in Bogensekunden un die z-Achse g_m = 6.7; // Maßstabsfaktor in ppm break; // Österreich von WGS84 nach MGI Ferro case HelmerttransformationsArt.OesterreichWGS84nachMGIFerro: g_dx = 577.326; // Translation in X g_dy = 90.129; // Translation in Y g_dz = 463.919; // Translation in Z g_ex = -5.137; // Drehwinkel in Bogensekunden un die x-Achse g_ey = -1.474; // Drehwinkel in Bogensekunden un die y-Achse g_ez = -5.297; // Drehwinkel in Bogensekunden un die z-Achse g_m = 2.423; // Maßstabsfaktor in ppm break; } #endregion #region Helmert // Umrechnung der Drehwinkel in Bogenmaß var exRad = (g_ex * Math.PI / 180.0) / 3600.0; var eyRad = (g_ey * Math.PI / 180.0) / 3600.0; var ezRad = (g_ez * Math.PI / 180.0) / 3600.0; // Maßstabsumrechnung var mEXP = 1 - g_m * Math.Pow(10, -6); // Drehmatrix // 1 Ez -Ez // -Ez 1 Ex // Ey -Ex 1 // Rotierende Vektoren = Drehmatrix * Vektoren in WGS84 var RotVektor1 = 1.0 * Bessel_x + ezRad * Bessel_y + (-1.0 * eyRad * Bessel_z); var RotVektor2 = (-1.0 * ezRad) * Bessel_x + 1 * Bessel_y + exRad * Bessel_z; var RotVektor3 = (eyRad) * Bessel_x + (-1.0 * exRad) * Bessel_y + 1 * Bessel_z; // Maßstab berücksichtigen var RotVectorM1 = RotVektor1 * mEXP; var RotVectorM2 = RotVektor2 * mEXP; var RotVectorM3 = RotVektor3 * mEXP; // Translation anbringen // dxT = Drehmatrix * dx * m var dxT = 1.0 * g_dx * mEXP + ezRad * g_dy * mEXP + (-1.0 * eyRad) * g_dz * mEXP; var dyT = (-1.0 * ezRad) * g_dx * mEXP + 1.0 * g_dy * mEXP + exRad * g_dz * mEXP; var dzT = (eyRad) * g_dx * mEXP + (-1.0 * exRad) * g_dy * mEXP + 1 * g_dz * mEXP; // Vektoren jetzt in WGS84 var WGS84_x = RotVectorM1 + dxT; var WGS84_y = RotVectorM2 + dyT; var WGS84_z = RotVectorM3 + dzT; #endregion #region Vektorenumrechnung var s = Math.Sqrt(WGS84_x * WGS84_x + WGS84_y * WGS84_y); var T = Math.Atan(WGS84_z * WGS84_a / (s * WGS84_b)); var Bz = Math.Atan((WGS84_z + WGS84_e2 * (WGS84_a * WGS84_a) / WGS84_b * Math.Pow(Math.Sin(T), 3)) / (s - WGS84_e2 * WGS84_a * Math.Pow(Math.Cos(T), 3))); var Lz = Math.Atan(WGS84_y / WGS84_x); var N2 = WGS84_a / Math.Sqrt(1 - WGS84_e2 * Math.Pow(Math.Sin(Bz), 2)); #endregion return(new GeoCoordinate(Latitude.Parse(Bz * 180 / Math.PI), Longitude.Parse(Lz * 180 / Math.PI), Altitude.Parse(s / Math.Cos(Bz)))); }