From 25de5cee060d109aeda383f6ad3a1c601c4b2e6f Mon Sep 17 00:00:00 2001 From: Glenn Burkhardt Date: Wed, 14 Aug 2019 00:37:09 -0400 Subject: [PATCH 1/6] Fix two problems: a) Index out of bounds error due to typo in convertMGRSToUPS; clearly the index should have been 1 instead of 12. b) Conversions from geodetic to MGRS would fail for low southern latitudes (zone 0). Geotrans 3.7 has this problem fixed. The WorldWind conversion code was derived from NGA's Geotrans. Test case: Lat: -89.345400 deg, Lon: -48.930600 deg ==> MGRS: AZN 45208 47747 --- .../geom/coords/MGRSCoordConverter.java | 229 ++++++++---------- .../worldwind/geom/coords/UTM_MGRS_test.java | 88 +++++++ 2 files changed, 186 insertions(+), 131 deletions(-) create mode 100644 src/gov/nasa/worldwind/geom/coords/UTM_MGRS_test.java diff --git a/src/gov/nasa/worldwind/geom/coords/MGRSCoordConverter.java b/src/gov/nasa/worldwind/geom/coords/MGRSCoordConverter.java index 4762603fa8..a760244236 100644 --- a/src/gov/nasa/worldwind/geom/coords/MGRSCoordConverter.java +++ b/src/gov/nasa/worldwind/geom/coords/MGRSCoordConverter.java @@ -37,7 +37,7 @@ class MGRSCoordConverter private static final int MGRS_ZONE_ERROR = 0x0100; private static final int MGRS_HEMISPHERE_ERROR = 0x0200; private static final int MGRS_LAT_WARNING = 0x0400; - private static final int MGRS_NOZONE_WARNING = 0x0800; + // private static final int MGRS_NOZONE_WARNING = 0x0800; private static final int MGRS_UTM_ERROR = 0x1000; private static final int MGRS_UPS_ERROR = 0x2000; @@ -62,7 +62,7 @@ class MGRSCoordConverter // Ellipsoid parameters, default to WGS 84 private double MGRS_a = 6378137.0; // Semi-major axis of ellipsoid in meters private double MGRS_f = 1 / 298.257223563; // Flattening of ellipsoid - private double MGRS_recpf = 298.257223563; + // private double MGRS_recpf = 298.257223563; private String MGRS_Ellipsoid_Code = "WE"; private Globe globe; @@ -255,9 +255,11 @@ public long convertMGRSToGeodetic(String MGRSString) { latitude = 0; longitude = 0; - long error_code = checkZone(MGRSString); - if (error_code == MGRS_NO_ERROR) - { + MGRSComponents mgrs = breakMGRSString(MGRSString); + if (mgrs == null) return last_error; + + long error_code = MGRS_NO_ERROR; + if (mgrs.zone != 0) { UTMCoord UTM = convertMGRSToUTM(MGRSString); if (UTM != null) { @@ -267,9 +269,8 @@ public long convertMGRSToGeodetic(String MGRSString) else error_code = MGRS_UTM_ERROR; } - else if (error_code == MGRS_NOZONE_WARNING) + else { - // TODO: polar conversion UPSCoord UPS = convertMGRSToUPS(MGRSString); if (UPS != null) { @@ -314,10 +315,7 @@ private MGRSComponents breakMGRSString(String MGRSString) long northing = 0; int precision = 0; - while (i < MGRSString.length() && MGRSString.charAt(i) == ' ') - { - i++; /* skip any leading blanks */ - } + MGRSString = MGRSString.toUpperCase().replaceAll("\\s", ""); j = i; while (i < MGRSString.length() && Character.isDigit(MGRSString.charAt(i))) { @@ -325,6 +323,7 @@ private MGRSComponents breakMGRSString(String MGRSString) } num_digits = i - j; if (num_digits <= 2) + { if (num_digits > 0) { /* get zone */ @@ -333,7 +332,11 @@ private MGRSComponents breakMGRSString(String MGRSString) error_code |= MGRS_STRING_ERROR; } else - error_code |= MGRS_STRING_ERROR; + { + zone = 0; + } + } + j = i; while (i < MGRSString.length() && Character.isLetter(MGRSString.charAt(i))) @@ -394,40 +397,6 @@ private MGRSComponents breakMGRSString(String MGRSString) return null; } - /** - * The function Check_Zone receives an MGRS coordinate string. If a zone is given, MGRS_NO_ERROR is returned. - * Otherwise, MGRS_NOZONE_WARNING. is returned. - * - * @param MGRSString the MGRS coordinate string. - * - * @return the error code. - */ - private long checkZone(String MGRSString) - { - int i = 0; - int j = 0; - int num_digits = 0; - long error_code = MGRS_NO_ERROR; - - /* skip any leading blanks */ - while (i < MGRSString.length() && MGRSString.charAt(i) == ' ') - { - i++; - } - j = i; - while (i < MGRSString.length() && Character.isDigit(MGRSString.charAt(i))) - { - i++; - } - num_digits = i - j; - if (num_digits > 2) - error_code |= MGRS_STRING_ERROR; - else if (num_digits <= 0) - error_code |= MGRS_NOZONE_WARNING; - - return error_code; - } - /** * The function Get_Latitude_Band_Min_Northing receives a latitude band letter and uses the Latitude_Band_Table to * determine the minimum northing for that latitude band letter. Updates min_northing. @@ -503,13 +472,9 @@ else if ((letter >= LETTER_P) && (letter <= LETTER_X)) */ private UTMCoord convertMGRSToUTM(String MGRSString) { - double scaled_min_northing; double grid_easting; /* Easting for 100,000 meter grid square */ double grid_northing; /* Northing for 100,000 meter grid square */ - double temp_grid_northing = 0.0; - double fabs_grid_northing = 0.0; double latitude = 0.0; - double longitude = 0.0; double divisor = 1.0; long error_code = MGRS_NO_ERROR; @@ -546,8 +511,8 @@ private UTMCoord convertMGRSToUTM(String MGRSString) if (error_code == MGRS_NO_ERROR) { grid_northing = - (double) (MGRS.squareLetter2) * ONEHT; // smithjl commented out + false_northing; - grid_easting = (double) ((MGRS.squareLetter1) - ltr2_low_value + 1) * ONEHT; + (MGRS.squareLetter2) * ONEHT; // smithjl commented out + false_northing; + grid_easting = ((MGRS.squareLetter1) - ltr2_low_value + 1) * ONEHT; if ((ltr2_low_value == LETTER_J) && (MGRS.squareLetter1 > LETTER_O)) grid_easting = grid_easting - ONEHT; @@ -622,10 +587,6 @@ private UTMCoord convertMGRSToUTM(String MGRSString) */ public long convertGeodeticToMGRS(double latitude, double longitude, int precision) { - String Hemisphere = AVKey.NORTH; - double Easting = 0.0; - double Northing = 0.0; - MGRSString = ""; long error_code = MGRS_NO_ERROR; @@ -736,8 +697,8 @@ private long convertUPSToMGRS(String Hemisphere, Double Easting, Double Northing // false_easting = UPS_Constant_Table.get(index).false_easting; // false_northing = UPS_Constant_Table.get(index).false_northing; ltr2_low_value = (int) upsConstants[index][1]; - false_easting = (double) upsConstants[index][4]; - false_northing = (double) upsConstants[index][5]; + false_easting = upsConstants[index][4]; + false_northing = upsConstants[index][5]; } else // AVKey.SOUTH.equals(Hemisphere) { @@ -750,8 +711,8 @@ private long convertUPSToMGRS(String Hemisphere, Double Easting, Double Northing // false_easting = UPS_Constant_Table.get((int) letters[0]).false_easting; // false_northing = UPS_Constant_Table.get((int) letters[0]).false_northing; ltr2_low_value = (int) upsConstants[(int) letters[0]][1]; - false_easting = (double) upsConstants[(int) letters[0]][4]; - false_northing = (double) upsConstants[(int) letters[0]][5]; + false_easting = upsConstants[(int) letters[0]][4]; + false_northing = upsConstants[(int) letters[0]][5]; } grid_northing = Northing; @@ -766,7 +727,7 @@ private long convertUPSToMGRS(String Hemisphere, Double Easting, Double Northing grid_easting = Easting; grid_easting = grid_easting - false_easting; - letters[1] = (int) ltr2_low_value + ((int) (grid_easting / ONEHT)); + letters[1] = ltr2_low_value + ((int) (grid_easting / ONEHT)); if (Easting < TWOMIL) { @@ -861,7 +822,7 @@ private long convertUTMToMGRS(long Zone, double Latitude, double Easting, double * The function Get_Grid_Values sets the letter range used for the 2nd letter in the MGRS coordinate string, based * on the set number of the utm zone. It also sets the false northing using a value of A for the second letter of * the grid square, based on the grid pattern and set number of the utm zone. - *

