Skip to content

Commit cb5e347

Browse files
committed
Allow single-digit zone when parsing MGRS grid reference
Single-digit zones needn't have a leading zero, as in e.g. Widipedia article. Also add tests from Defense Mapping Agency Technical Manual 8358.1.
1 parent ab0c504 commit cb5e347

File tree

3 files changed

+26
-9
lines changed

3 files changed

+26
-9
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
- Fix UTM constructor northing range check
99
- Fix Mgrs.toUtm() edge case at zone boundaries (e.g. @ 64°S,0°E)
1010
- Fix rounding error in Utm.toMgrs() which caused UTM for 80°S,0°E to fail
11+
- Allow single-digit zone when parsing MGRS grid reference [#104]
1112

1213
## [2.4.0] - 2022-03-16
1314

mgrs.js

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -148,18 +148,24 @@ class Mgrs {
148148
*
149149
* @example
150150
* const mgrsRef = Mgrs.parse('31U DQ 48251 11932');
151-
* const mgrsRef = Mgrs.parse('31UDQ4825111932');
151+
* const mgrsRef = Mgrs.parse('31UDQ4825111932'); // military style no separators
152152
* // mgrsRef: { zone:31, band:'U', e100k:'D', n100k:'Q', easting:48251, northing:11932 }
153153
*/
154154
static parse(mgrsGridRef) {
155155
if (!mgrsGridRef) throw new Error(`invalid MGRS grid reference ‘${mgrsGridRef}’`);
156156

157157
// check for military-style grid reference with no separators
158-
if (!mgrsGridRef.trim().match(/\s/)) {
159-
if (!Number(mgrsGridRef.slice(0, 2))) throw new Error(`invalid MGRS grid reference ‘${mgrsGridRef}’`);
160-
let en = mgrsGridRef.trim().slice(5); // get easting/northing following zone/band/100ksq
161-
en = en.slice(0, en.length/2)+' '+en.slice(-en.length/2); // separate easting/northing
162-
mgrsGridRef = mgrsGridRef.slice(0, 3)+' '+mgrsGridRef.slice(3, 5)+' '+en; // insert spaces
158+
if (!mgrsGridRef.trim().match(/\s/)) { // replace with standard space-separated format
159+
const milref = mgrsGridRef.match(/(\d\d?[A-Z])([A-Z]{2})([0-9]{2,10})/);
160+
if (!milref) throw new Error(`invalid MGRS grid reference ‘${mgrsGridRef}’`);
161+
const mil = {
162+
gzd: milref[1],
163+
en100k: milref[2],
164+
en: milref[3],
165+
};
166+
mil.e = mil.en.slice(0, mil.en.length/2);
167+
mil.n = mil.en.slice(-mil.en.length/2);
168+
mgrsGridRef = `${mil.gzd} ${mil.en100k} ${mil.e} ${mil.n}`;
163169
}
164170

165171
// match separate elements (separated by whitespace)
@@ -168,9 +174,9 @@ class Mgrs {
168174
if (ref==null || ref.length!=4) throw new Error(`invalid MGRS grid reference ‘${mgrsGridRef}’`);
169175

170176
// split gzd into zone/band
171-
const gzd = ref[0];
172-
const zone = gzd.slice(0, 2);
173-
const band = gzd.slice(2, 3);
177+
const gzd = ref[0].match(/(\d\d?)([A-Z])/i);
178+
const zone = gzd[1];
179+
const band = gzd[2];
174180

175181
// split 100km letter-pair into e/n
176182
const en100k = ref[1];

test/utm-mgrs-tests.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,16 @@ describe('utm/mgrs', function() {
7070
});
7171

7272
describe('MGRS parse', function() {
73+
// note Wikipedia considers 4Q & 4Q FJ to be valid MGRS values; this library expects easting & northing;
74+
test('Wikipedia 4Q FJ 1 6', () => Mgrs.parse('4Q FJ 1 6').toString(2).should.equal('04Q FJ 1 6'));
75+
test('Wikipedia 4Q FJ 12 67', () => Mgrs.parse('4Q FJ 12 67').toString(4).should.equal('04Q FJ 12 67'));
76+
test('Wikipedia 4Q FJ 123 678', () => Mgrs.parse('4Q FJ 123 678').toString(6).should.equal('04Q FJ 123 678'));
77+
test('Wikipedia 4Q FJ 1234 6789', () => Mgrs.parse('4Q FJ 1234 6789').toString(8).should.equal('04Q FJ 1234 6789'));
78+
test('Wikipedia 4Q FJ 12345 67890', () => Mgrs.parse('4Q FJ 12345 67890').toString(10).should.equal('04Q FJ 12345 67890'));
79+
// Defense Mapping Agency Technical Manual 8358.1: Datums, Ellipsoids, Grids, and Grid Reference Systems 3-4
80+
test('DMA 18SUU80', () => Mgrs.parse('18SUU80').toString(2).should.equal('18S UU 8 0'));
81+
test('DMA 18SUU8401', () => Mgrs.parse('18SUU8401').toString(4).should.equal('18S UU 84 01'));
82+
test('DMA 18SUU8360140', () => Mgrs.parse('18SUU836014').toString(6).should.equal('18S UU 836 014'));
7383
test('parse fail 1', () => should.Throw(function() { Mgrs.parse(null); }, Error, 'invalid MGRS grid reference ‘null’'));
7484
test('parse fail 2', () => should.Throw(function() { Mgrs.parse('Cambridge'); }, Error, 'invalid MGRS grid reference ‘Cambridge’'));
7585
test('parse fail 3', () => should.Throw(function() { Mgrs.parse('New York'); }, Error, 'invalid MGRS grid reference ‘New York’'));

0 commit comments

Comments
 (0)