Skip to content

Commit 0921e99

Browse files
committed
Point to MGRS conversion latitude min/max bounding and longitude normalization
1 parent 7a68ddc commit 0921e99

File tree

3 files changed

+171
-5
lines changed

3 files changed

+171
-5
lines changed

CHANGELOG.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ Adheres to [Semantic Versioning](http://semver.org/).
66

77
## 2.1.1 (TBD)
88

9-
* TBD
9+
* Point to MGRS conversion latitude min/max bounding and longitude normalization
1010

1111
## [2.1.0](https://github.com/ngageoint/mgrs-java/releases/tag/2.1.0) (09-22-2022)
1212

src/main/java/mil/nga/mgrs/MGRS.java

+27-4
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import mil.nga.mgrs.gzd.GridZone;
1414
import mil.nga.mgrs.gzd.GridZones;
1515
import mil.nga.mgrs.utm.UTM;
16+
import mil.nga.sf.util.GeometryUtils;
1617

1718
/**
1819
* Military Grid Reference System Coordinate
@@ -460,7 +461,17 @@ private static String removeSpaces(String value) {
460461
*/
461462
public static MGRS from(Point point) {
462463

463-
point = point.toDegrees();
464+
point = point.copy().toDegrees();
465+
466+
// Bound the latitude if needed
467+
if (point.getLatitude() < MGRSConstants.MIN_LAT) {
468+
point.setLatitude(MGRSConstants.MIN_LAT);
469+
} else if (point.getLatitude() > MGRSConstants.MAX_LAT) {
470+
point.setLatitude(MGRSConstants.MAX_LAT);
471+
}
472+
473+
// Normalize the longitude if needed
474+
GeometryUtils.normalizeWGS84(point);
464475

465476
UTM utm = UTM.from(point);
466477

@@ -478,6 +489,20 @@ public static MGRS from(Point point) {
478489
easting, northing);
479490
}
480491

492+
/**
493+
* Convert the coordinate to MGRS
494+
*
495+
* @param longitude
496+
* longitude
497+
* @param latitude
498+
* latitude
499+
* @return MGRS
500+
* @since 2.1.1
501+
*/
502+
public static MGRS from(double longitude, double latitude) {
503+
return from(Point.degrees(longitude, latitude));
504+
}
505+
481506
/**
482507
* Parse a MGRS string
483508
*
@@ -544,9 +569,7 @@ public static MGRS parse(String mgrs) throws ParseException {
544569
GridType.HUNDRED_KILOMETER.getPrecision())
545570
.toPoint();
546571
if (gridBounds.contains(northeast)) {
547-
mgrsValue = from(
548-
Point.degrees(gridSouthwest.getLongitude(),
549-
gridSouthwest.getLatitude()));
572+
mgrsValue = from(gridSouthwest);
550573
}
551574
} else if (westBounds) {
552575
Point east = MGRS

src/test/java/mil/nga/mgrs/MGRSTest.java

+143
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import mil.nga.mgrs.gzd.GridRange;
1717
import mil.nga.mgrs.gzd.GridZone;
1818
import mil.nga.mgrs.utm.UTM;
19+
import mil.nga.sf.util.GeometryConstants;
1920

2021
/**
2122
* MGRS Test
@@ -325,6 +326,148 @@ public void testCoordinate() throws ParseException {
325326

326327
}
327328

329+
/**
330+
* Test parsing point bounds
331+
*/
332+
@Test
333+
public void testPointBounds() {
334+
335+
// Max latitude tests
336+
337+
String mgrs = "39XVP9907028094";
338+
String mgrs2 = "39XVN9902494603";
339+
double longitude = 50.920338;
340+
double latitudeBelow = 83.7;
341+
double latitudeAbove = 100.0;
342+
343+
Point point = Point.degrees(longitude, MGRSConstants.MAX_LAT);
344+
assertEquals(mgrs, MGRS.from(point).coordinate());
345+
346+
point = Point.degrees(longitude, latitudeBelow);
347+
assertEquals(mgrs2, MGRS.from(point).coordinate());
348+
349+
point = Point.degrees(longitude,
350+
GeometryConstants.WEB_MERCATOR_MAX_LAT_RANGE);
351+
assertEquals(mgrs, MGRS.from(point).coordinate());
352+
353+
point = Point.degrees(longitude,
354+
GeometryConstants.WGS84_HALF_WORLD_LAT_HEIGHT);
355+
assertEquals(mgrs, MGRS.from(point).coordinate());
356+
357+
point = Point.degrees(longitude, latitudeAbove);
358+
assertEquals(mgrs, MGRS.from(point).coordinate());
359+
360+
// Max latitude and max longitude tests
361+
362+
longitude += (2 * GeometryConstants.WGS84_HALF_WORLD_LON_WIDTH);
363+
364+
point = Point.degrees(longitude, MGRSConstants.MAX_LAT);
365+
assertEquals(mgrs, MGRS.from(point).coordinate());
366+
367+
point = Point.degrees(longitude, latitudeBelow);
368+
assertEquals(mgrs2, MGRS.from(point).coordinate());
369+
370+
point = Point.degrees(longitude,
371+
GeometryConstants.WEB_MERCATOR_MAX_LAT_RANGE);
372+
assertEquals(mgrs, MGRS.from(point).coordinate());
373+
374+
point = Point.degrees(longitude,
375+
GeometryConstants.WGS84_HALF_WORLD_LAT_HEIGHT);
376+
assertEquals(mgrs, MGRS.from(point).coordinate());
377+
378+
point = Point.degrees(longitude, latitudeAbove);
379+
assertEquals(mgrs, MGRS.from(point).coordinate());
380+
381+
// Max latitude and min longitude tests
382+
383+
longitude -= (4 * GeometryConstants.WGS84_HALF_WORLD_LON_WIDTH);
384+
385+
point = Point.degrees(longitude, MGRSConstants.MAX_LAT);
386+
assertEquals(mgrs, MGRS.from(point).coordinate());
387+
388+
point = Point.degrees(longitude, latitudeBelow);
389+
assertEquals(mgrs2, MGRS.from(point).coordinate());
390+
391+
point = Point.degrees(longitude,
392+
GeometryConstants.WEB_MERCATOR_MAX_LAT_RANGE);
393+
assertEquals(mgrs, MGRS.from(point).coordinate());
394+
395+
point = Point.degrees(longitude,
396+
GeometryConstants.WGS84_HALF_WORLD_LAT_HEIGHT);
397+
assertEquals(mgrs, MGRS.from(point).coordinate());
398+
399+
point = Point.degrees(longitude, latitudeAbove);
400+
assertEquals(mgrs, MGRS.from(point).coordinate());
401+
402+
// Min latitude tests
403+
404+
mgrs = "52CDS8938618364";
405+
mgrs2 = "52CDT8854707650";
406+
longitude = 128.4525;
407+
latitudeAbove = -79.2;
408+
latitudeBelow = -100.0;
409+
410+
point = Point.degrees(longitude, MGRSConstants.MIN_LAT);
411+
assertEquals(mgrs, MGRS.from(point).coordinate());
412+
413+
point = Point.degrees(longitude, latitudeAbove);
414+
assertEquals(mgrs2, MGRS.from(point).coordinate());
415+
416+
point = Point.degrees(longitude,
417+
GeometryConstants.WEB_MERCATOR_MIN_LAT_RANGE);
418+
assertEquals(mgrs, MGRS.from(point).coordinate());
419+
420+
point = Point.degrees(longitude,
421+
-GeometryConstants.WGS84_HALF_WORLD_LAT_HEIGHT);
422+
assertEquals(mgrs, MGRS.from(point).coordinate());
423+
424+
point = Point.degrees(longitude, latitudeBelow);
425+
assertEquals(mgrs, MGRS.from(point).coordinate());
426+
427+
// Min latitude and max longitude tests
428+
429+
longitude += (2 * GeometryConstants.WGS84_HALF_WORLD_LON_WIDTH);
430+
431+
point = Point.degrees(longitude, MGRSConstants.MIN_LAT);
432+
assertEquals(mgrs, MGRS.from(point).coordinate());
433+
434+
point = Point.degrees(longitude, latitudeAbove);
435+
assertEquals(mgrs2, MGRS.from(point).coordinate());
436+
437+
point = Point.degrees(longitude,
438+
GeometryConstants.WEB_MERCATOR_MIN_LAT_RANGE);
439+
assertEquals(mgrs, MGRS.from(point).coordinate());
440+
441+
point = Point.degrees(longitude,
442+
-GeometryConstants.WGS84_HALF_WORLD_LAT_HEIGHT);
443+
assertEquals(mgrs, MGRS.from(point).coordinate());
444+
445+
point = Point.degrees(longitude, latitudeBelow);
446+
assertEquals(mgrs, MGRS.from(point).coordinate());
447+
448+
// Min latitude and min longitude tests
449+
450+
longitude -= (4 * GeometryConstants.WGS84_HALF_WORLD_LON_WIDTH);
451+
452+
point = Point.degrees(longitude, MGRSConstants.MIN_LAT);
453+
assertEquals(mgrs, MGRS.from(point).coordinate());
454+
455+
point = Point.degrees(longitude, latitudeAbove);
456+
assertEquals(mgrs2, MGRS.from(point).coordinate());
457+
458+
point = Point.degrees(longitude,
459+
GeometryConstants.WEB_MERCATOR_MIN_LAT_RANGE);
460+
assertEquals(mgrs, MGRS.from(point).coordinate());
461+
462+
point = Point.degrees(longitude,
463+
-GeometryConstants.WGS84_HALF_WORLD_LAT_HEIGHT);
464+
assertEquals(mgrs, MGRS.from(point).coordinate());
465+
466+
point = Point.degrees(longitude, latitudeBelow);
467+
assertEquals(mgrs, MGRS.from(point).coordinate());
468+
469+
}
470+
328471
/**
329472
* Test parsing GZD coordinates
330473
*

0 commit comments

Comments
 (0)