Mgrs.parse constructor
Parses a MGRS grid reference from a text string like '31U DQ 48251 11932'.
The input text should contains following elements:
- grid zone designator (GZD), e.g. ‘31U’, where zone is 1-60 and band is C..X covering 80°S..84°N
- 100km grid square letter-pair, e.g. ‘DQ’, where each letter represents 100km grid square column (‘e’) and row (‘n’) respectively
- easting, e.g. ‘48251’ (metres)
- northing, e.g. ‘11932’ (metres)
Use datum
to set the datum for calculations with a reference ellipsoid
and datum transformation parameters.
Throws FormatException if coordinates are invalid.
Examples:
// The MGRS grid reference parsed from text (same as using the default
// constructor `Mgrs(31, 'U', 'D', 'Q', 48251, 11932)`).
final mgrsRef = Mgrs.parse('31U DQ 48251 11932');
// Military style without separators.
final mgrsRefMil = Mgrs.parse('31UDQ4825111932');
Implementation
factory Mgrs.parse(
String text, {
Datum datum = Datum.WGS84,
}) {
// this shall contain: [ gzd, en100k, easting, northing ]
List<String>? ref;
// check for military-style grid reference with no separators
final trimmed = text.trim();
if (trimmed.length >= 6 && RegExp(r'\s+').allMatches(trimmed).isEmpty) {
// no whitespace found and at least 6 characters, should contain also
//easting and northing
// convert mgrsGridRef to standard space-separated format
final exp =
RegExp(r'(\d\d?[A-Z])([A-Z]{2})([0-9]{2,10})', caseSensitive: false)
.allMatches(text)
.map((m) => m.groups([1, 2, 3]));
if (exp.isEmpty) {
throw FormatException('invalid MGRS grid reference `$text`');
}
final parsed = exp.first;
final gzd = parsed[0]!;
final en100k = parsed[1]!;
final en = parsed[2]!;
final easting = en.substring(0, en.length ~/ 2);
final northing = en.substring(en.length ~/ 2);
ref = [gzd, en100k, easting, northing];
}
// if ref still null then match separate elements (separated by whitespace)
// the result should contain: [ gzd, en100k, easting, northing ]
ref ??= trimmed.split(RegExp(r'\s+'));
// check for 4 elements in MGRS grid reference
if (ref.length != 4) {
throw FormatException('invalid MGRS grid reference `$text`');
}
// split grid ref into gzd, en100k, e, n
final gzd = ref[0];
final en100k = ref[1];
final e = ref[2];
final n = ref[3];
if (!(gzd.length == 2 || gzd.length == 3) || en100k.length != 2) {
throw FormatException('invalid MGRS grid reference `$text`');
}
// split gzd into zone (one or two digits), band (one letter)
final gzdLen = gzd.length;
final lonZone = int.parse(gzd.substring(0, gzdLen - 1));
final band = gzd.substring(gzdLen - 1, gzdLen);
// split 100km letter-pair into column and row letters
final column = en100k[0];
final row = en100k[1];
final easting = _parseCoordinate(e);
final northing = _parseCoordinate(n);
// use the default constructor as it also validates the coordinates (and
// constructs also a MgrsGridSquare object)
return Mgrs(
lonZone,
band,
column,
row,
easting,
northing,
datum: datum,
);
}