/// <summary> /// Get the corresponding tile for the given geo coordinate. /// </summary> /// <param name="GeoCoordinates">An enumeration of geo coordinates.</param> public static GeoBoundingBox GeoCoordinate2BoundingBox(this IEnumerable <GeoCoordinate> GeoCoordinates) { var MinLat = Double.MaxValue; var MaxLat = Double.MinValue; var MinLng = Double.MaxValue; var MaxLng = Double.MinValue; var MinAlt = Double.MaxValue; var MaxAlt = Double.MinValue; foreach (var GeoCoordinate in GeoCoordinates) { if (GeoCoordinate.Latitude.Value < MinLat) { MinLat = GeoCoordinate.Latitude.Value; } if (GeoCoordinate.Longitude.Value < MinLng) { MinLng = GeoCoordinate.Longitude.Value; } if (GeoCoordinate.Altitude.HasValue && GeoCoordinate.Altitude.Value.Value < MinAlt) { MinAlt = GeoCoordinate.Altitude.Value.Value; } if (GeoCoordinate.Latitude.Value > MaxLat) { MaxLat = GeoCoordinate.Latitude.Value; } if (GeoCoordinate.Longitude.Value > MaxLng) { MaxLng = GeoCoordinate.Longitude.Value; } if (GeoCoordinate.Altitude.HasValue && GeoCoordinate.Altitude.Value.Value > MaxAlt) { MaxAlt = GeoCoordinate.Altitude.Value.Value; } } return(new GeoBoundingBox( Latitude.Parse(MinLat), Longitude.Parse(MinLng), Altitude.Parse(MinAlt), Latitude.Parse(MaxLat), Longitude.Parse(MaxLng), Altitude.Parse(MaxAlt) )); }
public GeoBoundingBox(Latitude Latitude, Longitude Longitude, Latitude Latitude2, Longitude Longitude2) : this(Latitude, Longitude, Altitude.Parse(0), Latitude2, Longitude2, Altitude.Parse(0)) { }
// 2.1.1. Positions // A position is the fundamental geometry construct. The "coordinates" member // of a geometry object is composed of one position (in the case of a Point // geometry), an array of positions (LineString or MultiPoint geometries), an // array of arrays of positions (Polygons, MultiLineStrings), or a // multidimensional array of positions (MultiPolygon). // // A position is represented by an array of numbers. There must be at least // two elements, and may be more. The order of elements must follow x, y, z // order (easting, northing, altitude for coordinates in a projected coordinate // reference system, or longitude, latitude, altitude for coordinates in a // geographic coordinate reference system). Any number of additional elements // are allowed -- interpretation and meaning of additional elements is beyond // the scope of this specification. // Point // // Point coordinates are in x, y order (easting, northing for projected // coordinates, longitude, latitude for geographic coordinates): // // { // "type": "Point", // "coordinates": [100.0, 0.0] // } // LineString // // Coordinates of LineString are an array of positions (see 2.1.1. Positions): // // { // "type": "LineString", // "coordinates": [ [100.0, 0.0], [101.0, 1.0] ] // } //Polygon //Coordinates of a Polygon are an array of LinearRing coordinate arrays. The first element in the array represents the exterior ring. Any subsequent elements represent interior rings (or holes). //No holes: //{ "type": "Polygon", // "coordinates": [ // [ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0] ] // ] // } //With holes: //{ "type": "Polygon", // "coordinates": [ // [ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0] ], // [ [100.2, 0.2], [100.8, 0.2], [100.8, 0.8], [100.2, 0.8], [100.2, 0.2] ] // ] // } //MultiPoint //Coordinates of a MultiPoint are an array of positions: //{ "type": "MultiPoint", // "coordinates": [ [100.0, 0.0], [101.0, 1.0] ] // } //MultiLineString //Coordinates of a MultiLineString are an array of LineString coordinate arrays: //{ "type": "MultiLineString", // "coordinates": [ // [ [100.0, 0.0], [101.0, 1.0] ], // [ [102.0, 2.0], [103.0, 3.0] ] // ] // } //MultiPolygon //Coordinates of a MultiPolygon are an array of Polygon coordinate arrays: //{ "type": "MultiPolygon", // "coordinates": [ // [[[102.0, 2.0], [103.0, 2.0], [103.0, 3.0], [102.0, 3.0], [102.0, 2.0]]], // [[[100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0]], // [[100.2, 0.2], [100.8, 0.2], [100.8, 0.8], [100.2, 0.8], [100.2, 0.2]]] // ] // } //GeometryCollection //Each element in the geometries array of a GeometryCollection is one of the geometry objects described above: //{ "type": "GeometryCollection", // "geometries": [ // { "type": "Point", // "coordinates": [100.0, 0.0] // }, // { "type": "LineString", // "coordinates": [ [101.0, 0.0], [102.0, 1.0] ] // } // ] //} // 2.2. Feature Objects //A GeoJSON object with the type "Feature" is a feature object. //A feature object must have a member with the name "geometry". The value of the geometry member is a geometry object as defined above or a JSON null value. //A feature object must have a member with the name "properties". The value of the properties member is an object (any JSON object or a JSON null value). //If a feature has a commonly used identifier, that identifier should be included as a member of the feature object with the name "id". // { "type": "FeatureCollection", // "features": [ // { // "type": "Feature", // "geometry": { // "type": "Point", // "coordinates": [102.0, 0.5] // }, // "properties": { // "prop0": "value0" // } // }, // { "type": "Feature", // "geometry": { // "type": "LineString", // "coordinates": [ // [102.0, 0.0], [103.0, 1.0], [104.0, 0.0], [105.0, 1.0] // ] // }, // "properties": { // "prop0": "value0", // "prop1": 0.0 // } // }, // { "type": "Feature", // "geometry": { // "type": "Polygon", // "coordinates": [ // [ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0], // [100.0, 1.0], [100.0, 0.0] ] // ] // }, // "properties": { // "prop0": "value0", // "prop1": {"this": "that"} // } // } // ] // } public static GeoBoundingBox GetBoundingBox(JObject GeoJSON, Int32 FeatureId = 0, Int32 ObjectId = 0) { Double lng, lat; var min_lng = Double.MaxValue; var max_lng = Double.MinValue; var min_lat = Double.MaxValue; var max_lat = Double.MinValue; var GeoCoordinates = GeoJSON?["features"]?[FeatureId]?["geometry"]?["coordinates"]?[ObjectId]; if (GeoCoordinates == null) { return(new GeoBoundingBox(Latitude.Parse(0), Longitude.Parse(0), Altitude.Parse(0), Latitude.Parse(0), Longitude.Parse(0), Altitude.Parse(0))); } else { foreach (var value in GeoCoordinates) { lng = Double.Parse(value[0].Value <String>()); lat = Double.Parse(value[1].Value <String>()); if (min_lat > lat) { min_lat = lat; } if (max_lat < lat) { max_lat = lat; } if (min_lng > lng) { min_lng = lng; } if (max_lng < lng) { max_lng = lng; } } } return(new GeoBoundingBox(Latitude.Parse(min_lat), Longitude.Parse(min_lng), Altitude.Parse(0), Latitude.Parse(max_lat), Longitude.Parse(max_lng), Altitude.Parse(0))); }
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)))); }