private static Int32 GridSize(Int16 digits) { Int16 actualDigits = UtmPoint.MakeDigitValid(digits); Int32 result = Convert.ToInt32(Math.Pow(10, UtmPoint.MaximumDigits - actualDigits)); return(result); }
private Boolean SameZone(UtmPoint point) { GeoPoint geoPoint = new GeoPoint(point, Datum); UtmPoint realUtm = geoPoint.CalcUTM(); Boolean result = (CentralPoint.ZoneNumber == realUtm.ZoneNumber); return(result); }
private void SetMgrs(String value) { String mgrs = value.Replace(" ", ""); Int16 digits = Convert.ToInt16((mgrs.Length - 1) / 2); CentralPoint = MakeCentral(UtmPoint.ParseMgrsString(value), digits); _Digits = digits; Name = value; }
/// <summary> /// Initializes a new instance of the GeoPoint class. /// </summary> /// <param name="utmPoint">UTM coordinates.</param> /// <param name="datum">Geographical datum.</param> public GeoPoint(UtmPoint utmPoint, GeoDatum datum) { Double excentricitySquared = datum.Ellipsoid.ExcentricitySquared; Double equatorialRadius = datum.Ellipsoid.SemiMajorAxis; Boolean northernHemisphere = utmPoint.IsNorthernHemisphere; Int32 zoneNumber = utmPoint.ZoneNumber; Double x = utmPoint.Easting - 500000.0; //remove 500,000 meter offset for longitude Double y = utmPoint.Northing; if (!northernHemisphere) { // point is in southern hemisphere y = y - 10000000.0; // remove 10,000,000 meter offset used for southern hemisphere } Double longOrigin = (zoneNumber - 1) * 6 - 180 + 3; // +3 puts origin in middle of zone Double excentricityPrimeSquared = (excentricitySquared) / (1 - excentricitySquared); Double M = y / dScaleFactor; Double mu = M / (equatorialRadius * (1 - excentricitySquared / 4 - 3 * excentricitySquared * excentricitySquared / 64 - 5 * excentricitySquared * excentricitySquared * excentricitySquared / 256)); Double e1 = (1 - Math.Sqrt(1 - excentricitySquared)) / (1 + Math.Sqrt(1 - excentricitySquared)); // phi in radians Double phi1Rad = mu + (3 * e1 / 2 - 27 * e1 * e1 * e1 / 32) * Math.Sin(2 * mu) + (21 * e1 * e1 / 16 - 55 * e1 * e1 * e1 * e1 / 32) * Math.Sin(4 * mu) + (151 * e1 * e1 * e1 / 96) * Math.Sin(6 * mu); // convert to degrees Double phi1 = phi1Rad * _convertRadianToDegree; Double N1 = equatorialRadius / Math.Sqrt(1 - excentricitySquared * Math.Sin(phi1Rad) * Math.Sin(phi1Rad)); Double T1 = Math.Tan(phi1Rad) * Math.Tan(phi1Rad); Double C1 = excentricityPrimeSquared * Math.Cos(phi1Rad) * Math.Cos(phi1Rad); Double R1 = equatorialRadius * (1 - excentricitySquared) / Math.Pow(1 - excentricitySquared * Math.Sin(phi1Rad) * Math.Sin(phi1Rad), 1.5); Double D = x / (N1 * dScaleFactor); // phi in radians Double latitude = phi1Rad - (N1 * Math.Tan(phi1Rad) / R1) * (D * D / 2 - (5 + 3 * T1 + 10 * C1 - 4 * C1 * C1 - 9 * excentricityPrimeSquared) * D * D * D * D / 24 + (61 + 90 * T1 + 298 * C1 + 45 * T1 * T1 - 252 * excentricityPrimeSquared - 3 * C1 * C1) * D * D * D * D * D * D / 720); // convert to degrees latitude = latitude * _convertRadianToDegree; // lon in radians Double longitude = (D - (1 + 2 * T1 + C1) * D * D * D / 6 + (5 - 2 * C1 + 28 * T1 - 3 * C1 * C1 + 8 * excentricityPrimeSquared + 24 * T1 * T1) * D * D * D * D * D / 120) / Math.Cos(phi1Rad); // convert to degrees longitude = longOrigin + longitude * _convertRadianToDegree; Longitude = longitude; Latitude = latitude; _Datum = datum; }
private static UtmPoint MakeCentral(UtmPoint point, Int16 digits) { String value = point.ToUtmString(digits); UtmPoint utmPoint = new UtmPoint(value); Double distance = 0.5 * GridSize(digits); Double easting = utmPoint.Easting + distance; Double northing = utmPoint.Northing + distance; UtmPoint middlePoint = new UtmPoint(easting, northing, utmPoint.ZoneNumber, utmPoint.IsNorthernHemisphere); return(middlePoint); }
public UtmPoint NorthWestCornerUtm() { String value = CentralPoint.ToUtmString(_Digits); UtmPoint result = new UtmPoint(value); if (!SameZone(result)) { result = LimitToZone(result); } return(result); }
public UtmPoint SouthEastCornerUtm() { String value = CentralPoint.ToUtmString(_Digits); UtmPoint result = new UtmPoint(value); result.Easting += GridSize(_Digits); result.Northing += GridSize(_Digits); if (!SameZone(result)) { result = LimitToZone(result); } return(result); }
private UtmPoint LimitToZone(UtmPoint point) { UtmPoint result = new UtmPoint(point); Int32 minEasting = 0; Int32 maxEasting = 0; if (point.Easting < CentralPoint.Easting) { minEasting = point.Easting; maxEasting = minEasting + GridSize(_Digits); } else { maxEasting = point.Easting; minEasting = maxEasting - GridSize(_Digits); } Int32 leftZone = 0; { UtmPoint tempUtmPoint = new UtmPoint(point); tempUtmPoint.Easting = minEasting; GeoPoint tempGeoPoint = new GeoPoint(tempUtmPoint, Datum); tempUtmPoint = tempGeoPoint.CalcUTM(); leftZone = tempUtmPoint.ZoneNumber; } Int32 eastingDiff = maxEasting - minEasting; while (eastingDiff > 1) { Int32 tempEasting = minEasting + eastingDiff / 2; result = new UtmPoint(point); result.Easting = tempEasting; GeoPoint tempGeoPoint = new GeoPoint(result, Datum); UtmPoint empUtmPoint = tempGeoPoint.CalcUTM(); if (empUtmPoint.ZoneNumber > leftZone) { maxEasting = tempEasting; } else { minEasting = tempEasting; } eastingDiff = eastingDiff / 2; } return(result); }
public UtmPoint ActualCentralPoint() { String value = CentralPoint.ToUtmString(_Digits); UtmPoint west = new UtmPoint(value); west.Northing += GridSize(_Digits) / 2; UtmPoint east = new UtmPoint(west); east.Easting += GridSize(_Digits); if (!SameZone(west)) { west = LimitToZone(west); } if (!SameZone(east)) { east = LimitToZone(east); } UtmPoint result = new UtmPoint(value); result.Northing += GridSize(_Digits) / 2; result.Easting = (west.Easting + east.Easting) / 2; return(result); }
public UtmPoint CalcUTM() { //converts lat/long to UTM coords. Equations from USGS Bulletin 1532 //East Longitudes are positive, West longitudes are negative. //North latitudes are positive, South latitudes are negative //Lat and Long are in decimal degrees double eccSquared = _Datum.Ellipsoid.ExcentricitySquared; double dEquatorialRadius = _Datum.Ellipsoid.SemiMajorAxis; double k0 = 0.9996; double LongOrigin; double eccPrimeSquared = (eccSquared) / (1 - eccSquared); //Make sure the longitude is between -180.00 .. 179.9 double lLongitude = (Longitude + 180) - Math.Truncate((Longitude + 180) / 360) * 360 - 180; // -180.00 .. 179.9; double LatRad = Latitude / _convertRadianToDegree; double LongRad = Longitude / _convertRadianToDegree; Int32 ZoneNumber = (Int32)Math.Truncate((lLongitude + 180) / 6) + 1; if (Latitude >= 56.0 && Latitude < 64.0 && lLongitude >= 3.0 && lLongitude < 12.0) { ZoneNumber = 32; // larger zone for southern Norway } if (Latitude >= 72.0 && Latitude < 84.0) { // Special zones for Svalbard if (lLongitude >= 0.0 && lLongitude < 9.0) { ZoneNumber = 31; } else if (lLongitude >= 9.0 && lLongitude < 21.0) { ZoneNumber = 33; } else if (lLongitude >= 21.0 && lLongitude < 33.0) { ZoneNumber = 35; } else if (lLongitude >= 33.0 && lLongitude < 42.0) { ZoneNumber = 37; } } LongOrigin = (ZoneNumber - 1) * 6 - 180 + 3; //+3 puts origin in middle of zone double LongOriginRad = LongOrigin / _convertRadianToDegree; double N = dEquatorialRadius / Math.Sqrt(1 - eccSquared * Math.Sin(LatRad) * Math.Sin(LatRad)); double T = Math.Tan(LatRad) * Math.Tan(LatRad); double C = eccPrimeSquared * Math.Cos(LatRad) * Math.Cos(LatRad); double A = Math.Cos(LatRad) * (LongRad - LongOriginRad); double M = dEquatorialRadius * ((1 - eccSquared / 4 - 3 * eccSquared * eccSquared / 64 - 5 * eccSquared * eccSquared * eccSquared / 256) * LatRad - (3 * eccSquared / 8 + 3 * eccSquared * eccSquared / 32 + 45 * eccSquared * eccSquared * eccSquared / 1024) * Math.Sin(2 * LatRad) + (15 * eccSquared * eccSquared / 256 + 45 * eccSquared * eccSquared * eccSquared / 1024) * Math.Sin(4 * LatRad) - (35 * eccSquared * eccSquared * eccSquared / 3072) * Math.Sin(6 * LatRad)); double UTMEasting = (double)(k0 * N * (A + (1 - T + C) * A * A * A / 6 + (5 - 18 * T + T * T + 72 * C - 58 * eccPrimeSquared) * A * A * A * A * A / 120) + 500000.0); double UTMNorthing = (double)(k0 * (M + N * Math.Tan(LatRad) * (A * A / 2 + (5 - T + 9 * C + 4 * C * C) * A * A * A * A / 24 + (61 - 58 * T + T * T + 600 * C - 330 * eccPrimeSquared) * A * A * A * A * A * A / 720))); if (Latitude < 0) { UTMNorthing += 10000000.0; //10000000 meter offset for southern hemisphere } UtmPoint lResult = new UtmPoint( (Int32)Math.Truncate(UTMEasting), (Int32)Math.Truncate(UTMNorthing), ZoneNumber, Latitude >= 0); return(lResult); }