/// <summary> /// Creates a new instance of GeocentricGeodetic /// </summary> public GeocentricGeodetic(Spheroid gi) { _a = gi.EquatorialRadius; _b = gi.PolarRadius; _a2 = _a * _a; _b2 = _b * _b; _e2 = (_a2 - _b2) / _a2; _ep2 = (_a2 - _b2) / _b2; }
private static void DatumTransform(ProjectionInfo source, ProjectionInfo dest, double[][] points, int startIndex, int numPoints) { Spheroid wgs84 = new Spheroid(Proj4Ellipsoids.WGS_1984); Datum sDatum = source.GeographicInfo.Datum; Datum dDatum = dest.GeographicInfo.Datum; double[][] zPoints = new double[points.Length][]; bool zIsTemp = false; /* -------------------------------------------------------------------- */ /* We cannot do any meaningful datum transformation if either */ /* the source or destination are of an unknown datum type */ /* (ie. only a +ellps declaration, no +datum). This is new */ /* behavior for PROJ 4.6.0. */ /* -------------------------------------------------------------------- */ if (sDatum.DatumType == DatumTypes.Unknown || dDatum.DatumType == DatumTypes.Unknown) { return; } /* -------------------------------------------------------------------- */ /* Short cut if the datums are identical. */ /* -------------------------------------------------------------------- */ if (sDatum.Matches(dDatum)) { return; } double srcA = sDatum.Spheroid.EquatorialRadius; double srcEs = sDatum.Spheroid.EccentricitySquared(); double dstA = dDatum.Spheroid.EquatorialRadius; double dstEs = dDatum.Spheroid.EccentricitySquared(); /* -------------------------------------------------------------------- */ /* Create a temporary Z value if one is not provided. */ /* -------------------------------------------------------------------- */ if (points[0].Length > 2) { zPoints = points; } else { for (int i = startIndex; i < numPoints; i++) { zPoints[i] = new[] { points[i][0], points[i][1], 0 }; } zIsTemp = true; } /* -------------------------------------------------------------------- */ /* If this datum requires grid shifts, then apply it to geodetic */ /* coordinates. */ /* -------------------------------------------------------------------- */ if (sDatum.DatumType == DatumTypes.GridShift) { // pj_apply_gridshift( pj_param(srcdefn->params,"snadgrids").s, 0, // point_count, point_offset, x, y, z ); GridShift.Apply(source.GeographicInfo.Datum.NadGrids, false, points, startIndex, numPoints); srcA = wgs84.EquatorialRadius; srcEs = wgs84.EccentricitySquared(); } if (dDatum.DatumType == DatumTypes.GridShift) { dstA = wgs84.EquatorialRadius; dstEs = wgs84.EccentricitySquared(); } /* ==================================================================== */ /* Do we need to go through geocentric coordinates? */ /* ==================================================================== */ if (srcEs != dstEs || srcA != dstA || sDatum.DatumType == DatumTypes.Param3 || sDatum.DatumType == DatumTypes.Param7 || dDatum.DatumType == DatumTypes.Param3 || dDatum.DatumType == DatumTypes.Param7) { /* -------------------------------------------------------------------- */ /* Convert to geocentric coordinates. */ /* -------------------------------------------------------------------- */ GeocentricGeodetic gc = new GeocentricGeodetic(sDatum.Spheroid); gc.GeodeticToGeocentric(zPoints, startIndex, numPoints); /* -------------------------------------------------------------------- */ /* Convert between datums. */ /* -------------------------------------------------------------------- */ if (sDatum.DatumType == DatumTypes.Param3 || sDatum.DatumType == DatumTypes.Param7) { // pj_geocentric_to_wgs84( srcdefn, point_count, point_offset,x,y,z); } if (dDatum.DatumType == DatumTypes.Param3 || dDatum.DatumType == DatumTypes.Param7) { // pj_geocentric_from_wgs84( dstdefn, point_count,point_offset,x,y,z); } /* -------------------------------------------------------------------- */ /* Convert back to geodetic coordinates. */ /* -------------------------------------------------------------------- */ gc = new GeocentricGeodetic(dDatum.Spheroid); gc.GeodeticToGeocentric(zPoints, startIndex, numPoints); } /* -------------------------------------------------------------------- */ /* Apply grid shift to destination if required. */ /* -------------------------------------------------------------------- */ if (dDatum.DatumType == DatumTypes.GridShift) { // pj_apply_gridshift( pj_param(dstdefn->params,"snadgrids").s, 1, // point_count, point_offset, x, y, z ); GridShift.Apply(dest.GeographicInfo.Datum.NadGrids, true, points, startIndex, numPoints); } if (zIsTemp) { for (int i = startIndex; i < numPoints; i++) { points[i][0] = zPoints[i][0]; points[i][1] = zPoints[i][1]; } } }
/// <summary> /// Uses a Proj4Datums enumeration in order to specify a known datum to /// define the spheroid and to WGS calculation method and parameters /// </summary> /// <param name="standardDatum">The Proj4Datums enumeration specifying the known datum</param> public Datum(Proj4Datums standardDatum) { _spheroid = new Spheroid(); AssignStandardDatum(standardDatum.ToString()); }
/// <summary> /// uses a string name of a standard datum to create a new instance of the Datum class /// </summary> /// <param name="standardDatum">The string name of the datum to use</param> public Datum(string standardDatum) { _spheroid = new Spheroid(); AssignStandardDatum(standardDatum); }
/// <summary> /// Creates a new instance of Datum /// </summary> public Datum() { _spheroid = new Spheroid(); }
/// <summary> /// Reads the proj4 parameters and parses out the ones that control the /// datum. /// </summary> /// <param name="parameters"></param> /// <remarks>Originally ported from pj_datum_set.c</remarks> public void ReadProj4Params(Dictionary <string, string> parameters) { DatumType = DatumTypes.Unknown; /* -------------------------------------------------------------------- */ /* Is there a datum definition in the parameters list? If so, */ /* add the defining values to the parameter list. Notice that */ /* this will append the ellipse definition as well as the */ /* towgs84= and related parameters. It should also be pointed */ /* out that the addition is permanent rather than temporary */ /* like most other keyword expansion so that the ellipse */ /* definition will last into the pj_ell_set() function called */ /* after this one. */ /* -------------------------------------------------------------------- */ if (parameters.ContainsKey("datum")) { AssignStandardDatum(parameters["datum"]); // Even though th ellipsoid is set by its known definition, we permit overriding it with a specifically defined ellps parameter } // ELLIPSOID PARAMETER if (parameters.ContainsKey("ellps")) { Spheroid = new Spheroid(parameters["ellps"]); } else { if (parameters.ContainsKey("a")) { Spheroid.EquatorialRadius = double.Parse(parameters["a"]); } if (parameters.ContainsKey("b")) { Spheroid.PolarRadius = double.Parse(parameters["b"]); } if (parameters.ContainsKey("rf")) { Spheroid.SetInverseFlattening(double.Parse(parameters["rf"])); } if (parameters.ContainsKey("R")) { Spheroid.EquatorialRadius = double.Parse(parameters["R"]); } } // DATUM PARAMETER if (parameters.ContainsKey("nadgrids")) { _nadGrids = parameters["nadgrids"].Split(','); _datumtype = DatumTypes.GridShift; } else if (parameters.ContainsKey("towgs84")) { string[] rawVals = parameters["towgs84"].Split(','); _toWGS84 = new double[rawVals.Length]; for (int i = 0; i < rawVals.Length; i++) { _toWGS84[i] = double.Parse(rawVals[i]); } _datumtype = DatumTypes.Param7; if (_toWGS84.Length < 7) { _datumtype = DatumTypes.Param3; } if (_toWGS84[3] == 0.0 && _toWGS84[4] == 0.0 && _toWGS84[5] == 0.0 && _toWGS84[6] == 0.0) { _datumtype = DatumTypes.Param3; } if (_datumtype == DatumTypes.Param7) { // Trnasform from arc seconds to radians _toWGS84[3] *= SecToRad; _toWGS84[4] *= SecToRad; _toWGS84[5] *= SecToRad; // transform from parts per millon to scaling factor _toWGS84[6] = (_toWGS84[6] / 1000000.0) + 1; } } }
private void AssignStandardDatum(string datumName) { string id = datumName.ToLower(); switch (id) { case "wgs84": _toWGS84 = new double[] { 0, 0, 0 }; _spheroid = new Spheroid(Proj4Ellipsoids.WGS_1984); _description = "WGS 1984"; _datumtype = DatumTypes.WGS84; _name = "D_WGS_1984"; break; case "ggrs87": _toWGS84 = new[] { -199.87, 74.79, 246.62 }; _spheroid = new Spheroid(Proj4Ellipsoids.GRS_1980); _description = "Greek Geodetic Reference System 1987"; _datumtype = DatumTypes.Param3; break; case "nad83": _toWGS84 = new double[] { 0, 0, 0 }; _spheroid = new Spheroid(Proj4Ellipsoids.GRS_1980); _description = "North American Datum 1983"; _datumtype = DatumTypes.WGS84; break; case "nad27": _nadGrids = new[] { "@conus", "@alaska", "@ntv2_0.gsb", "@ntv1_can.dat" }; _spheroid = new Spheroid(Proj4Ellipsoids.Clarke_1866); _description = "North American Datum 1927"; _datumtype = DatumTypes.GridShift; break; case "potsdam": _toWGS84 = new[] { 606.0, 23.0, 413.0 }; _spheroid = new Spheroid(Proj4Ellipsoids.Bessel_1841); _description = "Potsdam Rauenberg 1950 DHDN"; _datumtype = DatumTypes.Param3; break; case "carthage": _toWGS84 = new[] { -263.0, 6, 413 }; _spheroid = new Spheroid(Proj4Ellipsoids.ClarkeModified_1880); _description = "Carthage 1934 Tunisia"; _datumtype = DatumTypes.Param3; break; case "hermannskogel": _toWGS84 = new[] { 653.0, -212.0, 449 }; _spheroid = new Spheroid(Proj4Ellipsoids.Bessel_1841); _description = "Hermannskogel"; _datumtype = DatumTypes.Param3; break; case "ire65": _toWGS84 = new[] { 482.530, -130.569, 564.557, -1.042, -.214, -.631, 8.15 }; _spheroid = new Spheroid(Proj4Ellipsoids.AiryModified); _description = "Ireland 1965"; _datumtype = DatumTypes.Param7; break; case "nzgd49": _toWGS84 = new[] { 59.47, -5.04, 187.44, 0.47, -0.1, 1.024, -4.5993 }; _spheroid = new Spheroid(Proj4Ellipsoids.International_1909); _description = "New Zealand"; _datumtype = DatumTypes.Param7; break; case "osgb36": _toWGS84 = new[] { 446.448, -125.157, 542.060, 0.1502, 0.2470, 0.8421, -20.4894 }; _spheroid = new Spheroid(Proj4Ellipsoids.Airy_1830); _description = "Airy 1830"; _datumtype = DatumTypes.Param7; break; } }
/// <summary> /// Creates an esri well known text string for the datum part of the string /// </summary> /// <returns>The datum portion of the esri well known text</returns> public string ToEsriString() { return(@"DATUM[""" + _name + @"""," + Spheroid.ToEsriString() + "]"); }