/// <summary> /// The function convertToGeodetic converts UTM projection (zone, /// hemisphere, easting and northing) coordinates to geodetic (latitude /// and longitude) coordinates, according to the current ellipsoid /// parameters. If any errors occur, an exception is thrown with a description /// of the error. /// </summary> /// <param name="utmCoordinates"></param> /// <returns></returns> public GeodeticCoordinates convertToGeodetic(UTMCoordinates utmCoordinates) { /* * zone : UTM zone (input) * hemisphere : North or South hemisphere (input) * easting : Easting (X) in meters (input) * northing : Northing (Y) in meters (input) * longitude : Longitude in radians (output) * latitude : Latitude in radians (output) */ double False_Northing = 0; string errorStatus = ""; int zone = (int)utmCoordinates.zone; char hemisphere = utmCoordinates.hemisphere; double easting = utmCoordinates.easting; double northing = utmCoordinates.northing; if ((zone < 1) || (zone > 60)) { errorStatus += ErrorMessages.zone; } if ((hemisphere != 'S') && (hemisphere != 'N')) { errorStatus += ErrorMessages.hemisphere; } if ((easting < MIN_EASTING) || (easting > MAX_EASTING)) { errorStatus += ErrorMessages.easting; } if ((northing < MIN_NORTHING) || (northing > MAX_NORTHING)) { errorStatus += ErrorMessages.northing; } if (errorStatus.Length > 0) { throw new ArgumentException(errorStatus); } TransverseMercator transverseMercator = getTransverseMercator(zone); if (hemisphere == 'S') { False_Northing = 10000000; } GeodeticCoordinates geodeticCoordinates = transverseMercator.convertToGeodetic(new MapProjectionCoordinates(CoordinateType.Enum.transverseMercator, easting, northing - False_Northing)); //geodeticCoordinates.setWarningMessage(""); double latitude = geodeticCoordinates.latitude; if ((latitude < (MIN_LAT - EPSILON)) || (latitude >= (MAX_LAT + EPSILON))) { /* latitude out of range */ throw new ArgumentException(ErrorMessages.northing); } return(geodeticCoordinates); }
/// <summary> /// The function convertToGeodetic converts UTM projection (zone, /// hemisphere, easting and northing) coordinates to geodetic (latitude /// and longitude) coordinates, according to the current ellipsoid /// parameters. If any errors occur, an exception is thrown with a description /// of the error. /// </summary> /// <param name="utmCoordinates"></param> /// <returns></returns> public GeodeticCoordinates convertToGeodetic(UTMCoordinates utmCoordinates) { /* * zone : UTM zone (input) * hemisphere : North or South hemisphere (input) * easting : Easting (X) in meters (input) * northing : Northing (Y) in meters (input) * longitude : Longitude in radians (output) * latitude : Latitude in radians (output) */ double False_Northing = 0; string errorStatus = ""; int zone = (int)utmCoordinates.zone; char hemisphere = utmCoordinates.hemisphere; double easting = utmCoordinates.easting; double northing = utmCoordinates.northing; if ((zone < 1) || (zone > 60)) { errorStatus += ErrorMessages.zone; } if ((hemisphere != 'S') && (hemisphere != 'N')) { errorStatus += ErrorMessages.hemisphere; } if ((easting < MIN_EASTING) || (easting > MAX_EASTING)) { errorStatus += ErrorMessages.easting; } if ((northing < MIN_NORTHING) || (northing > MAX_NORTHING)) { errorStatus += ErrorMessages.northing; } if (errorStatus.Length > 0) { throw new ArgumentException(errorStatus); } TransverseMercator transverseMercator = getTransverseMercator(zone); if (hemisphere == 'S') { False_Northing = 10000000; } GeodeticCoordinates geodeticCoordinates = transverseMercator.convertToGeodetic(new MapProjectionCoordinates(CoordinateType.Enum.transverseMercator, easting, northing - False_Northing)); //geodeticCoordinates.setWarningMessage(""); double latitude = geodeticCoordinates.latitude; if ((latitude < (MIN_LAT - EPSILON)) || (latitude >= (MAX_LAT + EPSILON))) { /* latitude out of range */ throw new ArgumentException(ErrorMessages.northing); } return geodeticCoordinates; }
public MGRSorUSNGCoordinates fromUTM(UTMCoordinates utmCoordinates, double longitude, double latitude, long precision) { /* * The function fromUTM calculates an MGRS coordinate string * based on the zone, latitude, easting and northing. * * zone : Zone number (input) * hemisphere : Hemisphere (input) * longitude : Longitude in radians (input) * latitude : Latitude in radians (input) * easting : Easting (input) * northing : Northing (input) * precision : Precision (input) * MGRSString : MGRS coordinate string (output) */ double pattern_offset = 0.0; /* Pattern offset for 3rd letter */ double grid_northing = 0.0; /* Northing used to derive 3rd letter of MGRS */ long ltr2_low_value = 0; /* 2nd letter range - low number */ long ltr2_high_value = 0; /* 2nd letter range - high number */ int[] letters = new int[3]; /* Number location of 3 letters in alphabet */ int zoneOverride = 0; int natural_zone = 0; long zone = utmCoordinates.zone; char hemisphere = utmCoordinates.hemisphere; double easting = utmCoordinates.easting; double northing = utmCoordinates.northing; getLatitudeLetter(latitude, ref letters[0]); easting = Math.Round(easting); //Check if the point is within it's natural zone //If it is not, put it there if (longitude < Math.PI) { natural_zone = (int)(31 + ((longitude) / _6)); } else { natural_zone = (int)(((longitude) / _6) - 29); } if (natural_zone > 60) { natural_zone = 1; } if (zone != natural_zone) { // reconvert to override zone UTM utmOverride = new UTM(semiMajorAxis, flattening, natural_zone); UTMCoordinates utmCoordinatesOverride = utmOverride.convertFromGeodetic(new GeodeticCoordinates(CoordinateType.Enum.geodetic, longitude, latitude)); zone = utmCoordinatesOverride.zone; hemisphere = utmCoordinatesOverride.hemisphere; easting = utmCoordinatesOverride.easting; northing = utmCoordinatesOverride.northing; } easting = Math.Round(easting); /* UTM special cases */ if (letters[0] == LETTER_V) // V latitude band { if ((zone == 31) && (easting >= _500000)) { zoneOverride = 32; // extension of zone 32V } } else if (letters[0] == LETTER_X) { if ((zone == 32) && (easting < _500000)) // extension of zone 31X { zoneOverride = 31; } else if (((zone == 32) && (easting >= _500000)) || // western extension of zone 33X ((zone == 34) && (easting < _500000))) // eastern extension of zone 33X { zoneOverride = 33; } else if (((zone == 34) && (easting >= _500000)) || // western extension of zone 35X ((zone == 36) && (easting < _500000))) // eastern extension of zone 35X { zoneOverride = 35; } else if ((zone == 36) && (easting >= _500000)) // western extension of zone 37X { zoneOverride = 37; } } if (zoneOverride != 0) { // reconvert to override zone UTM utmOverride = new UTM(semiMajorAxis, flattening, zoneOverride); UTMCoordinates utmCoordinatesOverride = utmOverride.convertFromGeodetic(new GeodeticCoordinates(CoordinateType.Enum.geodetic, longitude, latitude)); zone = utmCoordinatesOverride.zone; hemisphere = utmCoordinatesOverride.hemisphere; easting = utmCoordinatesOverride.easting; northing = utmCoordinatesOverride.northing; } easting = Math.Round(easting); northing = Math.Round(northing); double divisor = Math.Pow(10.0, (5.0 - precision)); easting = (long)(easting / divisor) * divisor; northing = (long)(northing / divisor) * divisor; if (latitude <= 0.0 && northing == 1.0e7) { latitude = 0.0; northing = 0.0; } getGridValues(zone, ref ltr2_low_value, ref ltr2_high_value, ref pattern_offset); grid_northing = northing; while (grid_northing >= TWOMIL) { grid_northing = grid_northing - TWOMIL; } grid_northing = grid_northing + pattern_offset; if (grid_northing >= TWOMIL) { grid_northing = grid_northing - TWOMIL; } letters[2] = (int)(grid_northing / ONEHT); if (letters[2] > LETTER_H) { letters[2] = letters[2] + 1; } if (letters[2] > LETTER_N) { letters[2] = letters[2] + 1; } letters[1] = (int)(ltr2_low_value + ((long)(easting / ONEHT) - 1)); if ((ltr2_low_value == LETTER_J) && (letters[1] > LETTER_N)) { letters[1] = letters[1] + 1; } return new MGRSorUSNGCoordinates(CoordinateType.Enum.militaryGridReferenceSystem, makeMGRSString(zone, letters, easting, northing, precision)); }
public UTMCoordinates toUTM(long zone, long[] letters, double easting, double northing, long precision) { /* * The function toUTM converts an MGRS coordinate string * to UTM projection (zone, hemisphere, easting and northing) coordinates * according to the current ellipsoid parameters. If any errors occur, * an exception is thrown with a description of the error. * * MGRSString : MGRS coordinate string (input) * zone : UTM zone (output) * hemisphere : North or South hemisphere (output) * easting : Easting (X) in meters (output) * northing : Northing (Y) in meters (output) */ char hemisphere = '\0'; double min_northing = 0.0; double northing_offset = 0.0; long ltr2_low_value = 0; long ltr2_high_value = 0; double pattern_offset = 0.0; double upper_lat_limit = 0.0; /* North latitude limits based on 1st letter */ double lower_lat_limit = 0.0; /* South latitude limits based on 1st letter */ double grid_easting = 0.0; /* Easting for 100,000 meter grid square */ double grid_northing = 0.0; /* Northing for 100,000 meter grid square */ double latitude = 0.0; double divisor = 1.0; UTMCoordinates utmCoordinates = new UTMCoordinates(); if ((letters[0] == LETTER_X) && ((zone == 32) || (zone == 34) || (zone == 36))) { throw new ArgumentException(ErrorMessages.mgrsstaticString); } else if ((letters[0] == LETTER_V) && (zone == 31) && (letters[1] > LETTER_D)) { throw new ArgumentException(ErrorMessages.mgrsstaticString); } else { if (letters[0] < LETTER_N) { hemisphere = 'S'; } else { hemisphere = 'N'; } getGridValues(zone, ref ltr2_low_value, ref ltr2_high_value, ref pattern_offset); /* Check that the second letter of the MGRS string is within * the range of valid second letter values * Also check that the third letter is valid */ if ((letters[1] < ltr2_low_value) || (letters[1] > ltr2_high_value) || (letters[2] > LETTER_V)) { throw new ArgumentException(ErrorMessages.mgrsstaticString); } grid_easting = (double)((letters[1]) - ltr2_low_value + 1) * ONEHT; if ((ltr2_low_value == LETTER_J) && (letters[1] > LETTER_O)) { grid_easting = grid_easting - ONEHT; } double row_letter_northing = (double)(letters[2]) * ONEHT; if (letters[2] > LETTER_O) { row_letter_northing = row_letter_northing - ONEHT; } if (letters[2] > LETTER_I) { row_letter_northing = row_letter_northing - ONEHT; } if (row_letter_northing >= TWOMIL) { row_letter_northing = row_letter_northing - TWOMIL; } getLatitudeBandMinNorthing(letters[0], ref min_northing, ref northing_offset); grid_northing = row_letter_northing - pattern_offset; if (grid_northing < 0) { grid_northing += TWOMIL; } grid_northing += northing_offset; if (grid_northing < min_northing) grid_northing += TWOMIL; easting += grid_easting; northing += grid_northing; utmCoordinates = new UTMCoordinates(CoordinateType.Enum.universalTransverseMercator, (int)zone, hemisphere, easting, northing); /* check that point is within Zone Letter bounds */ GeodeticCoordinates geodeticCoordinates = utm.convertToGeodetic(utmCoordinates); divisor = Math.Pow(10.0, (double)precision); getLatitudeRange(letters[0], ref upper_lat_limit, ref lower_lat_limit); latitude = geodeticCoordinates.latitude; if (!(((lower_lat_limit - PI_OVER_180 / divisor) <= latitude) && (latitude <= (upper_lat_limit + PI_OVER_180 / divisor)))) { utmCoordinates.warningMessage = WarningMessages.latitude; } } return utmCoordinates; }
public MGRSorUSNGCoordinates convertFromUTM(UTMCoordinates utmCoordinates, long precision) { /* * The function convertFromUTM converts UTM (zone, easting, and * northing) coordinates to an MGRS coordinate string, according to the * current ellipsoid parameters. If any errors occur, an exception is * thrown with a description of the error. * * zone : UTM zone (input) * hemisphere : North or South hemisphere (input) * easting : Easting (X) in meters (input) * northing : Northing (Y) in meters (input) * precision : Precision level of MGRS string (input) * MGRSString : MGRS coordinate string (output) */ string errorStatus = ""; long zone = utmCoordinates.zone; char hemisphere = utmCoordinates.hemisphere; double easting = utmCoordinates.easting; double northing = utmCoordinates.northing; if ((zone < 1) || (zone > 60)) { errorStatus += ErrorMessages.zone; } if ((hemisphere != 'S') && (hemisphere != 'N')) { errorStatus += ErrorMessages.hemisphere; } if ((easting < MIN_EASTING) || (easting > MAX_EASTING)) { errorStatus += ErrorMessages.easting; } if ((northing < MIN_NORTHING) || (northing > MAX_NORTHING)) { errorStatus += ErrorMessages.northing; } if ((precision < 0) || (precision > MAX_PRECISION)) { errorStatus += ErrorMessages.precision; } if (errorStatus.Length > 0) { // throw CoordinateConversionException(errorStatus); } GeodeticCoordinates geodeticCoordinates = utm.convertToGeodetic(utmCoordinates); //If the latitude is within the valid mgrs non polar range [-80, 84), //convert to mgrs using the utm path, otherwise convert to mgrs using the ups path MGRSorUSNGCoordinates mgrsorUSNGCoordinates; double latitude = geodeticCoordinates.latitude; if ((latitude >= (MIN_MGRS_NON_POLAR_LAT - EPSILON)) && (latitude < (MAX_MGRS_NON_POLAR_LAT + EPSILON))) { mgrsorUSNGCoordinates = fromUTM(utmCoordinates, geodeticCoordinates.longitude, latitude, precision); } else { mgrsorUSNGCoordinates = fromUPS(ups.convertFromGeodetic(geodeticCoordinates), precision); } return mgrsorUSNGCoordinates; }