/** * Copyright (c) Codice Foundation * <p/> * This is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser * General Public License as published by the Free Software Foundation, either version 3 of the * License, or any later version. * <p/> * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. A copy of the GNU Lesser General Public License * is distributed along with this program and can be found at * <http://www.gnu.org/licenses/lgpl.html>. **/ package org.codice.ddf.spatial.geocoder.geonames; import java.text.ParseException; import java.util.List; import java.util.Locale; import java.util.MissingResourceException; import java.util.Optional; import org.codice.ddf.spatial.geocoder.GeoCoder; import org.codice.ddf.spatial.geocoder.GeoResult; import org.codice.ddf.spatial.geocoder.GeoResultCreator; import org.codice.ddf.spatial.geocoding.GeoEntry; import org.codice.ddf.spatial.geocoding.GeoEntryQueryException; import org.codice.ddf.spatial.geocoding.GeoEntryQueryable; import org.codice.ddf.spatial.geocoding.context.NearbyLocation; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class GeoNamesLocalIndex implements GeoCoder { private static final int SEARCH_RADIUS = 50; private static final int SEARCH_RESULT_LIMIT = 1; private static final Logger LOGGER = LoggerFactory.getLogger(GeoNamesLocalIndex.class); private GeoEntryQueryable geoEntryQueryable; public void setGeoEntryQueryable(final GeoEntryQueryable geoEntryQueryable) { this.geoEntryQueryable = geoEntryQueryable; } @Override public GeoResult getLocation(final String location) { try { final List<GeoEntry> topResults = geoEntryQueryable.query(location, 1); if (topResults.size() > 0) { final GeoEntry topResult = topResults.get(0); final String name = topResult.getName(); final double latitude = topResult.getLatitude(); final double longitude = topResult.getLongitude(); final String featureCode = topResult.getFeatureCode(); final long population = topResult.getPopulation(); return GeoResultCreator.createGeoResult(name, latitude, longitude, featureCode, population); } } catch (GeoEntryQueryException e) { LOGGER.debug("Error querying the local GeoNames index", e); } return null; } public NearbyLocation getNearbyCity(String location) throws GeoEntryQueryException { try { List<NearbyLocation> locations = geoEntryQueryable.getNearestCities(location, SEARCH_RADIUS, SEARCH_RESULT_LIMIT); if (locations.size() > 0) { return locations.get(0); } } catch (ParseException parseException) { LOGGER.debug("Error parsing the supplied wkt: {}", location, parseException); } return null; } @Override public Optional<String> getCountryCode(String locationWKT, int radius) { try { Optional<String> alpha2CountryCode = geoEntryQueryable.getCountryCode(locationWKT, radius); if (alpha2CountryCode.isPresent()) { try { String alpha3CountryCode = new Locale(Locale.ENGLISH.getLanguage(), alpha2CountryCode.get()).getISO3Country(); return Optional.of(alpha3CountryCode); } catch (MissingResourceException e) { LOGGER.debug( "Failed to convert country code {} to alpha-3 format. Returning empty value", alpha2CountryCode.get(), e); } } } catch (GeoEntryQueryException e) { LOGGER.debug("Error querying the local GeoNames index", e); } catch (ParseException e) { LOGGER.debug("Error parsing WKT: {} ", locationWKT, e); } return Optional.empty(); } }