/// <summary> /// Create a new MGRS reference object from the given UTM reference. It is /// assumed that this MGRS reference represents a point using the GRS 1980, /// International or WGS84 ellipsoids. It is assumed that the UTMRef object is /// valid. /// </summary> /// <param name="utm">A UTM reference.</param> /// <param name="isBessel">true if the parameters represent an MGRS reference using the /// Bessel 1841 ellipsoid; false is the parameters represent an MGRS /// reference using the GRS 1980, International or WGS84 ellipsoids.</param> public MGRSRef(UTMRef utm, bool isBessel = false) : base(utm.Datum) { int lngZone = utm.LngZone; int set = ((lngZone - 1) % 6) + 1; int eId = (int)Math.Floor(utm.Easting / 100000.0) + (8 * ((set - 1) % 3)); int nId = (int)Math.Floor((utm.Northing % 2000000) / 100000.0); if (eId > 8) { eId++; // Offset for no I character } if (eId > 14) { eId++; // Offset for no O character } char eIDc = (char)(eId + 64); // Northing ID offset for sets 2, 4 and 6 if (set % 2 == 0) { nId += 5; } if (isBessel) { nId += 10; } if (nId > 19) { nId -= 20; } char nIDc = NorthingIDs[nId]; UtmZoneNumber = lngZone; UtmZoneChar = utm.LatZone; EastingId = eIDc; NorthingId = nIDc; Easting = (int)Math.Round(utm.Easting) % 100000; Northing = (int)Math.Round(utm.Northing) % 100000; Precision = Precision.Precision1M; _isBessel = isBessel; }
/// <summary> /// Create a new MGRS reference object from the given UTM reference. It is /// assumed that this MGRS reference represents a point using the GRS 1980, /// International or WGS84 ellipsoids. It is assumed that the UTMRef object is /// valid. /// </summary> /// <param name="utm">A UTM reference.</param> /// <param name="isBessel">true if the parameters represent an MGRS reference using the /// Bessel 1841 ellipsoid; false is the parameters represent an MGRS /// reference using the GRS 1980, International or WGS84 ellipsoids.</param> public MGRSRef(UTMRef utm, bool isBessel) : base(utm.Datum) { int lngZone = utm.LngZone; int set = ((lngZone - 1) % 6) + 1; int eID = (int)Math.Floor(utm.Easting / 100000.0) + (8 * ((set - 1) % 3)); int nID = (int)Math.Floor((utm.Northing % 2000000) / 100000.0); if (eID > 8) { eID++; // Offset for no I character } if (eID > 14) { eID++; // Offset for no O character } char eIDc = (char)(eID + 64); // Northing ID offset for sets 2, 4 and 6 if (set % 2 == 0) { nID += 5; } if (isBessel) { nID += 10; } if (nID > 19) { nID -= 20; } char nIDc = northingIDs[nID]; this.utmZoneNumber = lngZone; this.utmZoneChar = utm.LatZone; this.eastingID = eIDc; this.northingID = nIDc; this.easting = (int)Math.Round(utm.Easting) % 100000; this.northing = (int)Math.Round(utm.Northing) % 100000; this.precision = Precision.Precision1M; this.isBessel = isBessel; }
/// <summary> /// Create a new MGRS reference object from the given UTM reference. It is /// assumed that this MGRS reference represents a point using the GRS 1980, /// International or WGS84 ellipsoids. It is assumed that the UTMRef object is /// valid. /// </summary> /// <param name="utm">A UTM reference.</param> /// <param name="isBessel">true if the parameters represent an MGRS reference using the /// Bessel 1841 ellipsoid; false is the parameters represent an MGRS /// reference using the GRS 1980, International or WGS84 ellipsoids.</param> public MGRSRef(UTMRef utm, bool isBessel) : base(utm.Datum) { int lngZone = utm.LngZone; int set = ((lngZone - 1) % 6) + 1; int eID = (int) Math.Floor(utm.Easting / 100000.0) + (8 * ((set - 1) % 3)); int nID = (int) Math.Floor((utm.Northing % 2000000) / 100000.0); if (eID > 8) eID++; // Offset for no I character if (eID > 14) eID++; // Offset for no O character char eIDc = (char) (eID + 64); // Northing ID offset for sets 2, 4 and 6 if (set % 2 == 0) { nID += 5; } if (isBessel) { nID += 10; } if (nID > 19) { nID -= 20; } char nIDc = northingIDs[nID]; this.utmZoneNumber = lngZone; this.utmZoneChar = utm.LatZone; this.eastingID = eIDc; this.northingID = nIDc; this.easting = (int) Math.Round(utm.Easting) % 100000; this.northing = (int) Math.Round(utm.Northing) % 100000; this.precision = Precision.Precision1M; this.isBessel = isBessel; }
/// <summary> /// Create a new MGRS reference object from the given UTM reference. It is /// assumed that the UTMRef object is valid. /// </summary> /// <param name="utm">A UTM reference.</param> public MGRSRef(UTMRef utm) : this(utm, false) { }
/// <summary> /// Convert this latitude and longitude to an MGRS reference. /// </summary> /// <returns>The converted MGRS reference</returns> public MGRSRef ToMGRSRef() { UTMRef utm = ToUtmRef(); return(new MGRSRef(utm)); }
/// <summary> /// Convert this latitude and longitude to a UTM reference. /// </summary> /// <returns>The converted UTM reference.</returns> /// <exception cref="NotDefinedOnUtmGridException"> /// If an attempt is made to convert a LatLng that falls outside the /// area covered by the UTM grid. The UTM grid is only defined for /// latitudes south of 84°N and north of 80°S.</exception> public UTMRef ToUtmRef() { if (Latitude < -80 || Latitude > 84) { throw new NotDefinedOnUtmGridException("Latitude (" + Latitude + ") falls outside the UTM grid."); } if (Longitude == 180.0) { Longitude = -180.0; } const double utmF0 = 0.9996; double a = Datum.ReferenceEllipsoid.SemiMajorAxis; double eSquared = Datum.ReferenceEllipsoid.EccentricitySquared; double longitude = Longitude; double latitude = Latitude; double latitudeRad = latitude * (Math.PI / 180.0); double longitudeRad = longitude * (Math.PI / 180.0); int longitudeZone = (int)Math.Floor((longitude + 180.0) / 6.0) + 1; // Special zone for Norway if (latitude >= 56.0 && latitude < 64.0 && longitude >= 3.0 && longitude < 12.0) { longitudeZone = 32; } // Special zones for Svalbard if (latitude >= 72.0 && latitude < 84.0) { if (longitude >= 0.0 && longitude < 9.0) { longitudeZone = 31; } else if (longitude >= 9.0 && longitude < 21.0) { longitudeZone = 33; } else if (longitude >= 21.0 && longitude < 33.0) { longitudeZone = 35; } else if (longitude >= 33.0 && longitude < 42.0) { longitudeZone = 37; } } double longitudeOrigin = (longitudeZone - 1) * 6 - 180 + 3; double longitudeOriginRad = longitudeOrigin * (Math.PI / 180.0); char utmZone = UTMRef.GetUTMLatitudeZoneLetter(latitude); double ePrimeSquared = (eSquared) / (1 - eSquared); double n = a / Math.Sqrt(1 - eSquared * Math.Sin(latitudeRad) * Math.Sin(latitudeRad)); double t = Math.Tan(latitudeRad) * Math.Tan(latitudeRad); double c = ePrimeSquared * Math.Cos(latitudeRad) * Math.Cos(latitudeRad); double A = Math.Cos(latitudeRad) * (longitudeRad - longitudeOriginRad); double m = a * ((1 - eSquared / 4 - 3 * eSquared * eSquared / 64 - 5 * eSquared * eSquared * eSquared / 256) * latitudeRad - (3 * eSquared / 8 + 3 * eSquared * eSquared / 32 + 45 * eSquared * eSquared * eSquared / 1024) * Math.Sin(2 * latitudeRad) + (15 * eSquared * eSquared / 256 + 45 * eSquared * eSquared * eSquared / 1024) * Math.Sin(4 * latitudeRad) - (35 * eSquared * eSquared * eSquared / 3072) * Math.Sin(6 * latitudeRad)); double utmEasting = (utmF0 * n * (A + (1 - t + c) * Math.Pow(A, 3.0) / 6 + (5 - 18 * t + t * t + 72 * c - 58 * ePrimeSquared) * Math.Pow(A, 5.0) / 120) + 500000.0); double utmNorthing = (utmF0 * (m + n * Math.Tan(latitudeRad) * (A * A / 2 + (5 - t + (9 * c) + (4 * c * c)) * Math.Pow(A, 4.0) / 24 + (61 - (58 * t) + (t * t) + (600 * c) - (330 * ePrimeSquared)) * Math.Pow(A, 6.0) / 720))); // Adjust for the southern hemisphere if (latitude < 0) { utmNorthing += 10000000.0; } return(new UTMRef(longitudeZone, utmZone, utmEasting, utmNorthing, Datum)); }