package org.opensextant.regex.geo; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.regex.MatchResult; import org.opensextant.geodesy.Geodetic2DPoint; import org.opensextant.geodesy.MGRS; import org.opensextant.geodesy.UTM; import org.opensextant.placedata.Geocoord; import org.opensextant.regex.Normalizer; import org.opensextant.regex.RegexAnnotation; import org.opensextant.regex.RegexRule; import org.opensextant.regex.geo.OrdinateParser.AXIS; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class GeoNormalizer implements Normalizer { /** Log object. */ private static final Logger LOGGER = LoggerFactory.getLogger(GeoNormalizer.class); /** There are 5 geocoord families. */ private static final String DD_FAMILY = "DD"; private static final String DM_FAMILY = "DM"; private static final String DMS_FAMILY = "DMS"; private static final String MGRS_FAMILY = "MGRS"; private static final String UTM_FAMILY = "UTM"; @Override public void normalize(RegexAnnotation anno, RegexRule r, MatchResult matchResult) { Map<String, Object> annoFeatures = anno.getFeatures(); Map<String, String> elementsFound = new HashMap<String, String>(); int numGroups = matchResult.groupCount(); for (int i = 0; i < numGroups + 1; i++) { String elemenValue = matchResult.group(i); String elemName = r.getElementMap().get(i); elementsFound.put(elemName, elemenValue); if (LOGGER.isDebugEnabled()) { annoFeatures.put(elemName, elemenValue); } } // the rule family tells us the set of elements to expect String family = r.getRuleFamily(); String ruleName = r.getRuleName(); if (DD_FAMILY.equals(family)) { Ordinate lat = null; Ordinate lon = null; try { lat = OrdinateParser.parse(elementsFound, AXIS.LATITUDE, OrdinateParser.ORDINATETYPE.DD); lon = OrdinateParser.parse(elementsFound, AXIS.LONGITUDE, OrdinateParser.ORDINATETYPE.DD); } catch (Exception e) { LOGGER.debug("Couldn't normalize " + anno + " Ordinate Parser exception:", e); } if (lat != null && lon != null) { Geocoord geo = new Geocoord(lat.getOrdinateValue(), lon.getOrdinateValue()); annoFeatures.put("geo", geo); annoFeatures.put("geoFamily", family); annoFeatures.put("geoPattern", ruleName); } else { anno.setValid(false); LOGGER.debug("Couldn't normalize " + anno); } } if (DM_FAMILY.equals(family) || DMS_FAMILY.equals(family)) { Ordinate lat = null; Ordinate lon = null; try { lat = OrdinateParser.parse(elementsFound, AXIS.LATITUDE, OrdinateParser.ORDINATETYPE.DMS); lon = OrdinateParser.parse(elementsFound, AXIS.LONGITUDE, OrdinateParser.ORDINATETYPE.DMS); } catch (Exception e) { LOGGER.debug("Couldn't normalize " + anno + " Ordinate Parser exception:", e); } if (lat != null && lon != null) { Geocoord geo = new Geocoord(lat.getOrdinateValue(), lon.getOrdinateValue()); annoFeatures.put("geo", geo); annoFeatures.put("geoFamily", family); annoFeatures.put("geoPattern", ruleName); } else { anno.setValid(false); LOGGER.debug("Couldn't normalize " + anno); } } if (MGRS_FAMILY.equals(family)) { List<MGRS> mgrsCandidates = null; try { mgrsCandidates = MGRSParser.parseMGRS(elementsFound); } catch (Exception e) { LOGGER.debug("Couldn't normalize " + anno + " MGRS parser exception:", e); } if (mgrsCandidates != null && !mgrsCandidates.isEmpty()) { MGRS mgrs = mgrsCandidates.get(0); Geodetic2DPoint pt = mgrs.toGeodetic2DPoint(); Geocoord geo = new Geocoord(pt.getLatitudeAsDegrees(), pt.getLongitudeAsDegrees()); annoFeatures.put("geo", geo); annoFeatures.put("geoFamily", family); annoFeatures.put("geoPattern", ruleName); List<Geocoord> altCoords = new ArrayList<Geocoord>(); if (mgrsCandidates.size() > 1) { for (MGRS m : mgrsCandidates) { Geodetic2DPoint pt2 = m.toGeodetic2DPoint(); Geocoord geo2 = new Geocoord(pt2.getLatitudeAsDegrees(), pt2.getLongitudeAsDegrees()); altCoords.add(geo2); } annoFeatures.put("geoAlternatives", altCoords); } } else { anno.setValid(false); LOGGER.debug("Couldn't normalize " + anno); } } if (UTM_FAMILY.equals(family)) { UTM utm = null; try { utm = UTMParser.parseUTM(elementsFound); } catch (Exception e) { LOGGER.debug("Couldn't normalize " + anno + " UTM parser exception:", e); } if (utm != null) { Geodetic2DPoint pt = utm.getGeodetic(); Geocoord geo = new Geocoord(pt.getLatitudeAsDegrees(), pt.getLongitudeAsDegrees()); annoFeatures.put("geo", geo); annoFeatures.put("geoFamily", family); annoFeatures.put("geoPattern", ruleName); } else { anno.setValid(false); LOGGER.debug("Couldn't normalize " + anno); } } return; } }