/* ------------------------------------------------------------------------- OpenTripPlanner GWT Client Copyright (C) 2015 Mecatran - info@mecatran.com This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. ------------------------------------------------------------------------- */ package com.mecatran.otp.gwt.client.proxies.osm; import java.util.ArrayList; import java.util.List; import com.google.gwt.core.client.JsArray; import com.mecatran.otp.gwt.client.model.LocationBean; import com.mecatran.otp.gwt.client.model.Wgs84BoundsBean; import com.mecatran.otp.gwt.client.model.Wgs84LatLonBean; import com.mecatran.otp.gwt.client.proxies.GeocoderProxy; import com.mecatran.otp.gwt.client.utils.HttpUtils; import com.mecatran.otp.gwt.client.utils.HttpUtils.DownloadListener; public class NominatimGeocoderProxy implements GeocoderProxy { public static final String OSM_NOMINATIM_URL = "http://nominatim.openstreetmap.org"; public static final String MAPQUEST_NOMINATIM_URL = "http://open.mapquestapi.com/nominatim/v1"; private String baseUrl; private Wgs84BoundsBean bounds; private int limit; public NominatimGeocoderProxy(String baseUrl, int limit) { this.baseUrl = baseUrl; this.limit = limit; } @Override public void configure(Wgs84BoundsBean bounds, String mainCountryName) { this.bounds = bounds; } @Override public void geocode(String address, final GeocoderListener listener) { String url = buildSearchUrl(address); HttpUtils.downloadJson(url, new DownloadListener<JsArray<NominatimPlace>>() { @Override public void onSuccess(JsArray<NominatimPlace> results) { List<LocationBean> locations = new ArrayList<>(results .length()); for (int i = 0; i < results.length(); i++) { NominatimPlace result = results.get(i); LocationBean location = new LocationBean(); location.setAddress(result.getFormattedAddress()); location.setLocation(new Wgs84LatLonBean(result .getLatitude(), result.getLongitude())); locations.add(location); } listener.onGeocodingDone(locations); } @Override public void onFailure(String msg) { listener.onGeocodingDone(null); } }); } @Override public void reverseGeocode(Wgs84LatLonBean location, final ReverseGeocoderListener listener) { String url = buildReverseUrl(location); HttpUtils.downloadJson(url, new DownloadListener<NominatimPlace>() { @Override public void onSuccess(NominatimPlace result) { if (result.getError() != null) { listener.onReverseGeocodingDone(null, 0); } else { LocationBean addr = new LocationBean(); addr.setLocation(new Wgs84LatLonBean(result.getLatitude(), result.getLongitude())); addr.setAddress(result.getFormattedAddress()); listener.onReverseGeocodingDone(addr, 100); } } @Override public void onFailure(String msg) { listener.onReverseGeocodingDone(null, 0); } }); } private String buildSearchUrl(String query) { StringBuffer sb = new StringBuffer(baseUrl); sb.append("/search?format=json"); sb.append("&limit=").append(limit); sb.append("&addressdetails=1"); sb.append("&viewport=").append(bounds.getMinLon()).append(",") .append(bounds.getMinLat()).append(",") .append(bounds.getMaxLon()).append(",") .append(bounds.getMaxLat()); sb.append("&bounded=1"); sb.append("&q=").append(query); // TODO URL-encode return sb.toString(); } private String buildReverseUrl(Wgs84LatLonBean location) { StringBuffer sb = new StringBuffer(baseUrl); sb.append("/reverse?format=json"); sb.append("&addressdetails=1"); sb.append("&lat=").append(location.getLat()); sb.append("&lon=").append(location.getLon()); return sb.toString(); } }