decode static method Null safety
- 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;
}