UTM and MGRS
NGA's UTM and MGRS · checked against GeographicLib's GeoConvert
Published · 1682 cases
What it is
UTM splits the world into 60 zones, each 6° of longitude wide, and flattens each onto its own grid in metres: an easting and a northing. MGRS is the military form of the same grid. It names the zone, a latitude band and a 100 km square, then gives the easting and northing inside that square, with more digits for more precision.
Part of 10U DU 85234 71665 |
Means |
|---|---|
10 |
Zone 10, 126° W to 120° W |
U |
Latitude band U, 48° N to 56° N |
DU |
The 100 km square |
85234 71665 |
Easting and northing in that square: five digits each is 1 m |
A reference names the south-west corner of the square the point is in. So each digit is truncated, never rounded. This is the most common mistake in MGRS code.
The test data writes references as GeographicLib does, with no spaces and the zone padded to two digits: 10UDU8523471665. How to space them for a person is the display’s call.
Operations
| Operation | Gives |
|---|---|
toUtm |
UTM from a latitude and longitudeIn: latitudeInDegrees, longitudeInDegreesOut: zone, hemisphere, eastingInMeters, northingInMeters, convergenceInDegrees, pointScale |
fromUtm |
A latitude and longitude from UTMIn: zone, hemisphere, eastingInMeters, northingInMetersOut: latitudeInDegrees, longitudeInDegrees |
toMgrs |
An MGRS reference from a latitude and longitudeIn: latitudeInDegrees, longitudeInDegrees, precisionInDigitsOut: mgrs |
fromMgrs |
The latitude and longitude of the reference's square's centreIn: mgrsOut: latitudeInDegrees, longitudeInDegrees |
parse |
A latitude and longitude from a typed coordinate: DD, DDM, DMS, UTM or MGRSIn: textOut: latitudeInDegrees, longitudeInDegrees |
Fields
| Field | Meaning |
|---|---|
latitudeInDegrees | −90 to 90, WGS84, north positive |
longitudeInDegrees | −180 to 180, WGS84, east positive. 180 is the same meridian as −180, in zone 1. |
zone | 1 to 60; 0 for UPS, from 84° N and beyond 80° S. Exactly 80° S is still UTM. |
hemisphere | north or south. The equator is north. |
eastingInMeters | In the zone, with 500,000 on its central meridian. UPS puts 2,000,000 at the pole. |
northingInMeters | From the equator in the north, from 10,000 km south of it in the south. UPS puts 2,000,000 at the pole. |
convergenceInDegrees | Grid convergence: the angle clockwise from true north to grid north |
pointScale | The grid's scale at the point: 0.9996 on a UTM central meridian, 0.994 at a pole |
precisionInDigits | 0 to 5 digits each for easting and northing: 0 names the 100 km square, 5 is 1 m |
mgrs | GeographicLib's form: the zone padded to two digits, the band, the square's two letters and the digits, with no spaces, like 04QFJ1234567890. UPS has no zone: ZAH0000000000. fromMgrs also takes an unpadded zone and lower case. |
text | A coordinate as a person types it: decimal degrees; degrees and minutes, or degrees, minutes and seconds, with ° ' " or colons; hemisphere letters before or after, and either order when lettered. Or UTM as 10n 491221 5458889, or MGRS. |
Edge cases
| Case | What it tests |
|---|---|
edge-to-utm-norway-32vtoUtm | Norway: at 60° N, 5° E is zone 32, not 31. |
edge-to-utm-norway-32v-west-edgetoUtm | Zone 32V is widened west to 3° E. |
edge-to-utm-norway-31v-west-of-edgetoUtm | Just west of 3° E: still zone 31. |
edge-to-utm-norway-32v-south-edgetoUtm | Exactly 56° N is band V, so the Norway rule applies. |
edge-to-utm-norway-31u-south-of-edgetoUtm | Just south of 56° N is band U: zone 31. |
edge-to-utm-norway-31w-north-of-bandtoUtm | Exactly 64° N is band W: zone 31 again. |
edge-to-utm-svalbard-31xtoUtm | Svalbard: zone 31X runs to 9° E. |
edge-to-utm-svalbard-33x-westtoUtm | Zones 32X, 34X and 36X don't exist: 9° E is 33X. |
edge-to-utm-svalbard-37xtoUtm | 33° E starts zone 37X. |
edge-to-utm-svalbard-32w-below-bandtoUtm | Just below 72° N is band W: the Svalbard rule doesn't apply. |
edge-to-utm-utm-last-northtoUtm | Just below 84° N: still UTM. |
edge-to-utm-ups-first-northtoUtm | Exactly 84° N is UPS, zone 0. |
edge-to-utm-utm-last-southtoUtm | Exactly 80° S is still UTM. |
edge-to-utm-ups-first-southtoUtm | Just past 80° S: UPS. |
edge-to-utm-antimeridian-easttoUtm | 180° is the same meridian as −180°: zone 1. |
edge-to-utm-zone-60toUtm | Just west of 180°: zone 60. |
edge-to-utm-equatortoUtm | The equator is north, with northing 0. |
edge-to-utm-just-south-of-equatortoUtm | A hair south: northing just under 10,000,000. |
edge-to-utm-north-poletoUtm | The pole is UPS easting and northing 2,000,000, scale 0.994. |
edge-to-utm-central-meridiantoUtm | On the central meridian: easting exactly 500,000, convergence 0, scale 0.9996. |
edge-to-mgrs-equatortoMgrs | Northing 0 at the equator: 00000. |
edge-to-mgrs-north-poletoMgrs | UPS has no zone number: ZAH. |
edge-from-utm-truncationfromUtm | The point the page's diagram draws: easting 85234.9, northing 71665.8 in its square. |
edge-to-mgrs-truncation-5toMgrs | Truncated, not rounded: 85234 71665, not 85235 71666. |
edge-to-mgrs-truncation-3toMgrs | Three digits truncate further: 852 716. |
edge-from-mgrs-unpadded-zonefromMgrs | 4Q reads the same as 04Q. |
edge-from-mgrs-lower-casefromMgrs | Lower case reads the same. |
edge-from-mgrs-100-km-squarefromMgrs | No digits: the centre of the 100 km square. |
parse-longitude-firstparse | Hemisphere letters say which is which, so the longitude can come first. |
parse-degrees-minutes-secondsparse | Degrees, minutes and seconds with ° ' and " marks. |
parse-colonsparse | Colons instead of marks. |
parse-utmparse | Three parts: a UTM zone and hemisphere, easting and northing. |
parse-mgrsparse | One part: an MGRS reference, read as its square's centre. |
invalid-from-utm-easting-1500-kmfromUtm | Past the zone's easting limits: outOfRange. |
invalid-from-mgrs-odd-digitsfromMgrs | An odd number of digits: invalidInput. |
invalid-parse-two-latitudesparse | Both lettered N: invalidInput. |
invalid-to-mgrs-precision-6toMgrs | Past this file's 0 to 5 digits. |
Their inputs and expected values are in vectors.json; search for the case's id.
For agents
Implement the Transverse Mercator projection with the Krüger series to sixth order in n, as in Karney (2011), on WGS84, with a scale of 0.9996 on each zone’s central meridian and false easting 500,000 m (and false northing 10,000,000 m in the south). Simpler textbook formulas drift near zone edges and fail the 1 mm tolerance. Beyond it, use Universal Polar Stereographic, zone 0, with scale 0.994 at the pole and false easting and northing 2,000,000 m. Apply the Norway and Svalbard zone exceptions. For MGRS, truncate the digits, never round, and read a reference back as the centre of its square. GeographicLib’s GeoConvert is the reference: match its choices, including where UPS starts. Pass every case in vectors.json within its tolerance.
Test data
vectors.json holds 1682 cases, published 2026-09-29. Earth model: WGS84. How to read it: Test data format.
| Operation | Cases |
|---|---|
toUtm |
427427 reference · 26 edge · 9 polar · 1 invalid |
fromUtm |
403403 reference · 1 edge · 3 polar · 2 invalid |
toMgrs |
430429 reference · 29 edge · 9 polar · 1 invalid |
fromMgrs |
408408 reference · 6 edge · 3 polar · 2 invalid |
parse |
1414 reference · 11 edge · 3 invalid |
Tags say where each value came from: what they mean.
| Field | Tolerance |
|---|---|
latitudeInDegrees | ± 0.0000001 |
longitudeInDegrees | ± 0.0000001 |
eastingInMeters | ± 0.001 |
northingInMeters | ± 0.001 |
convergenceInDegrees | ± 0.000001 |
pointScale | ± 0.0000001 |
Every other field is compared exactly.
Implementations
| Repo | Status |
|---|---|
| gshaw/algorithms-swiftSwift | Passes |
Each is a public repo that runs this page's test data with mise run test. See how implementations work.
Source
| Standard | Universal Grids and Grid Reference Systems, NGA.STND.0037National Geospatial-Intelligence Agency · Public domain |
| Method | Transverse Mercator with an accuracy of a few nanometersC. F. F. Karney, Journal of Geodesy 85, 475–485 (2011). https://doi.org/10.1007/s00190-011-0445-3 |
| Reference program | GeoConvert, GeographicLib 2.7Charles Karney. Every call and its output is in /utm-mgrs/sources/geoconvert.txt · MIT |