decode static method

UTM decode(
  1. String mgrsString
)

Decode the UTM parameters from a MGRS string.

@private @param {string} mgrsString an UPPERCASE coordinate string is expected. @return {object} An object literal with easting, northing, zoneLetter, zoneNumber and accuracy (in meters) properties.

Implementation

static UTM decode(String mgrsString) {
  if (mgrsString.isEmpty) {
    throw Exception('MGRSPoint coverting from nothing');
  }
  //remove any spaces in MGRS String
  mgrsString = mgrsString.replaceAll(' ', '');
  var length = mgrsString.length;
  var hunK;
  var sb = '';
  var i = 0;
  // get Zone number
  for (i; i < 2; i++) {
    var letter = mgrsString[i];
    if (!Mgrs.ALPHABET.contains(letter.toLowerCase())) {
      sb += letter;
    }
  }
  var zoneNumber = int.parse(sb);
  if (i == 0 || i + 3 > length) {
    // A good MGRS string has to be 4-5 digits long,
    // ##AAA/#AAA at least.
    throw Exception('MGRSPoint bad conversion from $mgrsString');
  }
  var zoneLetter = mgrsString[i++];
  // Should we check the zone letter here? Why not.
  if (ALPHABET.indexOf(zoneLetter.toLowerCase()) <=
          ALPHABET.indexOf('A'.toLowerCase()) ||
      zoneLetter == 'B' ||
      zoneLetter == 'Y' ||
      ALPHABET.indexOf(zoneLetter.toLowerCase()) >=
          ALPHABET.indexOf('Z'.toLowerCase()) ||
      zoneLetter == 'I' ||
      zoneLetter == 'O') {
    throw Exception(
        'MGRSPoint zone letter $zoneLetter not handled: $mgrsString');
  }
  hunK = mgrsString.substring(i, i += 2);
  var set = get100kSetForZone(zoneNumber);
  var east100k = getEastingFromChar(hunK[0], set);
  var north100k = getNorthingFromChar(hunK[1], set);
  // We have a bug where the northing may be 2000000 too low.
  // How do we know when to roll over?
  while (north100k < getMinNorthing(zoneLetter)) {
    north100k += 2000000;
  }
  // calculate the char index for easting/northing separator
  var remainder = length - i;
  if (remainder % 2 != 0) {
    throw Exception(
        'MGRSPoint has to have an even number of digits after the zone letter and two 100km letters - front half for easting meters, second half for northing meters $mgrsString');
  }
  var sep = (remainder / 2).truncate();
  var sepEasting = 0.0;
  var sepNorthing = 0.0;
  int? accuracyBonus;

  if (sep > 0) {
    accuracyBonus = (100000 / math.pow(10, sep)).round();
    var sepEastingString = mgrsString.substring(i, i + sep);
    sepEasting = double.parse(sepEastingString) * accuracyBonus;
    var sepNorthingString = mgrsString.substring(i + sep);
    sepNorthing = double.parse(sepNorthingString) * accuracyBonus;
  }
  var easting = sepEasting + east100k;
  var northing = sepNorthing + north100k;
  var utm = UTM(
      easting: easting,
      northing: northing,
      zoneLetter: zoneLetter,
      zoneNumber: zoneNumber,
      accuracy: accuracyBonus);
  return utm;
}