diff options
5 files changed, 136 insertions, 109 deletions
diff --git a/src/org/traccar/geocode/GisgraphyReverseGeocoder.java b/src/org/traccar/geocode/GisgraphyReverseGeocoder.java index 9d513a6f5..392a11e66 100644 --- a/src/org/traccar/geocode/GisgraphyReverseGeocoder.java +++ b/src/org/traccar/geocode/GisgraphyReverseGeocoder.java @@ -23,45 +23,33 @@ import java.io.InputStreamReader; import java.net.URL; import java.net.URLConnection; -public class GisgraphyReverseGeocoder implements ReverseGeocoder { - - private final String url; +public class GisgraphyReverseGeocoder extends JsonReverseGeocoder { public GisgraphyReverseGeocoder() { this("http://services.gisgraphy.com/street/streetsearch"); } public GisgraphyReverseGeocoder(String url) { - this.url = url + "?format=json&lat=%f&lng=%f&from=1&to=1"; + super(url + "?format=json&lat=%f&lng=%f&from=1&to=1"); } @Override - public String getAddress(AddressFormat format, double latitude, double longitude) { - - try { - Address address = new Address(); - URLConnection conn = new URL(String.format(url, latitude, longitude)).openConnection(); - - JsonObject json = Json.createReader(new InputStreamReader(conn.getInputStream())).readObject(); - JsonObject result = json.getJsonArray("result").getJsonObject(0); - - if (result.containsKey("name")) { - address.setStreet(result.getString("name")); - } - if (result.containsKey("isIn")) { - address.setSettlement(result.getString("isIn")); - } - if (result.containsKey("countryCode")) { - address.setCountry(result.getString("countryCode")); - } + protected Address parseAddress(JsonObject json) { + Address address = new Address(); - return format.format(address); + JsonObject result = json.getJsonArray("result").getJsonObject(0); - } catch(Exception error) { - Log.warning(error); + if (result.containsKey("name")) { + address.setStreet(result.getString("name")); + } + if (result.containsKey("isIn")) { + address.setSettlement(result.getString("isIn")); + } + if (result.containsKey("countryCode")) { + address.setCountry(result.getString("countryCode")); } - return null; + return address; } } diff --git a/src/org/traccar/geocode/GoogleReverseGeocoder.java b/src/org/traccar/geocode/GoogleReverseGeocoder.java index efefdb0f6..df8d99545 100644 --- a/src/org/traccar/geocode/GoogleReverseGeocoder.java +++ b/src/org/traccar/geocode/GoogleReverseGeocoder.java @@ -24,60 +24,53 @@ import javax.json.JsonObject; import javax.json.JsonString; import org.traccar.helper.Log; -public class GoogleReverseGeocoder implements ReverseGeocoder { +public class GoogleReverseGeocoder extends JsonReverseGeocoder { - private final String url = "http://maps.googleapis.com/maps/api/geocode/json?latlng=%f,%f"; + public GoogleReverseGeocoder() { + super("http://maps.googleapis.com/maps/api/geocode/json?latlng=%f,%f"); + } @Override - public String getAddress(AddressFormat format, double latitude, double longitude) { + protected Address parseAddress(JsonObject json) { + JsonArray results = json.getJsonArray("results"); - try { + if (!results.isEmpty()) { Address address = new Address(); - URLConnection conn = new URL(String.format(url, latitude, longitude)).openConnection(); - - JsonObject json = Json.createReader(new InputStreamReader(conn.getInputStream())).readObject(); - JsonArray results = json.getJsonArray("results"); - if (!results.isEmpty()) { + JsonObject result = (JsonObject) results.get(0); + JsonArray components = result.getJsonArray("address_components"); - JsonObject result = (JsonObject) results.get(0); - JsonArray components = result.getJsonArray("address_components"); + for (JsonObject component : components.getValuesAs(JsonObject.class)) { - for (JsonObject component : components.getValuesAs(JsonObject.class)) { + String value = component.getString("short_name"); - String value = component.getString("short_name"); - - for (JsonString type : component.getJsonArray("types").getValuesAs(JsonString.class)) { - if (type.getString().equals("street_number")) { - address.setHouse(value); - break; - } else if (type.getString().equals("route")) { - address.setStreet(value); - break; - } else if (type.getString().equals("locality")) { - address.setSettlement(value); - break; - } else if (type.getString().equals("administrative_area_level_2")) { - address.setDistrict(value); - break; - } else if (type.getString().equals("administrative_area_level_1")) { - address.setState(value); - break; - } else if (type.getString().equals("country")) { - address.setCountry(value); - break; - } else if (type.getString().equals("postal_code")) { - address.setPostcode(value); - break; - } + for (JsonString type : component.getJsonArray("types").getValuesAs(JsonString.class)) { + if (type.getString().equals("street_number")) { + address.setHouse(value); + break; + } else if (type.getString().equals("route")) { + address.setStreet(value); + break; + } else if (type.getString().equals("locality")) { + address.setSettlement(value); + break; + } else if (type.getString().equals("administrative_area_level_2")) { + address.setDistrict(value); + break; + } else if (type.getString().equals("administrative_area_level_1")) { + address.setState(value); + break; + } else if (type.getString().equals("country")) { + address.setCountry(value); + break; + } else if (type.getString().equals("postal_code")) { + address.setPostcode(value); + break; } } - - return format.format(address); } - } catch(Exception error) { - Log.warning(error); + return address; } return null; diff --git a/src/org/traccar/geocode/JsonReverseGeocoder.java b/src/org/traccar/geocode/JsonReverseGeocoder.java new file mode 100644 index 000000000..cd7dafae5 --- /dev/null +++ b/src/org/traccar/geocode/JsonReverseGeocoder.java @@ -0,0 +1,58 @@ +/* + * Copyright 2015 Anton Tananaev (anton.tananaev@gmail.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.geocode; + +import org.traccar.helper.Log; + +import javax.json.Json; +import javax.json.JsonObject; +import java.io.InputStreamReader; +import java.io.Reader; +import java.net.URL; +import java.net.URLConnection; + +public abstract class JsonReverseGeocoder implements ReverseGeocoder { + + private final String url; + + public JsonReverseGeocoder(String url) { + this.url = url; + } + + @Override + public String getAddress(AddressFormat format, double latitude, double longitude) { + + try { + URLConnection conn = new URL(String.format(url, latitude, longitude)).openConnection(); + Reader reader = new InputStreamReader(conn.getInputStream()); + try { + Address address = parseAddress(Json.createReader(reader).readObject()); + if (address != null) { + return format.format(address); + } + } finally { + reader.close(); + } + } catch(Exception error) { + Log.warning(error); + } + + return null; + } + + protected abstract Address parseAddress(JsonObject json); + +} diff --git a/src/org/traccar/geocode/NominatimReverseGeocoder.java b/src/org/traccar/geocode/NominatimReverseGeocoder.java index 911e0fa71..6777f5a82 100644 --- a/src/org/traccar/geocode/NominatimReverseGeocoder.java +++ b/src/org/traccar/geocode/NominatimReverseGeocoder.java @@ -27,59 +27,47 @@ import javax.xml.parsers.DocumentBuilderFactory; import org.traccar.helper.Log; import org.w3c.dom.Document; -public class NominatimReverseGeocoder implements ReverseGeocoder { - - private final String url; +public class NominatimReverseGeocoder extends JsonReverseGeocoder { public NominatimReverseGeocoder() { this("http://nominatim.openstreetmap.org/reverse"); } public NominatimReverseGeocoder(String url) { - this.url = url + "?format=json&lat=%f&lon=%f&zoom=18&addressdetails=1"; + super(url + "?format=json&lat=%f&lon=%f&zoom=18&addressdetails=1"); } @Override - public String getAddress(AddressFormat format, double latitude, double longitude) { - - try { - Address address = new Address(); - URLConnection conn = new URL(String.format(url, latitude, longitude)).openConnection(); - - JsonObject json = Json.createReader(new InputStreamReader(conn.getInputStream())).readObject().getJsonObject("address"); - - if (json.containsKey("house_number")) { - address.setHouse(json.getString("house_number")); - } - if (json.containsKey("road")) { - address.setStreet(json.getString("road")); - } - if (json.containsKey("village")) { - address.setSettlement(json.getString("village")); - } - if (json.containsKey("city")) { - address.setSettlement(json.getString("city")); - } - if (json.containsKey("state_district")) { - address.setDistrict(json.getString("state_district")); - } - if (json.containsKey("state")) { - address.setState(json.getString("state")); - } - if (json.containsKey("country_code")) { - address.setCountry(json.getString("country_code").toUpperCase()); - } - if (json.containsKey("postcode")) { - address.setPostcode(json.getString("postcode")); - } + protected Address parseAddress(JsonObject json) { + Address address = new Address(); + JsonObject result = json.getJsonObject("address"); - return format.format(address); - - } catch(Exception error) { - Log.warning(error); + if (result.containsKey("house_number")) { + address.setHouse(result.getString("house_number")); + } + if (result.containsKey("road")) { + address.setStreet(result.getString("road")); + } + if (result.containsKey("village")) { + address.setSettlement(result.getString("village")); + } + if (result.containsKey("city")) { + address.setSettlement(result.getString("city")); + } + if (result.containsKey("state_district")) { + address.setDistrict(result.getString("state_district")); + } + if (result.containsKey("state")) { + address.setState(result.getString("state")); + } + if (result.containsKey("country_code")) { + address.setCountry(result.getString("country_code").toUpperCase()); + } + if (result.containsKey("postcode")) { + address.setPostcode(result.getString("postcode")); } - return null; + return address; } } diff --git a/test/org/traccar/geocode/ReverseGeocoderTest.java b/test/org/traccar/geocode/ReverseGeocoderTest.java index 6f244b545..cae515e27 100644 --- a/test/org/traccar/geocode/ReverseGeocoderTest.java +++ b/test/org/traccar/geocode/ReverseGeocoderTest.java @@ -11,7 +11,7 @@ public class ReverseGeocoderTest { ReverseGeocoder reverseGeocoder = new GoogleReverseGeocoder(); assertEquals( - "1700 Charleston Rd, Mountain View, CA, US", + "1600 Amphitheatre Pkwy, Mountain View, CA, US", reverseGeocoder.getAddress(new AddressFormat(), 37.4217550, -122.0846330)); } |