toUtm method

Utm toUtm()

Converts this MGRS grid reference to the UTM projected coordinates.

Grid references refer to squares rather than points (with the size of the square indicated by the precision of the reference); this conversion will return the UTM coordinate of the SW corner of the grid reference square.

Returns the UTM coordinate of the SW corner of this MGRS grid reference.

Examples:

  final mgrsRef = Mgrs.parse('31U DQ 48251 11932');
  final utmCoord = mgrsRef.toUtm(); // 31 N 448251 5411932

Implementation

Utm toUtm() {
  final lonZone = gridSquare.lonZone;
  final isNorth =
      _latBands.indexOf(gridSquare.band) >= _latBands.indexOf('N');
  final hemisphere = isNorth ? 'N' : 'S';

  // get easting specified by e100k (note +1 because eastings start at 166e3
  // due to 500km false origin)
  final col =
      _columnLetters[(lonZone - 1) % 3].indexOf(gridSquare.column) + 1;
  final e100kNum = col * 100000; // e100k in metres

  // get northing specified by n100k
  final row = _rowLetters[(lonZone - 1) % 2].indexOf(gridSquare.row);
  final n100kNum = row * 100000; // n100k in metres

  // latitude of (bottom of) band, 10 bands above the equator, 8°latitude each
  final latBand = (_latBands.indexOf(gridSquare.band) - 10) * 8;

  // get southern-most northing of bottom of band, using floor() to extend to
  // include entirety of bottom-most 100km square - note in northern
  // hemisphere, centre of zone will be furthest south; in southern hemisphere
  // extremity of zone will be furthest south, so use 3°E / 0°E
  final position = Utm.fromGeographic(
    Geographic(
      lat: latBand.toDouble(),
      lon: isNorth ? 3.0 : 0.0,
    ),
    datum: datum,
    roundResults: false,
  );
  final nBand = (position.northing / 100000.0).floor() * 100000;

  // 100km grid square row letters repeat every 2,000km north; add enough
  // 2,000km blocks to get into required band
  var n2M = 0; // northing of 2,000km block
  while (n2M + n100kNum + northing < nBand) {
    n2M += 2000000;
  }

  return Utm(
    gridSquare.lonZone,
    hemisphere,
    (e100kNum + easting).toDouble(),
    (n2M + n100kNum + northing).toDouble(),
    datum: datum,
  );
}