/** This method performs format conversions with string constructors in degrees and dms */ public void testRandomEquals() { for (int i = 0; i < 1000; i++) { Geodetic3DPoint a1 = randomGeoPoint(r); Geodetic3DPoint a2 = new Geodetic3DPoint(a1.getLongitude(), a1.getLatitude(), a1.getElevation()); // note by making equals() work in round off errors (such as in this case) using // Angle.equals() vs phi1=phi2 && lamb1==lamb2 // but break contract in hashCode such that a.equals(b) -> true but hashCode(a) may not equal // hashCode(b) assertEquals(a1, a2); assertEquals(a1.hashCode(), a2.hashCode()); // for symmetric tests to work elevation must be non-zero final double elevation = a1.getElevation(); if (elevation == 0.0 || Math.abs(elevation) < 1e-8) a1.setElevation(1234.5); // test symmetric equals tests a.equals(b) -> b.equals(a) Geodetic2DPoint pt2 = new Geodetic2DPoint(a1.getLongitude(), a1.getLatitude()); assertFalse(pt2.equals(a1)); assertFalse(a1.equals(pt2)); a1.setElevation(0); assertEquals(pt2, a1); // pt2.equals(al) -> a1.equals(pt2) assertEquals(a1, pt2); } }
/** Test 2d vs 3d points with 3d elavations at/close to 0 */ public void testMismatchedEquals() { Geodetic2DPoint p1 = makePoint(-81.9916466079043, 29.9420387052815, 5000.1); Geodetic2DPoint p2 = makePoint(-81.9916466079043, 29.9420387052815, 0.0); if (p1.equals(p2)) fail("different elevation but equals() == true"); if (p2.equals(p1)) fail("different elevation but equals() == true"); Geodetic2DPoint p3 = makePoint(-81.9916466079043, 29.9420387052815); assertEquals("2d with elev=0 and 3d point same lat/lon", p2, p3); assertEquals("2d with elev=0 and 3d point same lat/lon", p3, p2); Geodetic2DPoint p4 = makePoint(-81.9916466079043, 29.9420387052815, 1e-6); // assertEquals(p3, new Geodetic2DPoint(p4.getLongitude(), p4.getLatitude())); assertEquals("3d with elev=1e-4 and 3d point same lat/lon", p2, p4); assertEquals("3d with elev=1e-4 and 3d point same lat/lon", p4, p2); assertEquals("3d with elev=1e-4 and 3d point same lat/lon", p3, p4); }
/** * The match object is normalized, setting the coord_text and other data from parsing "text" and * knowing which pattern family was matched. * * @param m * @param groups * @return void * @throws XCoordException */ public void normalize_coordinate(GeocoordMatch m, Map<String, String> groups) throws XCoordException { // Extract m.regex_groups, and ordered list of group names // align with matcher.group(N) // value = matcher.group(N) // name = m.regex_groups.itemAt(N) // if (m.cce_family_id == XConstants.DD_PATTERN) { // get lat text // lon text -- remove whitespace from both // coord_text = lat + ' ' + lon // set lat, lon // // decDegLat, decDegLon, degSym, hemiLat, hemiLon // DMSOrdinate ddlat = new DMSOrdinate(groups, DMLAT, m.getText()); DMSOrdinate ddlon = new DMSOrdinate(groups, DMLON, m.getText()); // m.setLatitude(groups.get("decDegLat"), lat_hemi); // m.setLongitude(groups.get("decDegLon"), lon_hemi); // Yield a cooridnate-only version of text; "+42.4440 -102.3333" // preserving the innate precision given in the original text. // m.lat_text = ddlat.text; m.lon_text = ddlon.text; m.setCoordinate(ddlat, ddlon); /** DD filters enabled. Disable: XCoord.RUNTIME_FLAGS XOR XConstants.DD_FILTERS_ON */ if ((XCoord.RUNTIME_FLAGS & XConstants.DD_FILTERS_ON) > 0) { /** * With FILTERS ON if lat/lon have no ALPHA hemisphere -- ENSW and if lat/lon text for match * has no COORD symbology then this is likely not a DD coordinate -- filter out. */ if (!ddlon.hemisphere.isAlpha() && !ddlat.hemisphere.isAlpha()) { if (!ddlat.hasSymbols()) { m.filter_state = XConstants.FILTERED_OUT; } } } m.coord_text = m.lat_text + " " + m.lon_text; } else if (m.cce_family_id == XConstants.DM_PATTERN) { // get lat text // lon text -- remove whitespace from both // coord_text = lat + ' ' + lon // set lat, lon // DMSOrdinate dmlat = new DMSOrdinate(groups, DMLAT, m.getText()); DMSOrdinate dmlon = new DMSOrdinate(groups, DMLON, m.getText()); m.lat_text = dmlat.text; m.lon_text = dmlon.text; m.setCoordinate(dmlat, dmlon); m.coord_text = m.lat_text + " " + m.lon_text; } else if (m.cce_family_id == XConstants.DMS_PATTERN) { // remove whitespace // set lat, lon // DMSOrdinate dmlat = new DMSOrdinate(groups, DMLAT, m.getText()); DMSOrdinate dmlon = new DMSOrdinate(groups, DMLON, m.getText()); m.lat_text = dmlat.text; m.lon_text = dmlon.text; m.setCoordinate(dmlat, dmlon); m.coord_text = m.lat_text + " " + m.lon_text; } else if (m.cce_family_id == XConstants.MGRS_PATTERN) { // Capture the normalized coord text just to aid in reporting in error situations // m.coord_text = TextUtils.delete_whitespace(m.getText()); // TODO: make use of multiple answers. try { MGRS[] mgrs_candidates = MGRSParser.parseMGRS(m.getText(), m.coord_text, groups); // Hopefully 1 candidate, but maybe 2 are found. // 1 is normal. 2 arise from having odd-digit offsets in NorthingEasting // if (mgrs_candidates != null) { MGRS mgrs = mgrs_candidates[0]; m.coord_text = mgrs.toString(); Geodetic2DPoint pt = mgrs.toGeodetic2DPoint(); m.latitude = pt.getLatitudeAsDegrees(); m.longitude = pt.getLongitudeAsDegrees(); if (mgrs_candidates.length == 2) { mgrs = mgrs_candidates[1]; GeocoordMatch m2 = new GeocoordMatch(); m2.copy(m); m2.coord_text = mgrs.toString(); pt = mgrs.toGeodetic2DPoint(); m2.latitude = pt.getLatitudeAsDegrees(); m2.longitude = pt.getLongitudeAsDegrees(); m.addOtherInterpretation(m2); } } } catch (java.lang.IllegalArgumentException parseErr) { log.debug( "Failed to parse MGRS pattern with text=" + m.getText() + " COORD?:" + m.coord_text, parseErr); // No normalization done. } catch (Exception err) { throw new XCoordException("Failed to parse MGRS", err); } } else if (m.cce_family_id == XConstants.UTM_PATTERN) { m.coord_text = utility.delete_whitespace(m.getText()); try { UTM utm = UTMParser.parseUTM(m.coord_text, groups); if (utm != null) { Geodetic2DPoint pt = utm.getGeodetic(); m.latitude = pt.getLatitudeAsDegrees(); m.longitude = pt.getLongitudeAsDegrees(); m.coord_text = utm.toString(); } } catch (java.lang.IllegalArgumentException parseErr) { log.debug( "Failed to parse UTM pattern with text=" + m.getText() + " COORD?:" + m.coord_text, parseErr); // No normalization done. } catch (Exception err) { throw new XCoordException("Failed to parse UTM pattern", err); } } // return m.coord_text; }