/* This program 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 (at your option) any later version. 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.opentripplanner.geocoder.nominatim; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.URI; import java.net.URL; import java.net.URLConnection; import java.util.ArrayList; import java.util.List; import javax.ws.rs.core.UriBuilder; import org.opentripplanner.geocoder.Geocoder; import org.opentripplanner.geocoder.GeocoderResult; import org.opentripplanner.geocoder.GeocoderResults; import com.vividsolutions.jts.geom.Envelope; public class NominatimGeocoder implements Geocoder { private String nominatimUrl; private Integer resultLimit; private String viewBox; private String emailAddress; private NominatimJsonDeserializer nominatimJsonDeserializer; public NominatimGeocoder() { nominatimJsonDeserializer = new NominatimJsonDeserializer(); } public String getNominatimUrl() { return nominatimUrl; } public void setNominatimUrl(String nominatimUrl) { this.nominatimUrl = nominatimUrl; } public Integer getResultLimit() { return resultLimit; } public void setResultLimit(Integer resultLimit) { this.resultLimit = resultLimit; } public String getViewBox() { return viewBox; } public void setViewBox(String viewBox) { this.viewBox = viewBox; } public String getEmailAddress() { return emailAddress; } public void setEmailAddress(String emailAddress) { this.emailAddress = emailAddress; } @Override public GeocoderResults geocode(String address, Envelope bbox) { String content = null; try { // make json request URL nominatimGeocoderUrl = getNominatimGeocoderUrl(address, bbox); URLConnection conn = nominatimGeocoderUrl.openConnection(); BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream(), "utf-8")); StringBuilder sb = new StringBuilder(128); String line = null; while ((line = reader.readLine()) != null) { sb.append(line); sb.append("\n"); } reader.close(); content = sb.toString(); } catch (IOException e) { e.printStackTrace(); return noGeocoderResult("Error parsing geocoder response"); } List<NominatimGeocoderResult> nominatimResults = nominatimJsonDeserializer.parseResults(content); List<GeocoderResult> geocoderResults = new ArrayList<GeocoderResult>(); for (NominatimGeocoderResult nominatimGeocoderResult : nominatimResults) { Double lat = nominatimGeocoderResult.getLatDouble(); Double lng = nominatimGeocoderResult.getLngDouble(); String displayName = nominatimGeocoderResult.getDisplay_name(); GeocoderResult geocoderResult = new GeocoderResult(lat, lng, displayName); geocoderResults.add(geocoderResult); } return new GeocoderResults(geocoderResults); } private URL getNominatimGeocoderUrl(String address, Envelope bbox) throws IOException { UriBuilder uriBuilder = UriBuilder.fromUri(nominatimUrl); uriBuilder.queryParam("q", address); uriBuilder.queryParam("format", "json"); if (bbox != null) { uriBuilder.queryParam("viewbox", bbox.getMinX() + "," + bbox.getMinY() + "," + bbox.getMaxX() + "," + bbox.getMaxY()); uriBuilder.queryParam("bounded", 1); } else if (viewBox != null) { uriBuilder.queryParam("viewbox", viewBox); uriBuilder.queryParam("bounded", 1); } if (resultLimit != null) { uriBuilder.queryParam("limit", resultLimit); } if (emailAddress != null) { uriBuilder.queryParam("email", emailAddress); } URI uri = uriBuilder.build(); return new URL(uri.toString()); } private GeocoderResults noGeocoderResult(String error) { return new GeocoderResults(error); } }