Skip to content

Global grids

The package contains a port for Dart language of conversions between geographic coordinates (lat/lon) and UTM coordinates / MGRS grid references, originally written in JavaScript by Chris Veness. See the online form on the Movable Type Scripts web site and source code of UTM and MGRS classes on GitHub.

🌐 About UTM and MGRS

The Universal Transverse Mercator (UTM) is a global map projection system that divides the world into a series of six-degree longitudinal zones. Each zone is projected using a Transverse Mercator projection, which minimizes distortion within that zone. UTM coordinates are widely used in mapping and navigation due to their accuracy and ease of use.

The Military Grid Reference System (MGRS) is an extension of the UTM system. It provides a standardized method for referencing locations on the Earth’s surface, using a combination of letters and numbers to specify grid squares. MGRS is particularly useful for military operations and other applications requiring precise location data.

UTM coordinates and MGRS grid references are based on the WGS84 ellipsoid.

📚 API documentation

Classes related to UTM coordinates with links to the API documentation (version 1.5.0):

ClassDescription
UtmUTM coordinates, with functions to parse them and convert them to geographic points.
UtmMetaMetadata (convergence and scale) as a result from UTM calculations related to position.
UtmZoneThe UTM zone represented by the lonZone number and hemisphere.

Classes about MGRS grid references:

ClassDescription
MgrsMilitary Grid Reference System (MGRS/NATO) grid references, with methods to parse references, and to convert between MGRS references and UTM coordinates.
MgrsGridSquareThe 100km grid square (or the 100,000-meter square identifier) as a part of the grid zone in MGRS/NATO grid references.
MgrsGridZoneA grid zone as a polygon of 6° × 8° in MGRS/NATO grid references.

See also other classes in the geodesy sub package.

🗒️ Sample code

The following code snippets demonstrate how to convert between geographic coordinates, UTM coordinates, and MGRS grid references using the geobase package.

// sample geographic position
final eiffel = Geographic(lat: 48.8582, lon: 2.2945);
// UTM coordinates for the position
final eiffelUtm = eiffel.toUtm();
print(eiffelUtm.toText()); // "31 N 448252 5411933"
print(eiffelUtm.zone.lonZone); // "31" (longitudinal zone)
print(eiffelUtm.zone.hemisphere.symbol); // "N" (hemisphere, N or S)
// UTM easting and northing are floating point values in meters
print(eiffelUtm.easting.toStringAsFixed(3)); // "448251.795"
print(eiffelUtm.northing.toStringAsFixed(3)); // "5411932.678"
// the projected position contains x (easting) and y (northing) values, with
// optional z (elevation) and m (measure) values
print(eiffelUtm.projected.toText(decimals: 3)); // "448251.795,5411932.678"
// UTM coordinates for the position with extra metadata
final eiffelUtmMeta = eiffel.toUtmMeta();
print(eiffelUtmMeta.position.toText()); // "31 N 448252 5411933"
// The bearing of the grid north clockwise from the true north, in degrees.
print(eiffelUtmMeta.convergence.toStringAsFixed(3)); // "-0.531"
// The scale factor at the position (factor is 0.9996 at the central meridian)
print(eiffelUtmMeta.scale.toStringAsFixed(6)); // "0.999633"
// The UTM zone can be forced to neighbour zones too, but if the position is
// out of the defined limits of a zone, then the convergence gets larger and
// the scale error indicated by the scale factor increases.
final zone30 = UtmZone(30, 'N');
final eiffelUtmZone30Meta = eiffel.toUtmMeta(zone: zone30, verifyEN: false);
print(eiffelUtmZone30Meta.position.toText()); // "30 N 888277 5425221"
print(eiffelUtmZone30Meta.convergence.toStringAsFixed(3)); // "3.992"
print(eiffelUtmZone30Meta.scale.toStringAsFixed(6)); // "1.001453"
// UTM coordinates can be constructed from components too
final eiffelUtm2 = Utm(31, 'N', eiffelUtm.easting, eiffelUtm.northing);
print(eiffelUtm == eiffelUtm2); // "true"
// MGRS grid reference for the position
final eiffelMgrs = eiffel.toMgrs();
print(eiffelMgrs.toText()); // "31U DQ 48251 11932"
print(eiffelMgrs.gridSquare.lonZone); // "31" (longitudinal zone)
print(eiffelMgrs.gridSquare.band); // "U" (latitudinal band)
print(eiffelMgrs.gridSquare.column); // "D" (100km square column)
print(eiffelMgrs.gridSquare.row); // "Q" (100km square row)
// MGRS easting and northing are integer values in meters, truncated from the
// UTM coordinates as MGRS grid references refer to squares rather than points
// (both values has a range from 0 to 99999 within a 100 km square)
print(eiffelMgrs.easting); // "48251"
print(eiffelMgrs.northing); // "11932"
// It's also possible to convert between UTM coordinates and MGRS references
print(eiffelUtm.toMgrs().toText()); // "31U DQ 48251 11932"
// Not the same as the original UTM coordinates because of the truncation
print(eiffelMgrs.toUtm().toText()); // "31 N 448251 5411932"
// UTM coordinates can be converted back to geographic coordinates;
print(eiffelUtm.toGeographic().latLonDms()); // "48.8582°N, 2.2945°E"
// MGRS references can be constructed from components too (4Q FJ 12345 67890)
final honoluluMgrs = Mgrs(4, 'Q', 'F', 'J', 12345, 67890);
final honoluluUtm = honoluluMgrs.toUtm();
print(honoluluMgrs.toText()); // "4Q FJ 12345 67890"
print(honoluluUtm.toText()); // "4 N 612345 2367890"
// The `toText()` for UTM has more options for formatting, for example:
print(eiffelUtm.toText(decimals: 3)); // "31 N 448251.795 5411932.678"
print(honoluluUtm.toText(zeroPadZone: true)); // "04 N 612345 2367890"
print(honoluluUtm.toText(swapXY: true)); // "4 N 2367890 612345"
// Also the `toText()` for MGRS has more options for formatting, for example:
print(honoluluMgrs.toText(zeroPadZone: true)); // "04Q FJ 12345 67890"
print(honoluluMgrs.toText(militaryStyle: true)); // "4QFJ1234567890"
// MGRS references can be printed in different precisions
print(honoluluMgrs.toText(digits: 8)); // "4Q FJ 1234 6789" (10 m precision)
print(honoluluMgrs.toText(digits: 4)); // "4Q FJ 12 67" (1 km precision)
print(honoluluMgrs.gridSquare.toText()); // "4Q FJ" (100 km precision)