+ *

* Key values that are set in this function include: ltr2_low_value, ltr2_high_value, and false_northing. * * @param zone Zone number @@ -884,18 +845,18 @@ private void getGridValues(long zone) if ((set_number == 1) || (set_number == 4)) { - ltr2_low_value = (long) LETTER_A; - ltr2_high_value = (long) LETTER_H; + ltr2_low_value = LETTER_A; + ltr2_high_value = LETTER_H; } else if ((set_number == 2) || (set_number == 5)) { - ltr2_low_value = (long) LETTER_J; - ltr2_high_value = (long) LETTER_R; + ltr2_low_value = LETTER_J; + ltr2_high_value = LETTER_R; } else if ((set_number == 3) || (set_number == 6)) { - ltr2_low_value = (long) LETTER_S; - ltr2_high_value = (long) LETTER_Z; + ltr2_low_value = LETTER_S; + ltr2_high_value = LETTER_Z; } /* False northing at A for second letter of grid square */ @@ -930,7 +891,7 @@ private long getLatitudeLetter(double latitude) double lat_deg = latitude * RAD_TO_DEG; if (lat_deg >= 72 && lat_deg < 84.5) - lastLetter = (long) LETTER_X; + lastLetter = LETTER_X; else if (lat_deg > -80.5 && lat_deg < 72) { temp = ((latitude + (80.0 * DEG_TO_RAD)) / (8.0 * DEG_TO_RAD)) + 1.0e-12; @@ -961,7 +922,7 @@ private double roundMGRS(double value) ival = (long) (ivalue); if ((fraction > 0.5) || ((fraction == 0.5) && (ival % 2 == 1))) ival++; - return (double) ival; + return ival; } /** @@ -1077,84 +1038,90 @@ private UPSCoord convertMGRSToUPS(String MGRS) MGRSComponents mgrs = breakMGRSString(MGRS); if (mgrs == null) + { error_code = this.last_error; - - if (mgrs != null && mgrs.zone > 0) - error_code |= MGRS_STRING_ERROR; - - if (error_code == MGRS_NO_ERROR) + } + else { - easting = mgrs.easting; - northing = mgrs.northing; - - if (mgrs.latitudeBand >= LETTER_Y) - { - hemisphere = AVKey.NORTH; - - index = mgrs.latitudeBand - 22; - ltr2_low_value = upsConstants[index][1]; //.ltr2_low_value; - ltr2_high_value = upsConstants[index][2]; //.ltr2_high_value; - ltr3_high_value = upsConstants[index][3]; //.ltr3_high_value; - false_easting = upsConstants[index][4]; //.false_easting; - false_northing = upsConstants[index][5]; //.false_northing; - } - else + if (mgrs.zone > 0) { - hemisphere = AVKey.SOUTH; - - ltr2_low_value = upsConstants[mgrs.latitudeBand][12]; //.ltr2_low_value; - ltr2_high_value = upsConstants[mgrs.latitudeBand][2]; //.ltr2_high_value; - ltr3_high_value = upsConstants[mgrs.latitudeBand][3]; //.ltr3_high_value; - false_easting = upsConstants[mgrs.latitudeBand][4]; //.false_easting; - false_northing = upsConstants[mgrs.latitudeBand][5]; //.false_northing; + error_code |= MGRS_STRING_ERROR; } - // Check that the second letter of the MGRS string is within - // the range of valid second letter values - // Also check that the third letter is valid - if ((mgrs.squareLetter1 < ltr2_low_value) || (mgrs.squareLetter1 > ltr2_high_value) || - ((mgrs.squareLetter1 == LETTER_D) || (mgrs.squareLetter1 == LETTER_E) || - (mgrs.squareLetter1 == LETTER_M) || (mgrs.squareLetter1 == LETTER_N) || - (mgrs.squareLetter1 == LETTER_V) || (mgrs.squareLetter1 == LETTER_W)) || - (mgrs.squareLetter2 > ltr3_high_value)) - error_code = MGRS_STRING_ERROR; - if (error_code == MGRS_NO_ERROR) { - grid_northing = (double) mgrs.squareLetter2 * ONEHT + false_northing; - if (mgrs.squareLetter2 > LETTER_I) - grid_northing = grid_northing - ONEHT; + easting = mgrs.easting; + northing = mgrs.northing; - if (mgrs.squareLetter2 > LETTER_O) - grid_northing = grid_northing - ONEHT; - - grid_easting = (double) ((mgrs.squareLetter1) - ltr2_low_value) * ONEHT + false_easting; - if (ltr2_low_value != LETTER_A) + if (mgrs.latitudeBand >= LETTER_Y) { - if (mgrs.squareLetter1 > LETTER_L) - grid_easting = grid_easting - 300000.0; - - if (mgrs.squareLetter1 > LETTER_U) - grid_easting = grid_easting - 200000.0; + hemisphere = AVKey.NORTH; + + index = mgrs.latitudeBand - 22; + ltr2_low_value = upsConstants[index][1]; //.ltr2_low_value; + ltr2_high_value = upsConstants[index][2]; //.ltr2_high_value; + ltr3_high_value = upsConstants[index][3]; //.ltr3_high_value; + false_easting = upsConstants[index][4]; //.false_easting; + false_northing = upsConstants[index][5]; //.false_northing; } else { - if (mgrs.squareLetter1 > LETTER_C) - grid_easting = grid_easting - 200000.0; - - if (mgrs.squareLetter1 > LETTER_I) - grid_easting = grid_easting - ONEHT; + hemisphere = AVKey.SOUTH; - if (mgrs.squareLetter1 > LETTER_L) - grid_easting = grid_easting - 300000.0; + ltr2_low_value = upsConstants[mgrs.latitudeBand][1]; //.ltr2_low_value; + ltr2_high_value = upsConstants[mgrs.latitudeBand][2]; //.ltr2_high_value; + ltr3_high_value = upsConstants[mgrs.latitudeBand][3]; //.ltr3_high_value; + false_easting = upsConstants[mgrs.latitudeBand][4]; //.false_easting; + false_northing = upsConstants[mgrs.latitudeBand][5]; //.false_northing; } - easting = grid_easting + easting; - northing = grid_northing + northing; - return UPSCoord.fromUPS(hemisphere, easting, northing, globe); + // Check that the second letter of the MGRS string is within + // the range of valid second letter values + // Also check that the third letter is valid + if ((mgrs.squareLetter1 < ltr2_low_value) || (mgrs.squareLetter1 > ltr2_high_value) || + ((mgrs.squareLetter1 == LETTER_D) || (mgrs.squareLetter1 == LETTER_E) || + (mgrs.squareLetter1 == LETTER_M) || (mgrs.squareLetter1 == LETTER_N) || + (mgrs.squareLetter1 == LETTER_V) || (mgrs.squareLetter1 == LETTER_W)) || + (mgrs.squareLetter2 > ltr3_high_value)) + error_code = MGRS_STRING_ERROR; + + if (error_code == MGRS_NO_ERROR) + { + grid_northing = mgrs.squareLetter2 * ONEHT + false_northing; + if (mgrs.squareLetter2 > LETTER_I) + grid_northing = grid_northing - ONEHT; + + if (mgrs.squareLetter2 > LETTER_O) + grid_northing = grid_northing - ONEHT; + + grid_easting = ((mgrs.squareLetter1) - ltr2_low_value) * ONEHT + false_easting; + if (ltr2_low_value != LETTER_A) + { + if (mgrs.squareLetter1 > LETTER_L) + grid_easting = grid_easting - 300000.0; + + if (mgrs.squareLetter1 > LETTER_U) + grid_easting = grid_easting - 200000.0; + } + else + { + if (mgrs.squareLetter1 > LETTER_C) + grid_easting = grid_easting - 200000.0; + + if (mgrs.squareLetter1 > LETTER_I) + grid_easting = grid_easting - ONEHT; + + if (mgrs.squareLetter1 > LETTER_L) + grid_easting = grid_easting - 300000.0; + } + + easting = grid_easting + easting; + northing = grid_northing + northing; + return UPSCoord.fromUPS(hemisphere, easting, northing, globe); + } } } return null; } -} +} \ No newline at end of file diff --git a/src/gov/nasa/worldwind/geom/coords/UTM_MGRS_test.java b/src/gov/nasa/worldwind/geom/coords/UTM_MGRS_test.java new file mode 100644 index 0000000000..49ef3edab5 --- /dev/null +++ b/src/gov/nasa/worldwind/geom/coords/UTM_MGRS_test.java @@ -0,0 +1,88 @@ +package gov.nasa.worldwind.geom.coords; + +import org.junit.Test; + +import gov.nasa.worldwind.geom.LatLon; + +public class UTM_MGRS_test { + + private LatLon[] input0 = { + LatLon.fromDegrees(-74.37916, 155.02235), + LatLon.fromDegrees(0, 0), + LatLon.fromDegrees(0.1300, -0.2324), + LatLon.fromDegrees(-45.6456, 23.3545), + LatLon.fromDegrees(-12.7650, -33.8765), + LatLon.fromDegrees(23.4578, -135.4545), + LatLon.fromDegrees(77.3450,156.9876), + }; + + private LatLon[] MGRS_only = { + LatLon.fromDegrees(-89.3454, -48.9306), + LatLon.fromDegrees(-80.5434, -170.6540), + }; + + private LatLon[] noInverse = { + LatLon.fromDegrees(90.0000, 177.0000), + LatLon.fromDegrees(-90.0000, -177.0000), + LatLon.fromDegrees(90.0000, 3.0000), + }; + private String[] noInverseToMgrs = { + "ZAH 00000 00000", "BAN 00000 00000", "ZAH 00000 00000" + }; + + private boolean isClose(double x, double y, double limit) { + return (Math.abs(x - y) < limit); + } + + private boolean isClose(LatLon a, LatLon b) { + double epsilonRad = Math.toRadians(9.0e-6); + return isClose(a, b, epsilonRad); + } + + private boolean isClose(LatLon a, LatLon b, double limit) { + return isClose(a.latitude.radians, b.latitude.radians, limit) + && isClose(a.longitude.radians, b.longitude.radians, limit); + } + + @Test + public void test() { + for (LatLon p : input0) { + + UTMCoord utm = UTMCoord.fromLatLon(p.latitude, p.longitude); + MGRSCoord mgrs = MGRSCoord.fromLatLon(p.latitude, p.longitude); + UTMCoord coord1 = UTMCoord.fromUTM(utm.getZone(), utm.getHemisphere(), utm.getEasting(), utm.getNorthing()); + System.out.println(p + " ==> " + " UTM: " + utm.toString() + ", MGRS: " + mgrs.toString()); + + + LatLon p1 = LatLon.fromRadians(coord1.getLatitude().radians, coord1.getLongitude().radians); + assert(isClose(p, p1)); + + MGRSCoord coord2 = MGRSCoord.fromString(mgrs.toString(), null); + LatLon p2 = LatLon.fromRadians(coord2.getLatitude().radians, coord2.getLongitude().radians); + assert(isClose(p.getLatitude().radians, p2.getLatitude().radians, 0.000020)); + assert(isClose(p.getLongitude().radians, p2.getLongitude().radians, 0.000020)); + } + + for (LatLon p : MGRS_only) { + MGRSCoord mgrs = MGRSCoord.fromLatLon(p.latitude, p.longitude); + + System.out.println(p + " ==> " + "MGRS: " + mgrs.toString()); + + MGRSCoord coord2 = MGRSCoord.fromString(mgrs.toString(), null); + LatLon p2 = LatLon.fromRadians(coord2.getLatitude().radians, coord2.getLongitude().radians); + assert(isClose(p, p2, 0.000020)); + } + + for (int i=0; i < noInverse.length; i++) { + LatLon p = noInverse[i]; + MGRSCoord mgrs = MGRSCoord.fromLatLon(p.latitude, p.longitude); + + System.out.print(p + " ==> " + "MGRS: " + mgrs.toString()); + + MGRSCoord coord2 = MGRSCoord.fromString(mgrs.toString(), null); + LatLon p2 = LatLon.fromRadians(coord2.getLatitude().radians, coord2.getLongitude().radians); + System.out.println(" ==> " + p2); + assert(mgrs.toString().trim().equals(noInverseToMgrs[i])); + } + } +} From c1535de5740bc49f6d1f460b58792703ef8050a3 Mon Sep 17 00:00:00 2001 From: Wiehann Matthysen Date: Wed, 14 Aug 2019 10:05:07 +0200 Subject: [PATCH 2/6] Small fixes to MGRSCoordConverter. Made some formatting fixes as well as fixing a spelling mistake in one of the comments. --- .../nasa/worldwind/geom/coords/MGRSCoordConverter.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/gov/nasa/worldwind/geom/coords/MGRSCoordConverter.java b/src/gov/nasa/worldwind/geom/coords/MGRSCoordConverter.java index a760244236..76661b64b8 100644 --- a/src/gov/nasa/worldwind/geom/coords/MGRSCoordConverter.java +++ b/src/gov/nasa/worldwind/geom/coords/MGRSCoordConverter.java @@ -256,10 +256,14 @@ public long convertMGRSToGeodetic(String MGRSString) latitude = 0; longitude = 0; MGRSComponents mgrs = breakMGRSString(MGRSString); - if (mgrs == null) return last_error; + if (mgrs == null) + { + return last_error; + } long error_code = MGRS_NO_ERROR; - if (mgrs.zone != 0) { + if (mgrs.zone != 0) + { UTMCoord UTM = convertMGRSToUTM(MGRSString); if (UTM != null) { @@ -1015,7 +1019,7 @@ public long getError() /** * The function Convert_MGRS_To_UPS converts an MGRS coordinate string to UPS (hemisphere, easting, and northing) * coordinates, according to the current ellipsoid parameters. If any errors occur, the error code(s) are returned - * by the function, otherwide UPS_NO_ERROR is returned. + * by the function, otherwise UPS_NO_ERROR is returned. * * @param MGRS the MGRS coordinate string. * From a74b3e045f72b8f155705269c160edb663cf0fe5 Mon Sep 17 00:00:00 2001 From: Wiehann Matthysen Date: Wed, 14 Aug 2019 10:07:19 +0200 Subject: [PATCH 3/6] Moved UTM_MGRS_test to correct location. Moved the UTM_MGRS_test class to the correct location. It should be in the test folder so that it gets executed as part of the unit tests. --- .../gov/nasa/worldwind/geom/coords/UTM_MGRS_test.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) rename {src => test}/gov/nasa/worldwind/geom/coords/UTM_MGRS_test.java (97%) diff --git a/src/gov/nasa/worldwind/geom/coords/UTM_MGRS_test.java b/test/gov/nasa/worldwind/geom/coords/UTM_MGRS_test.java similarity index 97% rename from src/gov/nasa/worldwind/geom/coords/UTM_MGRS_test.java rename to test/gov/nasa/worldwind/geom/coords/UTM_MGRS_test.java index 49ef3edab5..74421502b7 100644 --- a/src/gov/nasa/worldwind/geom/coords/UTM_MGRS_test.java +++ b/test/gov/nasa/worldwind/geom/coords/UTM_MGRS_test.java @@ -1,8 +1,7 @@ package gov.nasa.worldwind.geom.coords; -import org.junit.Test; - import gov.nasa.worldwind.geom.LatLon; +import org.junit.Test; public class UTM_MGRS_test { From 44f34a0648a6e84b3bc8ffb41af8737e70c86dba Mon Sep 17 00:00:00 2001 From: Wiehann Matthysen Date: Wed, 14 Aug 2019 11:32:01 +0200 Subject: [PATCH 4/6] Renamed UTM_MGRS_test to CoordTest. --- .../geom/coords/{UTM_MGRS_test.java => CoordTest.java} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename test/gov/nasa/worldwind/geom/coords/{UTM_MGRS_test.java => CoordTest.java} (96%) diff --git a/test/gov/nasa/worldwind/geom/coords/UTM_MGRS_test.java b/test/gov/nasa/worldwind/geom/coords/CoordTest.java similarity index 96% rename from test/gov/nasa/worldwind/geom/coords/UTM_MGRS_test.java rename to test/gov/nasa/worldwind/geom/coords/CoordTest.java index 74421502b7..0379754f33 100644 --- a/test/gov/nasa/worldwind/geom/coords/UTM_MGRS_test.java +++ b/test/gov/nasa/worldwind/geom/coords/CoordTest.java @@ -3,7 +3,7 @@ import gov.nasa.worldwind.geom.LatLon; import org.junit.Test; -public class UTM_MGRS_test { +public class CoordTest { private LatLon[] input0 = { LatLon.fromDegrees(-74.37916, 155.02235), From 295f7a9a0b81a016dfaba4efa68d661ac5845722 Mon Sep 17 00:00:00 2001 From: Wiehann Matthysen Date: Wed, 14 Aug 2019 11:33:24 +0200 Subject: [PATCH 5/6] Fixed up CoordTest. - Split up some of the methods into smaller self-contained methods. - Renamed some of the variables for clarity. - Changed the formatting by replacing tabs with spaces. Made some other formatting changes so that the code fits in with rest of code-base. - Added license-header at the top. --- .../nasa/worldwind/geom/coords/CoordTest.java | 175 ++++++++++-------- 1 file changed, 98 insertions(+), 77 deletions(-) diff --git a/test/gov/nasa/worldwind/geom/coords/CoordTest.java b/test/gov/nasa/worldwind/geom/coords/CoordTest.java index 0379754f33..2310ab2e53 100644 --- a/test/gov/nasa/worldwind/geom/coords/CoordTest.java +++ b/test/gov/nasa/worldwind/geom/coords/CoordTest.java @@ -1,87 +1,108 @@ +/* + * Copyright (C) 2012 United States Government as represented by the Administrator of the + * National Aeronautics and Space Administration. + * All Rights Reserved. + */ package gov.nasa.worldwind.geom.coords; import gov.nasa.worldwind.geom.LatLon; import org.junit.Test; -public class CoordTest { +import static org.junit.Assert.*; - private LatLon[] input0 = { - LatLon.fromDegrees(-74.37916, 155.02235), - LatLon.fromDegrees(0, 0), - LatLon.fromDegrees(0.1300, -0.2324), - LatLon.fromDegrees(-45.6456, 23.3545), - LatLon.fromDegrees(-12.7650, -33.8765), - LatLon.fromDegrees(23.4578, -135.4545), - LatLon.fromDegrees(77.3450,156.9876), - }; +public class CoordTest +{ + private static boolean isClose(double x, double y, double limit) + { + return (Math.abs(x - y) < limit); + } - private LatLon[] MGRS_only = { - LatLon.fromDegrees(-89.3454, -48.9306), - LatLon.fromDegrees(-80.5434, -170.6540), - }; - - private LatLon[] noInverse = { - LatLon.fromDegrees(90.0000, 177.0000), - LatLon.fromDegrees(-90.0000, -177.0000), - LatLon.fromDegrees(90.0000, 3.0000), - }; - private String[] noInverseToMgrs = { - "ZAH 00000 00000", "BAN 00000 00000", "ZAH 00000 00000" - }; - - private boolean isClose(double x, double y, double limit) { - return (Math.abs(x - y) < limit); - } - - private boolean isClose(LatLon a, LatLon b) { - double epsilonRad = Math.toRadians(9.0e-6); - return isClose(a, b, epsilonRad); - } - - private boolean isClose(LatLon a, LatLon b, double limit) { - return isClose(a.latitude.radians, b.latitude.radians, limit) - && isClose(a.longitude.radians, b.longitude.radians, limit); - } + private static boolean isClose(LatLon a, LatLon b) + { + double epsilonRad = Math.toRadians(9.0e-6); + return isClose(a, b, epsilonRad); + } - @Test - public void test() { - for (LatLon p : input0) { + private static boolean isClose(LatLon a, LatLon b, double limit) + { + return isClose(a.latitude.radians, b.latitude.radians, limit) + && isClose(a.longitude.radians, b.longitude.radians, limit); + } + + private static final LatLon[] TEST_POSITIONS = + { + LatLon.fromDegrees(-74.37916, 155.02235), + LatLon.fromDegrees(0, 0), + LatLon.fromDegrees(0.1300, -0.2324), + LatLon.fromDegrees(-45.6456, 23.3545), + LatLon.fromDegrees(-12.7650, -33.8765), + LatLon.fromDegrees(23.4578, -135.4545), + LatLon.fromDegrees(77.3450, 156.9876) + }; + + @Test + public void utmConstructionTest() + { + for (LatLon input : TEST_POSITIONS) + { + UTMCoord fromLatLon = UTMCoord.fromLatLon(input.latitude, input.longitude); + UTMCoord utmCoord = UTMCoord.fromUTM(fromLatLon.getZone(), fromLatLon.getHemisphere(), fromLatLon.getEasting(), fromLatLon.getNorthing()); + LatLon position = LatLon.fromRadians(utmCoord.getLatitude().radians, utmCoord.getLongitude().radians); + assertTrue(isClose(input, position)); + } + } - UTMCoord utm = UTMCoord.fromLatLon(p.latitude, p.longitude); - MGRSCoord mgrs = MGRSCoord.fromLatLon(p.latitude, p.longitude); - UTMCoord coord1 = UTMCoord.fromUTM(utm.getZone(), utm.getHemisphere(), utm.getEasting(), utm.getNorthing()); - System.out.println(p + " ==> " + " UTM: " + utm.toString() + ", MGRS: " + mgrs.toString()); - - - LatLon p1 = LatLon.fromRadians(coord1.getLatitude().radians, coord1.getLongitude().radians); - assert(isClose(p, p1)); - - MGRSCoord coord2 = MGRSCoord.fromString(mgrs.toString(), null); - LatLon p2 = LatLon.fromRadians(coord2.getLatitude().radians, coord2.getLongitude().radians); - assert(isClose(p.getLatitude().radians, p2.getLatitude().radians, 0.000020)); - assert(isClose(p.getLongitude().radians, p2.getLongitude().radians, 0.000020)); - } - - for (LatLon p : MGRS_only) { - MGRSCoord mgrs = MGRSCoord.fromLatLon(p.latitude, p.longitude); - - System.out.println(p + " ==> " + "MGRS: " + mgrs.toString()); - - MGRSCoord coord2 = MGRSCoord.fromString(mgrs.toString(), null); - LatLon p2 = LatLon.fromRadians(coord2.getLatitude().radians, coord2.getLongitude().radians); - assert(isClose(p, p2, 0.000020)); - } - - for (int i=0; i < noInverse.length; i++) { - LatLon p = noInverse[i]; - MGRSCoord mgrs = MGRSCoord.fromLatLon(p.latitude, p.longitude); - - System.out.print(p + " ==> " + "MGRS: " + mgrs.toString()); - - MGRSCoord coord2 = MGRSCoord.fromString(mgrs.toString(), null); - LatLon p2 = LatLon.fromRadians(coord2.getLatitude().radians, coord2.getLongitude().radians); - System.out.println(" ==> " + p2); - assert(mgrs.toString().trim().equals(noInverseToMgrs[i])); - } - } + @Test + public void mgrsConstructionTest() + { + for (LatLon input : TEST_POSITIONS) + { + MGRSCoord fromLatLon = MGRSCoord.fromLatLon(input.latitude, input.longitude); + MGRSCoord fromString = MGRSCoord.fromString(fromLatLon.toString(), null); + LatLon position = LatLon.fromRadians(fromString.getLatitude().radians, fromString.getLongitude().radians); + assertTrue(isClose(input, position, 000020)); + } + } + + private static final LatLon[] MGRS_ONLY_POSITIONS = + { + LatLon.fromDegrees(-89.3454, -48.9306), + LatLon.fromDegrees(-80.5434, -170.6540), + }; + + @Test + public void mgrsOnlyConstructionTest() + { + for (LatLon input : MGRS_ONLY_POSITIONS) + { + MGRSCoord fromLatLon = MGRSCoord.fromLatLon(input.latitude, input.longitude); + MGRSCoord fromString = MGRSCoord.fromString(fromLatLon.toString(), null); + LatLon position = LatLon.fromRadians(fromString.getLatitude().radians, fromString.getLongitude().radians); + assertTrue(isClose(input, position, 000020)); + } + } + + private static final LatLon[] NO_INVERSE_POSITIONS = + { + LatLon.fromDegrees(90.0000, 177.0000), + LatLon.fromDegrees(-90.0000, -177.0000), + LatLon.fromDegrees(90.0000, 3.0000) + }; + + private static final String[] NO_INVERSE_TO_MGRS = + { + "ZAH 00000 00000", "BAN 00000 00000", "ZAH 00000 00000" + }; + + @Test + public void noInverseToMGRSTest() + { + for (int i = 0; i < NO_INVERSE_POSITIONS.length; i++) + { + LatLon input = NO_INVERSE_POSITIONS[i]; + MGRSCoord fromLatLon = MGRSCoord.fromLatLon(input.latitude, input.longitude); + String mgrsString = fromLatLon.toString().trim(); + assertEquals(mgrsString, NO_INVERSE_TO_MGRS[i]); + } + } } From 45a37ff9240edffa008b8cab02f5c31e9cc79bc4 Mon Sep 17 00:00:00 2001 From: Glenn Burkhardt Date: Wed, 14 Aug 2019 09:00:01 -0400 Subject: [PATCH 6/6] Update copyright date --- test/gov/nasa/worldwind/geom/coords/CoordTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/gov/nasa/worldwind/geom/coords/CoordTest.java b/test/gov/nasa/worldwind/geom/coords/CoordTest.java index 2310ab2e53..904f8970fb 100644 --- a/test/gov/nasa/worldwind/geom/coords/CoordTest.java +++ b/test/gov/nasa/worldwind/geom/coords/CoordTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 United States Government as represented by the Administrator of the + * Copyright (C) 2019 United States Government as represented by the Administrator of the * National Aeronautics and Space Administration. * All Rights Reserved. */