From 68569c05fb4be377baed5cd0ecb1b75176d24f01 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 31 Dec 2016 11:35:58 +1300 Subject: Rename geocode package to geocoder --- src/org/traccar/Context.java | 18 ++-- src/org/traccar/ReverseGeocoderHandler.java | 4 +- src/org/traccar/geocode/Address.java | 100 ------------------ src/org/traccar/geocode/AddressFormat.java | 80 --------------- .../traccar/geocode/BingMapsReverseGeocoder.java | 59 ----------- .../traccar/geocode/FactualReverseGeocoder.java | 57 ----------- .../geocode/GeocodeFarmReverseGeocoder.java | 61 ----------- .../traccar/geocode/GisgraphyReverseGeocoder.java | 52 ---------- src/org/traccar/geocode/GoogleReverseGeocoder.java | 86 ---------------- src/org/traccar/geocode/JsonReverseGeocoder.java | 89 ---------------- .../traccar/geocode/MapQuestReverseGeocoder.java | 62 ----------- .../traccar/geocode/NominatimReverseGeocoder.java | 81 --------------- .../traccar/geocode/OpenCageReverseGeocoder.java | 73 ------------- src/org/traccar/geocode/ReverseGeocoder.java | 30 ------ src/org/traccar/geocoder/Address.java | 100 ++++++++++++++++++ src/org/traccar/geocoder/AddressFormat.java | 80 +++++++++++++++ .../traccar/geocoder/BingMapsReverseGeocoder.java | 59 +++++++++++ .../traccar/geocoder/FactualReverseGeocoder.java | 57 +++++++++++ .../geocoder/GeocodeFarmReverseGeocoder.java | 61 +++++++++++ .../traccar/geocoder/GisgraphyReverseGeocoder.java | 52 ++++++++++ .../traccar/geocoder/GoogleReverseGeocoder.java | 86 ++++++++++++++++ src/org/traccar/geocoder/JsonReverseGeocoder.java | 89 ++++++++++++++++ .../traccar/geocoder/MapQuestReverseGeocoder.java | 62 +++++++++++ .../traccar/geocoder/NominatimReverseGeocoder.java | 81 +++++++++++++++ .../traccar/geocoder/OpenCageReverseGeocoder.java | 73 +++++++++++++ src/org/traccar/geocoder/ReverseGeocoder.java | 30 ++++++ test/org/traccar/geocode/AddressFormatTest.java | 32 ------ test/org/traccar/geocode/ReverseGeocoderTest.java | 114 --------------------- test/org/traccar/geocoder/AddressFormatTest.java | 32 ++++++ test/org/traccar/geocoder/ReverseGeocoderTest.java | 114 +++++++++++++++++++++ 30 files changed, 987 insertions(+), 987 deletions(-) delete mode 100644 src/org/traccar/geocode/Address.java delete mode 100644 src/org/traccar/geocode/AddressFormat.java delete mode 100644 src/org/traccar/geocode/BingMapsReverseGeocoder.java delete mode 100644 src/org/traccar/geocode/FactualReverseGeocoder.java delete mode 100644 src/org/traccar/geocode/GeocodeFarmReverseGeocoder.java delete mode 100644 src/org/traccar/geocode/GisgraphyReverseGeocoder.java delete mode 100644 src/org/traccar/geocode/GoogleReverseGeocoder.java delete mode 100644 src/org/traccar/geocode/JsonReverseGeocoder.java delete mode 100644 src/org/traccar/geocode/MapQuestReverseGeocoder.java delete mode 100644 src/org/traccar/geocode/NominatimReverseGeocoder.java delete mode 100644 src/org/traccar/geocode/OpenCageReverseGeocoder.java delete mode 100644 src/org/traccar/geocode/ReverseGeocoder.java create mode 100644 src/org/traccar/geocoder/Address.java create mode 100644 src/org/traccar/geocoder/AddressFormat.java create mode 100644 src/org/traccar/geocoder/BingMapsReverseGeocoder.java create mode 100644 src/org/traccar/geocoder/FactualReverseGeocoder.java create mode 100644 src/org/traccar/geocoder/GeocodeFarmReverseGeocoder.java create mode 100644 src/org/traccar/geocoder/GisgraphyReverseGeocoder.java create mode 100644 src/org/traccar/geocoder/GoogleReverseGeocoder.java create mode 100644 src/org/traccar/geocoder/JsonReverseGeocoder.java create mode 100644 src/org/traccar/geocoder/MapQuestReverseGeocoder.java create mode 100644 src/org/traccar/geocoder/NominatimReverseGeocoder.java create mode 100644 src/org/traccar/geocoder/OpenCageReverseGeocoder.java create mode 100644 src/org/traccar/geocoder/ReverseGeocoder.java delete mode 100644 test/org/traccar/geocode/AddressFormatTest.java delete mode 100644 test/org/traccar/geocode/ReverseGeocoderTest.java create mode 100644 test/org/traccar/geocoder/AddressFormatTest.java create mode 100644 test/org/traccar/geocoder/ReverseGeocoderTest.java diff --git a/src/org/traccar/Context.java b/src/org/traccar/Context.java index 4825158c4..72d5dd9f8 100644 --- a/src/org/traccar/Context.java +++ b/src/org/traccar/Context.java @@ -34,15 +34,15 @@ import org.traccar.database.NotificationManager; import org.traccar.database.PermissionsManager; import org.traccar.database.GeofenceManager; import org.traccar.database.StatisticsManager; -import org.traccar.geocode.BingMapsReverseGeocoder; -import org.traccar.geocode.FactualReverseGeocoder; -import org.traccar.geocode.GeocodeFarmReverseGeocoder; -import org.traccar.geocode.GisgraphyReverseGeocoder; -import org.traccar.geocode.GoogleReverseGeocoder; -import org.traccar.geocode.MapQuestReverseGeocoder; -import org.traccar.geocode.NominatimReverseGeocoder; -import org.traccar.geocode.OpenCageReverseGeocoder; -import org.traccar.geocode.ReverseGeocoder; +import org.traccar.geocoder.BingMapsReverseGeocoder; +import org.traccar.geocoder.FactualReverseGeocoder; +import org.traccar.geocoder.GeocodeFarmReverseGeocoder; +import org.traccar.geocoder.GisgraphyReverseGeocoder; +import org.traccar.geocoder.GoogleReverseGeocoder; +import org.traccar.geocoder.MapQuestReverseGeocoder; +import org.traccar.geocoder.NominatimReverseGeocoder; +import org.traccar.geocoder.OpenCageReverseGeocoder; +import org.traccar.geocoder.ReverseGeocoder; import org.traccar.helper.Log; import org.traccar.geolocation.GoogleGeolocationProvider; import org.traccar.geolocation.GeolocationProvider; diff --git a/src/org/traccar/ReverseGeocoderHandler.java b/src/org/traccar/ReverseGeocoderHandler.java index 7304234cc..5813c1136 100644 --- a/src/org/traccar/ReverseGeocoderHandler.java +++ b/src/org/traccar/ReverseGeocoderHandler.java @@ -20,8 +20,8 @@ import org.jboss.netty.channel.ChannelHandlerContext; import org.jboss.netty.channel.ChannelUpstreamHandler; import org.jboss.netty.channel.Channels; import org.jboss.netty.channel.MessageEvent; -import org.traccar.geocode.AddressFormat; -import org.traccar.geocode.ReverseGeocoder; +import org.traccar.geocoder.AddressFormat; +import org.traccar.geocoder.ReverseGeocoder; import org.traccar.helper.Log; import org.traccar.model.Position; diff --git a/src/org/traccar/geocode/Address.java b/src/org/traccar/geocode/Address.java deleted file mode 100644 index d77602f2c..000000000 --- a/src/org/traccar/geocode/Address.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright 2015 Anton Tananaev (anton@traccar.org) - * - * 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; - -public class Address { - - private String postcode; - - public String getPostcode() { - return postcode; - } - - public void setPostcode(String postcode) { - this.postcode = postcode; - } - - private String country; - - public String getCountry() { - return country; - } - - public void setCountry(String country) { - this.country = country; - } - - private String state; - - public String getState() { - return state; - } - - public void setState(String state) { - this.state = state; - } - - private String district; - - public String getDistrict() { - return district; - } - - public void setDistrict(String district) { - this.district = district; - } - - private String settlement; - - public String getSettlement() { - return settlement; - } - - public void setSettlement(String settlement) { - this.settlement = settlement; - } - - private String suburb; - - public String getSuburb() { - return suburb; - } - - public void setSuburb(String suburb) { - this.suburb = suburb; - } - - private String street; - - public String getStreet() { - return street; - } - - public void setStreet(String street) { - this.street = street; - } - - private String house; - - public String getHouse() { - return house; - } - - public void setHouse(String house) { - this.house = house; - } - -} diff --git a/src/org/traccar/geocode/AddressFormat.java b/src/org/traccar/geocode/AddressFormat.java deleted file mode 100644 index 8046abfd7..000000000 --- a/src/org/traccar/geocode/AddressFormat.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright 2015 Anton Tananaev (anton@traccar.org) - * - * 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 java.text.FieldPosition; -import java.text.Format; -import java.text.ParsePosition; - -/** - * Available parameters: - * - * %p - postcode - * %c - country - * %s - state - * %d - district - * %t - settlement (town) - * %u - suburb - * %r - street (road) - * %h - house - * - */ -public class AddressFormat extends Format { - - private final String format; - - public AddressFormat() { - this("%h %r, %t, %s, %c"); - } - - public AddressFormat(String format) { - this.format = format; - } - - private static String replace(String s, String key, String value) { - if (value != null) { - s = s.replace(key, value); - } else { - s = s.replaceAll("[, ]*" + key, ""); - } - return s; - } - - @Override - public StringBuffer format(Object o, StringBuffer stringBuffer, FieldPosition fieldPosition) { - Address address = (Address) o; - String result = format; - - result = replace(result, "%p", address.getPostcode()); - result = replace(result, "%c", address.getCountry()); - result = replace(result, "%s", address.getState()); - result = replace(result, "%d", address.getDistrict()); - result = replace(result, "%t", address.getSettlement()); - result = replace(result, "%u", address.getSuburb()); - result = replace(result, "%r", address.getStreet()); - result = replace(result, "%h", address.getHouse()); - - result = result.replaceAll("^[, ]*", ""); - - return stringBuffer.append(result); - } - - @Override - public Address parseObject(String s, ParsePosition parsePosition) { - throw new UnsupportedOperationException(); - } - -} diff --git a/src/org/traccar/geocode/BingMapsReverseGeocoder.java b/src/org/traccar/geocode/BingMapsReverseGeocoder.java deleted file mode 100644 index 69148875a..000000000 --- a/src/org/traccar/geocode/BingMapsReverseGeocoder.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2014 - 2015 Stefaan Van Dooren (stefaan.vandooren@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 javax.json.JsonArray; -import javax.json.JsonObject; - -public class BingMapsReverseGeocoder extends JsonReverseGeocoder { - - public BingMapsReverseGeocoder(String url, String key, int cacheSize) { - super(url + "/Locations/%f,%f?key=" + key + "&include=ciso2", cacheSize); - } - - @Override - public Address parseAddress(JsonObject json) { - JsonArray result = json.getJsonArray("resourceSets"); - if (result != null) { - JsonObject location = - result.getJsonObject(0).getJsonArray("resources").getJsonObject(0).getJsonObject("address"); - if (location != null) { - Address address = new Address(); - if (location.containsKey("addressLine")) { - address.setStreet(location.getString("addressLine")); - } - if (location.containsKey("locality")) { - address.setSettlement(location.getString("locality")); - } - if (location.containsKey("adminDistrict2")) { - address.setDistrict(location.getString("adminDistrict2")); - } - if (location.containsKey("adminDistrict")) { - address.setState(location.getString("adminDistrict")); - } - if (location.containsKey("countryRegionIso2")) { - address.setCountry(location.getString("countryRegionIso2").toUpperCase()); - } - if (location.containsKey("postalCode")) { - address.setPostcode(location.getString("postalCode")); - } - return address; - } - } - return null; - } - -} diff --git a/src/org/traccar/geocode/FactualReverseGeocoder.java b/src/org/traccar/geocode/FactualReverseGeocoder.java deleted file mode 100644 index 15211f74a..000000000 --- a/src/org/traccar/geocode/FactualReverseGeocoder.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2014 - 2015 Stefaan Van Dooren (stefaan.vandooren@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 javax.json.JsonObject; - -public class FactualReverseGeocoder extends JsonReverseGeocoder { - - public FactualReverseGeocoder(String url, String key, int cacheSize) { - super(url + "?latitude=%f&longitude=%f&KEY=" + key, cacheSize); - } - - @Override - public Address parseAddress(JsonObject json) { - JsonObject result = json.getJsonObject("response").getJsonObject("data"); - if (result != null) { - Address address = new Address(); - if (result.getJsonObject("street_number") != null) { - address.setHouse(result.getJsonObject("street_number").getString("name")); - } - if (result.getJsonObject("street_name") != null) { - address.setStreet(result.getJsonObject("street_name").getString("name")); - } - if (result.getJsonObject("locality") != null) { - address.setSettlement(result.getJsonObject("locality").getString("name")); - } - if (result.getJsonObject("county") != null) { - address.setDistrict(result.getJsonObject("county").getString("name")); - } - if (result.getJsonObject("region") != null) { - address.setState(result.getJsonObject("region").getString("name")); - } - if (result.getJsonObject("country") != null) { - address.setCountry(result.getJsonObject("country").getString("name")); - } - if (result.getJsonObject("postcode") != null) { - address.setPostcode(result.getJsonObject("postcode").getString("name")); - } - return address; - } - return null; - } - -} diff --git a/src/org/traccar/geocode/GeocodeFarmReverseGeocoder.java b/src/org/traccar/geocode/GeocodeFarmReverseGeocoder.java deleted file mode 100644 index 477eec15b..000000000 --- a/src/org/traccar/geocode/GeocodeFarmReverseGeocoder.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2016 Anton Tananaev (anton@traccar.org) - * - * 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 javax.json.JsonObject; - -public class GeocodeFarmReverseGeocoder extends JsonReverseGeocoder { - - private static final String URL = "https://www.geocode.farm/v3/json/reverse/"; - - public GeocodeFarmReverseGeocoder(int cacheSize) { - super(URL + "?lat=%f&lon=%f&country=us&lang=en&count=1", cacheSize); - } - - public GeocodeFarmReverseGeocoder(String key, int cacheSize) { - super(URL + "?lat=%f&lon=%f&country=us&lang=en&count=1&key=" + key, cacheSize); - } - - @Override - public Address parseAddress(JsonObject json) { - Address address = new Address(); - - JsonObject result = json - .getJsonObject("geocoding_results") - .getJsonArray("RESULTS") - .getJsonObject(0) - .getJsonObject("ADDRESS"); - - if (result.containsKey("street_number")) { - address.setStreet(result.getString("street_number")); - } - if (result.containsKey("street_name")) { - address.setStreet(result.getString("street_name")); - } - if (result.containsKey("locality")) { - address.setSettlement(result.getString("locality")); - } - if (result.containsKey("admin_1")) { - address.setState(result.getString("admin_1")); - } - if (result.containsKey("country")) { - address.setCountry(result.getString("country")); - } - - return address; - } - -} diff --git a/src/org/traccar/geocode/GisgraphyReverseGeocoder.java b/src/org/traccar/geocode/GisgraphyReverseGeocoder.java deleted file mode 100644 index dd5e1ff5b..000000000 --- a/src/org/traccar/geocode/GisgraphyReverseGeocoder.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2015 - 2016 Anton Tananaev (anton@traccar.org) - * - * 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 javax.json.JsonObject; - -public class GisgraphyReverseGeocoder extends JsonReverseGeocoder { - - public GisgraphyReverseGeocoder() { - this("http://services.gisgraphy.com/reversegeocoding/search", 0); - } - - public GisgraphyReverseGeocoder(String url, int cacheSize) { - super(url + "?format=json&lat=%f&lng=%f&from=1&to=1", cacheSize); - } - - @Override - public Address parseAddress(JsonObject json) { - Address address = new Address(); - - JsonObject result = json.getJsonArray("result").getJsonObject(0); - - if (result.containsKey("streetName")) { - address.setStreet(result.getString("streetName")); - } - if (result.containsKey("city")) { - address.setSettlement(result.getString("city")); - } - if (result.containsKey("state")) { - address.setState(result.getString("state")); - } - if (result.containsKey("countryCode")) { - address.setCountry(result.getString("countryCode")); - } - - return address; - } - -} diff --git a/src/org/traccar/geocode/GoogleReverseGeocoder.java b/src/org/traccar/geocode/GoogleReverseGeocoder.java deleted file mode 100644 index b9835440e..000000000 --- a/src/org/traccar/geocode/GoogleReverseGeocoder.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright 2012 - 2015 Anton Tananaev (anton@traccar.org) - * - * 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 javax.json.JsonArray; -import javax.json.JsonObject; -import javax.json.JsonString; - -public class GoogleReverseGeocoder extends JsonReverseGeocoder { - - public GoogleReverseGeocoder() { - this(0); - } - - public GoogleReverseGeocoder(int cacheSize) { - super("http://maps.googleapis.com/maps/api/geocode/json?latlng=%f,%f", cacheSize); - } - - public GoogleReverseGeocoder(String key, int cacheSize) { - super("https://maps.googleapis.com/maps/api/geocode/json?latlng=%f,%f&key=" + key, cacheSize); - } - - @Override - public Address parseAddress(JsonObject json) { - JsonArray results = json.getJsonArray("results"); - - if (!results.isEmpty()) { - Address address = new Address(); - - JsonObject result = (JsonObject) results.get(0); - JsonArray components = result.getJsonArray("address_components"); - - for (JsonObject component : components.getValuesAs(JsonObject.class)) { - - String value = component.getString("short_name"); - - typesLoop: for (JsonString type : component.getJsonArray("types").getValuesAs(JsonString.class)) { - - switch (type.getString()) { - case "street_number": - address.setHouse(value); - break typesLoop; - case "route": - address.setStreet(value); - break typesLoop; - case "locality": - address.setSettlement(value); - break typesLoop; - case "administrative_area_level_2": - address.setDistrict(value); - break typesLoop; - case "administrative_area_level_1": - address.setState(value); - break typesLoop; - case "country": - address.setCountry(value); - break typesLoop; - case "postal_code": - address.setPostcode(value); - break typesLoop; - default: - break; - } - } - } - - return address; - } - - return null; - } - -} diff --git a/src/org/traccar/geocode/JsonReverseGeocoder.java b/src/org/traccar/geocode/JsonReverseGeocoder.java deleted file mode 100644 index d3661b53c..000000000 --- a/src/org/traccar/geocode/JsonReverseGeocoder.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright 2015 Anton Tananaev (anton@traccar.org) - * - * 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 com.ning.http.client.AsyncCompletionHandler; -import com.ning.http.client.Response; -import org.traccar.Context; - -import javax.json.Json; -import javax.json.JsonObject; -import javax.json.JsonReader; -import java.util.AbstractMap; -import java.util.Collections; -import java.util.LinkedHashMap; -import java.util.Map; - -public abstract class JsonReverseGeocoder implements ReverseGeocoder { - - private final String url; - - private Map, String> cache; - - public JsonReverseGeocoder(String url, final int cacheSize) { - this.url = url; - if (cacheSize > 0) { - this.cache = Collections.synchronizedMap(new LinkedHashMap, String>() { - @Override - protected boolean removeEldestEntry(Map.Entry eldest) { - return size() > cacheSize; - } - }); - } - } - - @Override - public void getAddress( - final AddressFormat format, final double latitude, - final double longitude, final ReverseGeocoderCallback callback) { - - if (cache != null) { - String cachedAddress = cache.get(new AbstractMap.SimpleImmutableEntry<>(latitude, longitude)); - if (cachedAddress != null) { - callback.onSuccess(cachedAddress); - return; - } - } - - Context.getAsyncHttpClient().prepareGet(String.format(url, latitude, longitude)) - .execute(new AsyncCompletionHandler() { - @Override - public Object onCompleted(Response response) throws Exception { - try (JsonReader reader = Json.createReader(response.getResponseBodyAsStream())) { - Address address = parseAddress(reader.readObject()); - if (address != null) { - String formattedAddress = format.format(address); - if (cache != null) { - cache.put(new AbstractMap.SimpleImmutableEntry<>(latitude, longitude), formattedAddress); - } - callback.onSuccess(formattedAddress); - } else { - callback.onFailure(new IllegalArgumentException("Empty address")); - } - } - return null; - } - - @Override - public void onThrowable(Throwable t) { - callback.onFailure(t); - } - }); - } - - public abstract Address parseAddress(JsonObject json); - -} diff --git a/src/org/traccar/geocode/MapQuestReverseGeocoder.java b/src/org/traccar/geocode/MapQuestReverseGeocoder.java deleted file mode 100644 index 93edfdd09..000000000 --- a/src/org/traccar/geocode/MapQuestReverseGeocoder.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2014 - 2015 Stefaan Van Dooren (stefaan.vandooren@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 javax.json.JsonArray; -import javax.json.JsonObject; - -public class MapQuestReverseGeocoder extends JsonReverseGeocoder { - - public MapQuestReverseGeocoder(String url, String key, int cacheSize) { - super(url + "?key=" + key + "&location=%f,%f", cacheSize); - } - - @Override - public Address parseAddress(JsonObject json) { - JsonArray result = json.getJsonArray("results"); - if (result != null) { - JsonArray locations = result.getJsonObject(0).getJsonArray("locations"); - if (locations != null) { - JsonObject location = locations.getJsonObject(0); - - Address address = new Address(); - - if (location.containsKey("street")) { - address.setStreet(location.getString("street")); - } - if (location.containsKey("adminArea5")) { - address.setSettlement(location.getString("adminArea5")); - } - if (location.containsKey("adminArea4")) { - address.setDistrict(location.getString("adminArea4")); - } - if (location.containsKey("adminArea3")) { - address.setState(location.getString("adminArea3")); - } - if (location.containsKey("adminArea1")) { - address.setCountry(location.getString("adminArea1").toUpperCase()); - } - if (location.containsKey("postalCode")) { - address.setPostcode(location.getString("postalCode")); - } - - return address; - } - } - return null; - } - -} diff --git a/src/org/traccar/geocode/NominatimReverseGeocoder.java b/src/org/traccar/geocode/NominatimReverseGeocoder.java deleted file mode 100644 index b393f6490..000000000 --- a/src/org/traccar/geocode/NominatimReverseGeocoder.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2014 - 2015 Anton Tananaev (anton@traccar.org) - * - * 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 javax.json.JsonObject; - -public class NominatimReverseGeocoder extends JsonReverseGeocoder { - - public NominatimReverseGeocoder() { - this("http://nominatim.openstreetmap.org/reverse", 0); - } - - public NominatimReverseGeocoder(String url, int cacheSize) { - super(url + "?format=json&lat=%f&lon=%f&zoom=18&addressdetails=1", cacheSize); - } - - public NominatimReverseGeocoder(String url, String key, int cacheSize) { - super(url + "?format=json&lat=%f&lon=%f&zoom=18&addressdetails=1&key=" + key, cacheSize); - } - - @Override - public Address parseAddress(JsonObject json) { - JsonObject result = json.getJsonObject("address"); - - if (result != null) { - Address address = new Address(); - - if (result.containsKey("house_number")) { - address.setHouse(result.getString("house_number")); - } - if (result.containsKey("road")) { - address.setStreet(result.getString("road")); - } - if (result.containsKey("suburb")) { - address.setSuburb(result.getString("suburb")); - } - - if (result.containsKey("village")) { - address.setSettlement(result.getString("village")); - } else if (result.containsKey("town")) { - address.setSettlement(result.getString("town")); - } else if (result.containsKey("city")) { - address.setSettlement(result.getString("city")); - } - - if (result.containsKey("state_district")) { - address.setDistrict(result.getString("state_district")); - } else if (result.containsKey("region")) { - address.setDistrict(result.getString("region")); - } - - 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 address; - } - - return null; - } - -} diff --git a/src/org/traccar/geocode/OpenCageReverseGeocoder.java b/src/org/traccar/geocode/OpenCageReverseGeocoder.java deleted file mode 100644 index df447d59e..000000000 --- a/src/org/traccar/geocode/OpenCageReverseGeocoder.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2014 - 2015 Stefaan Van Dooren (stefaan.vandooren@gmail.com) - * Copyright 2016 Anton Tananaev (anton@traccar.org) - * - * 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 javax.json.JsonArray; -import javax.json.JsonObject; - -public class OpenCageReverseGeocoder extends JsonReverseGeocoder { - - public OpenCageReverseGeocoder(String url, String key, int cacheSize) { - super(url + "/json?q=%f,%f&key=" + key, cacheSize); - } - - @Override - public Address parseAddress(JsonObject json) { - JsonArray result = json.getJsonArray("results"); - if (result != null) { - JsonObject location = result.getJsonObject(0).getJsonObject("components"); - if (location != null) { - Address address = new Address(); - - if (location.containsKey("building")) { - address.setHouse(location.getString("building")); - } - if (location.containsKey("house_number")) { - address.setHouse(location.getString("house_number")); - } - if (location.containsKey("road")) { - address.setStreet(location.getString("road")); - } - if (location.containsKey("suburb")) { - address.setSuburb(location.getString("suburb")); - } - if (location.containsKey("city")) { - address.setSettlement(location.getString("city")); - } - if (location.containsKey("city_district")) { - address.setSettlement(location.getString("city_district")); - } - if (location.containsKey("county")) { - address.setDistrict(location.getString("county")); - } - if (location.containsKey("state")) { - address.setState(location.getString("state")); - } - if (location.containsKey("country_code")) { - address.setCountry(location.getString("country_code").toUpperCase()); - } - if (location.containsKey("postcode")) { - address.setPostcode(location.getString("postcode")); - } - - return address; - } - } - return null; - } - -} diff --git a/src/org/traccar/geocode/ReverseGeocoder.java b/src/org/traccar/geocode/ReverseGeocoder.java deleted file mode 100644 index b67ac50bb..000000000 --- a/src/org/traccar/geocode/ReverseGeocoder.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2012 - 2013 Anton Tananaev (anton@traccar.org) - * - * 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; - -public interface ReverseGeocoder { - - interface ReverseGeocoderCallback { - - void onSuccess(String address); - - void onFailure(Throwable e); - - } - - void getAddress(AddressFormat format, double latitude, double longitude, ReverseGeocoderCallback callback); - -} diff --git a/src/org/traccar/geocoder/Address.java b/src/org/traccar/geocoder/Address.java new file mode 100644 index 000000000..d542d1b19 --- /dev/null +++ b/src/org/traccar/geocoder/Address.java @@ -0,0 +1,100 @@ +/* + * Copyright 2015 Anton Tananaev (anton@traccar.org) + * + * 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.geocoder; + +public class Address { + + private String postcode; + + public String getPostcode() { + return postcode; + } + + public void setPostcode(String postcode) { + this.postcode = postcode; + } + + private String country; + + public String getCountry() { + return country; + } + + public void setCountry(String country) { + this.country = country; + } + + private String state; + + public String getState() { + return state; + } + + public void setState(String state) { + this.state = state; + } + + private String district; + + public String getDistrict() { + return district; + } + + public void setDistrict(String district) { + this.district = district; + } + + private String settlement; + + public String getSettlement() { + return settlement; + } + + public void setSettlement(String settlement) { + this.settlement = settlement; + } + + private String suburb; + + public String getSuburb() { + return suburb; + } + + public void setSuburb(String suburb) { + this.suburb = suburb; + } + + private String street; + + public String getStreet() { + return street; + } + + public void setStreet(String street) { + this.street = street; + } + + private String house; + + public String getHouse() { + return house; + } + + public void setHouse(String house) { + this.house = house; + } + +} diff --git a/src/org/traccar/geocoder/AddressFormat.java b/src/org/traccar/geocoder/AddressFormat.java new file mode 100644 index 000000000..0800d6dcc --- /dev/null +++ b/src/org/traccar/geocoder/AddressFormat.java @@ -0,0 +1,80 @@ +/* + * Copyright 2015 Anton Tananaev (anton@traccar.org) + * + * 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.geocoder; + +import java.text.FieldPosition; +import java.text.Format; +import java.text.ParsePosition; + +/** + * Available parameters: + * + * %p - postcode + * %c - country + * %s - state + * %d - district + * %t - settlement (town) + * %u - suburb + * %r - street (road) + * %h - house + * + */ +public class AddressFormat extends Format { + + private final String format; + + public AddressFormat() { + this("%h %r, %t, %s, %c"); + } + + public AddressFormat(String format) { + this.format = format; + } + + private static String replace(String s, String key, String value) { + if (value != null) { + s = s.replace(key, value); + } else { + s = s.replaceAll("[, ]*" + key, ""); + } + return s; + } + + @Override + public StringBuffer format(Object o, StringBuffer stringBuffer, FieldPosition fieldPosition) { + Address address = (Address) o; + String result = format; + + result = replace(result, "%p", address.getPostcode()); + result = replace(result, "%c", address.getCountry()); + result = replace(result, "%s", address.getState()); + result = replace(result, "%d", address.getDistrict()); + result = replace(result, "%t", address.getSettlement()); + result = replace(result, "%u", address.getSuburb()); + result = replace(result, "%r", address.getStreet()); + result = replace(result, "%h", address.getHouse()); + + result = result.replaceAll("^[, ]*", ""); + + return stringBuffer.append(result); + } + + @Override + public Address parseObject(String s, ParsePosition parsePosition) { + throw new UnsupportedOperationException(); + } + +} diff --git a/src/org/traccar/geocoder/BingMapsReverseGeocoder.java b/src/org/traccar/geocoder/BingMapsReverseGeocoder.java new file mode 100644 index 000000000..46354d06a --- /dev/null +++ b/src/org/traccar/geocoder/BingMapsReverseGeocoder.java @@ -0,0 +1,59 @@ +/* + * Copyright 2014 - 2015 Stefaan Van Dooren (stefaan.vandooren@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.geocoder; + +import javax.json.JsonArray; +import javax.json.JsonObject; + +public class BingMapsReverseGeocoder extends JsonReverseGeocoder { + + public BingMapsReverseGeocoder(String url, String key, int cacheSize) { + super(url + "/Locations/%f,%f?key=" + key + "&include=ciso2", cacheSize); + } + + @Override + public Address parseAddress(JsonObject json) { + JsonArray result = json.getJsonArray("resourceSets"); + if (result != null) { + JsonObject location = + result.getJsonObject(0).getJsonArray("resources").getJsonObject(0).getJsonObject("address"); + if (location != null) { + Address address = new Address(); + if (location.containsKey("addressLine")) { + address.setStreet(location.getString("addressLine")); + } + if (location.containsKey("locality")) { + address.setSettlement(location.getString("locality")); + } + if (location.containsKey("adminDistrict2")) { + address.setDistrict(location.getString("adminDistrict2")); + } + if (location.containsKey("adminDistrict")) { + address.setState(location.getString("adminDistrict")); + } + if (location.containsKey("countryRegionIso2")) { + address.setCountry(location.getString("countryRegionIso2").toUpperCase()); + } + if (location.containsKey("postalCode")) { + address.setPostcode(location.getString("postalCode")); + } + return address; + } + } + return null; + } + +} diff --git a/src/org/traccar/geocoder/FactualReverseGeocoder.java b/src/org/traccar/geocoder/FactualReverseGeocoder.java new file mode 100644 index 000000000..f1137893e --- /dev/null +++ b/src/org/traccar/geocoder/FactualReverseGeocoder.java @@ -0,0 +1,57 @@ +/* + * Copyright 2014 - 2015 Stefaan Van Dooren (stefaan.vandooren@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.geocoder; + +import javax.json.JsonObject; + +public class FactualReverseGeocoder extends JsonReverseGeocoder { + + public FactualReverseGeocoder(String url, String key, int cacheSize) { + super(url + "?latitude=%f&longitude=%f&KEY=" + key, cacheSize); + } + + @Override + public Address parseAddress(JsonObject json) { + JsonObject result = json.getJsonObject("response").getJsonObject("data"); + if (result != null) { + Address address = new Address(); + if (result.getJsonObject("street_number") != null) { + address.setHouse(result.getJsonObject("street_number").getString("name")); + } + if (result.getJsonObject("street_name") != null) { + address.setStreet(result.getJsonObject("street_name").getString("name")); + } + if (result.getJsonObject("locality") != null) { + address.setSettlement(result.getJsonObject("locality").getString("name")); + } + if (result.getJsonObject("county") != null) { + address.setDistrict(result.getJsonObject("county").getString("name")); + } + if (result.getJsonObject("region") != null) { + address.setState(result.getJsonObject("region").getString("name")); + } + if (result.getJsonObject("country") != null) { + address.setCountry(result.getJsonObject("country").getString("name")); + } + if (result.getJsonObject("postcode") != null) { + address.setPostcode(result.getJsonObject("postcode").getString("name")); + } + return address; + } + return null; + } + +} diff --git a/src/org/traccar/geocoder/GeocodeFarmReverseGeocoder.java b/src/org/traccar/geocoder/GeocodeFarmReverseGeocoder.java new file mode 100644 index 000000000..ca69a9026 --- /dev/null +++ b/src/org/traccar/geocoder/GeocodeFarmReverseGeocoder.java @@ -0,0 +1,61 @@ +/* + * Copyright 2016 Anton Tananaev (anton@traccar.org) + * + * 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.geocoder; + +import javax.json.JsonObject; + +public class GeocodeFarmReverseGeocoder extends JsonReverseGeocoder { + + private static final String URL = "https://www.geocode.farm/v3/json/reverse/"; + + public GeocodeFarmReverseGeocoder(int cacheSize) { + super(URL + "?lat=%f&lon=%f&country=us&lang=en&count=1", cacheSize); + } + + public GeocodeFarmReverseGeocoder(String key, int cacheSize) { + super(URL + "?lat=%f&lon=%f&country=us&lang=en&count=1&key=" + key, cacheSize); + } + + @Override + public Address parseAddress(JsonObject json) { + Address address = new Address(); + + JsonObject result = json + .getJsonObject("geocoding_results") + .getJsonArray("RESULTS") + .getJsonObject(0) + .getJsonObject("ADDRESS"); + + if (result.containsKey("street_number")) { + address.setStreet(result.getString("street_number")); + } + if (result.containsKey("street_name")) { + address.setStreet(result.getString("street_name")); + } + if (result.containsKey("locality")) { + address.setSettlement(result.getString("locality")); + } + if (result.containsKey("admin_1")) { + address.setState(result.getString("admin_1")); + } + if (result.containsKey("country")) { + address.setCountry(result.getString("country")); + } + + return address; + } + +} diff --git a/src/org/traccar/geocoder/GisgraphyReverseGeocoder.java b/src/org/traccar/geocoder/GisgraphyReverseGeocoder.java new file mode 100644 index 000000000..b656120d9 --- /dev/null +++ b/src/org/traccar/geocoder/GisgraphyReverseGeocoder.java @@ -0,0 +1,52 @@ +/* + * Copyright 2015 - 2016 Anton Tananaev (anton@traccar.org) + * + * 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.geocoder; + +import javax.json.JsonObject; + +public class GisgraphyReverseGeocoder extends JsonReverseGeocoder { + + public GisgraphyReverseGeocoder() { + this("http://services.gisgraphy.com/reversegeocoding/search", 0); + } + + public GisgraphyReverseGeocoder(String url, int cacheSize) { + super(url + "?format=json&lat=%f&lng=%f&from=1&to=1", cacheSize); + } + + @Override + public Address parseAddress(JsonObject json) { + Address address = new Address(); + + JsonObject result = json.getJsonArray("result").getJsonObject(0); + + if (result.containsKey("streetName")) { + address.setStreet(result.getString("streetName")); + } + if (result.containsKey("city")) { + address.setSettlement(result.getString("city")); + } + if (result.containsKey("state")) { + address.setState(result.getString("state")); + } + if (result.containsKey("countryCode")) { + address.setCountry(result.getString("countryCode")); + } + + return address; + } + +} diff --git a/src/org/traccar/geocoder/GoogleReverseGeocoder.java b/src/org/traccar/geocoder/GoogleReverseGeocoder.java new file mode 100644 index 000000000..f644079d3 --- /dev/null +++ b/src/org/traccar/geocoder/GoogleReverseGeocoder.java @@ -0,0 +1,86 @@ +/* + * Copyright 2012 - 2015 Anton Tananaev (anton@traccar.org) + * + * 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.geocoder; + +import javax.json.JsonArray; +import javax.json.JsonObject; +import javax.json.JsonString; + +public class GoogleReverseGeocoder extends JsonReverseGeocoder { + + public GoogleReverseGeocoder() { + this(0); + } + + public GoogleReverseGeocoder(int cacheSize) { + super("http://maps.googleapis.com/maps/api/geocode/json?latlng=%f,%f", cacheSize); + } + + public GoogleReverseGeocoder(String key, int cacheSize) { + super("https://maps.googleapis.com/maps/api/geocode/json?latlng=%f,%f&key=" + key, cacheSize); + } + + @Override + public Address parseAddress(JsonObject json) { + JsonArray results = json.getJsonArray("results"); + + if (!results.isEmpty()) { + Address address = new Address(); + + JsonObject result = (JsonObject) results.get(0); + JsonArray components = result.getJsonArray("address_components"); + + for (JsonObject component : components.getValuesAs(JsonObject.class)) { + + String value = component.getString("short_name"); + + typesLoop: for (JsonString type : component.getJsonArray("types").getValuesAs(JsonString.class)) { + + switch (type.getString()) { + case "street_number": + address.setHouse(value); + break typesLoop; + case "route": + address.setStreet(value); + break typesLoop; + case "locality": + address.setSettlement(value); + break typesLoop; + case "administrative_area_level_2": + address.setDistrict(value); + break typesLoop; + case "administrative_area_level_1": + address.setState(value); + break typesLoop; + case "country": + address.setCountry(value); + break typesLoop; + case "postal_code": + address.setPostcode(value); + break typesLoop; + default: + break; + } + } + } + + return address; + } + + return null; + } + +} diff --git a/src/org/traccar/geocoder/JsonReverseGeocoder.java b/src/org/traccar/geocoder/JsonReverseGeocoder.java new file mode 100644 index 000000000..808b7c83f --- /dev/null +++ b/src/org/traccar/geocoder/JsonReverseGeocoder.java @@ -0,0 +1,89 @@ +/* + * Copyright 2015 Anton Tananaev (anton@traccar.org) + * + * 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.geocoder; + +import com.ning.http.client.AsyncCompletionHandler; +import com.ning.http.client.Response; +import org.traccar.Context; + +import javax.json.Json; +import javax.json.JsonObject; +import javax.json.JsonReader; +import java.util.AbstractMap; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.Map; + +public abstract class JsonReverseGeocoder implements ReverseGeocoder { + + private final String url; + + private Map, String> cache; + + public JsonReverseGeocoder(String url, final int cacheSize) { + this.url = url; + if (cacheSize > 0) { + this.cache = Collections.synchronizedMap(new LinkedHashMap, String>() { + @Override + protected boolean removeEldestEntry(Map.Entry eldest) { + return size() > cacheSize; + } + }); + } + } + + @Override + public void getAddress( + final AddressFormat format, final double latitude, + final double longitude, final ReverseGeocoderCallback callback) { + + if (cache != null) { + String cachedAddress = cache.get(new AbstractMap.SimpleImmutableEntry<>(latitude, longitude)); + if (cachedAddress != null) { + callback.onSuccess(cachedAddress); + return; + } + } + + Context.getAsyncHttpClient().prepareGet(String.format(url, latitude, longitude)) + .execute(new AsyncCompletionHandler() { + @Override + public Object onCompleted(Response response) throws Exception { + try (JsonReader reader = Json.createReader(response.getResponseBodyAsStream())) { + Address address = parseAddress(reader.readObject()); + if (address != null) { + String formattedAddress = format.format(address); + if (cache != null) { + cache.put(new AbstractMap.SimpleImmutableEntry<>(latitude, longitude), formattedAddress); + } + callback.onSuccess(formattedAddress); + } else { + callback.onFailure(new IllegalArgumentException("Empty address")); + } + } + return null; + } + + @Override + public void onThrowable(Throwable t) { + callback.onFailure(t); + } + }); + } + + public abstract Address parseAddress(JsonObject json); + +} diff --git a/src/org/traccar/geocoder/MapQuestReverseGeocoder.java b/src/org/traccar/geocoder/MapQuestReverseGeocoder.java new file mode 100644 index 000000000..9c0a0e891 --- /dev/null +++ b/src/org/traccar/geocoder/MapQuestReverseGeocoder.java @@ -0,0 +1,62 @@ +/* + * Copyright 2014 - 2015 Stefaan Van Dooren (stefaan.vandooren@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.geocoder; + +import javax.json.JsonArray; +import javax.json.JsonObject; + +public class MapQuestReverseGeocoder extends JsonReverseGeocoder { + + public MapQuestReverseGeocoder(String url, String key, int cacheSize) { + super(url + "?key=" + key + "&location=%f,%f", cacheSize); + } + + @Override + public Address parseAddress(JsonObject json) { + JsonArray result = json.getJsonArray("results"); + if (result != null) { + JsonArray locations = result.getJsonObject(0).getJsonArray("locations"); + if (locations != null) { + JsonObject location = locations.getJsonObject(0); + + Address address = new Address(); + + if (location.containsKey("street")) { + address.setStreet(location.getString("street")); + } + if (location.containsKey("adminArea5")) { + address.setSettlement(location.getString("adminArea5")); + } + if (location.containsKey("adminArea4")) { + address.setDistrict(location.getString("adminArea4")); + } + if (location.containsKey("adminArea3")) { + address.setState(location.getString("adminArea3")); + } + if (location.containsKey("adminArea1")) { + address.setCountry(location.getString("adminArea1").toUpperCase()); + } + if (location.containsKey("postalCode")) { + address.setPostcode(location.getString("postalCode")); + } + + return address; + } + } + return null; + } + +} diff --git a/src/org/traccar/geocoder/NominatimReverseGeocoder.java b/src/org/traccar/geocoder/NominatimReverseGeocoder.java new file mode 100644 index 000000000..faeaf247f --- /dev/null +++ b/src/org/traccar/geocoder/NominatimReverseGeocoder.java @@ -0,0 +1,81 @@ +/* + * Copyright 2014 - 2015 Anton Tananaev (anton@traccar.org) + * + * 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.geocoder; + +import javax.json.JsonObject; + +public class NominatimReverseGeocoder extends JsonReverseGeocoder { + + public NominatimReverseGeocoder() { + this("http://nominatim.openstreetmap.org/reverse", 0); + } + + public NominatimReverseGeocoder(String url, int cacheSize) { + super(url + "?format=json&lat=%f&lon=%f&zoom=18&addressdetails=1", cacheSize); + } + + public NominatimReverseGeocoder(String url, String key, int cacheSize) { + super(url + "?format=json&lat=%f&lon=%f&zoom=18&addressdetails=1&key=" + key, cacheSize); + } + + @Override + public Address parseAddress(JsonObject json) { + JsonObject result = json.getJsonObject("address"); + + if (result != null) { + Address address = new Address(); + + if (result.containsKey("house_number")) { + address.setHouse(result.getString("house_number")); + } + if (result.containsKey("road")) { + address.setStreet(result.getString("road")); + } + if (result.containsKey("suburb")) { + address.setSuburb(result.getString("suburb")); + } + + if (result.containsKey("village")) { + address.setSettlement(result.getString("village")); + } else if (result.containsKey("town")) { + address.setSettlement(result.getString("town")); + } else if (result.containsKey("city")) { + address.setSettlement(result.getString("city")); + } + + if (result.containsKey("state_district")) { + address.setDistrict(result.getString("state_district")); + } else if (result.containsKey("region")) { + address.setDistrict(result.getString("region")); + } + + 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 address; + } + + return null; + } + +} diff --git a/src/org/traccar/geocoder/OpenCageReverseGeocoder.java b/src/org/traccar/geocoder/OpenCageReverseGeocoder.java new file mode 100644 index 000000000..a913a9288 --- /dev/null +++ b/src/org/traccar/geocoder/OpenCageReverseGeocoder.java @@ -0,0 +1,73 @@ +/* + * Copyright 2014 - 2015 Stefaan Van Dooren (stefaan.vandooren@gmail.com) + * Copyright 2016 Anton Tananaev (anton@traccar.org) + * + * 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.geocoder; + +import javax.json.JsonArray; +import javax.json.JsonObject; + +public class OpenCageReverseGeocoder extends JsonReverseGeocoder { + + public OpenCageReverseGeocoder(String url, String key, int cacheSize) { + super(url + "/json?q=%f,%f&key=" + key, cacheSize); + } + + @Override + public Address parseAddress(JsonObject json) { + JsonArray result = json.getJsonArray("results"); + if (result != null) { + JsonObject location = result.getJsonObject(0).getJsonObject("components"); + if (location != null) { + Address address = new Address(); + + if (location.containsKey("building")) { + address.setHouse(location.getString("building")); + } + if (location.containsKey("house_number")) { + address.setHouse(location.getString("house_number")); + } + if (location.containsKey("road")) { + address.setStreet(location.getString("road")); + } + if (location.containsKey("suburb")) { + address.setSuburb(location.getString("suburb")); + } + if (location.containsKey("city")) { + address.setSettlement(location.getString("city")); + } + if (location.containsKey("city_district")) { + address.setSettlement(location.getString("city_district")); + } + if (location.containsKey("county")) { + address.setDistrict(location.getString("county")); + } + if (location.containsKey("state")) { + address.setState(location.getString("state")); + } + if (location.containsKey("country_code")) { + address.setCountry(location.getString("country_code").toUpperCase()); + } + if (location.containsKey("postcode")) { + address.setPostcode(location.getString("postcode")); + } + + return address; + } + } + return null; + } + +} diff --git a/src/org/traccar/geocoder/ReverseGeocoder.java b/src/org/traccar/geocoder/ReverseGeocoder.java new file mode 100644 index 000000000..2f6d6d82b --- /dev/null +++ b/src/org/traccar/geocoder/ReverseGeocoder.java @@ -0,0 +1,30 @@ +/* + * Copyright 2012 - 2013 Anton Tananaev (anton@traccar.org) + * + * 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.geocoder; + +public interface ReverseGeocoder { + + interface ReverseGeocoderCallback { + + void onSuccess(String address); + + void onFailure(Throwable e); + + } + + void getAddress(AddressFormat format, double latitude, double longitude, ReverseGeocoderCallback callback); + +} diff --git a/test/org/traccar/geocode/AddressFormatTest.java b/test/org/traccar/geocode/AddressFormatTest.java deleted file mode 100644 index 325ae1433..000000000 --- a/test/org/traccar/geocode/AddressFormatTest.java +++ /dev/null @@ -1,32 +0,0 @@ -package org.traccar.geocode; - -import org.junit.Assert; -import org.junit.Test; - -public class AddressFormatTest { - - private void test(Address address, String format, String expected) { - Assert.assertEquals(expected, new AddressFormat(format).format(address)); - } - - @Test - public void testFormat() { - - Address address = new Address(); - address.setCountry("NZ"); - address.setSettlement("Auckland"); - address.setStreet("Queen St"); - address.setHouse("1A"); - - test(address, "%h %r %t %d %s %c %p", "1A Queen St Auckland NZ"); - test(address, "%h %r %t", "1A Queen St Auckland"); - test(address, "%h %r, %t", "1A Queen St, Auckland"); - test(address, "%h %r, %t %p", "1A Queen St, Auckland"); - test(address, "%t %d %c", "Auckland NZ"); - test(address, "%t, %d, %c", "Auckland, NZ"); - test(address, "%d %c", "NZ"); - test(address, "%d, %c", "NZ"); - test(address, "%p", ""); - } - -} diff --git a/test/org/traccar/geocode/ReverseGeocoderTest.java b/test/org/traccar/geocode/ReverseGeocoderTest.java deleted file mode 100644 index eab147cd5..000000000 --- a/test/org/traccar/geocode/ReverseGeocoderTest.java +++ /dev/null @@ -1,114 +0,0 @@ -package org.traccar.geocode; - -import org.junit.Assert; -import org.junit.Test; - -public class ReverseGeocoderTest { - - private boolean enable = false; - - @Test - public void test() throws InterruptedException { - if (enable) { - testGeocodeFarm(); - } - } - - private String address; - - private synchronized String waitAddress() { - try { - wait(5000); - return address; - } catch (InterruptedException e) { - throw new RuntimeException(e); - } - } - - private synchronized void setAddress(String address) { - this.address = address; - notifyAll(); - } - - public void testGoogle() throws InterruptedException { - ReverseGeocoder reverseGeocoder = new GoogleReverseGeocoder(); - - reverseGeocoder.getAddress(new AddressFormat(), 37.4217550, -122.0846330, new ReverseGeocoder.ReverseGeocoderCallback() { - @Override - public void onSuccess(String address) { - setAddress(address); - } - - @Override - public void onFailure(Throwable e) { - } - }); - Assert.assertEquals("1600 Amphitheatre Pkwy, Mountain View, CA, US", waitAddress()); - } - - public void testNominatim() throws InterruptedException { - ReverseGeocoder reverseGeocoder = new NominatimReverseGeocoder(); - - reverseGeocoder.getAddress(new AddressFormat(), 40.7337807, -73.9974401, new ReverseGeocoder.ReverseGeocoderCallback() { - @Override - public void onSuccess(String address) { - setAddress(address); - } - - @Override - public void onFailure(Throwable e) { - } - }); - Assert.assertEquals("35 West 9th Street, NYC, New York, US", waitAddress()); - } - - public void testGisgraphy() throws InterruptedException { - ReverseGeocoder reverseGeocoder = new GisgraphyReverseGeocoder(); - - reverseGeocoder.getAddress(new AddressFormat(), 48.8530000, 2.3400000, new ReverseGeocoder.ReverseGeocoderCallback() { - @Override - public void onSuccess(String address) { - setAddress(address); - } - - @Override - public void onFailure(Throwable e) { - } - }); - Assert.assertEquals("Rue du Jardinet, Paris, FR", waitAddress()); - } - - public void testOpenCage() throws InterruptedException { - ReverseGeocoder reverseGeocoder = new OpenCageReverseGeocoder( - "http://api.opencagedata.com/geocode/v1", "SECRET", 0); - - reverseGeocoder.getAddress(new AddressFormat(), 34.116302, -118.051519, new ReverseGeocoder.ReverseGeocoderCallback() { - @Override - public void onSuccess(String address) { - setAddress(address); - } - - @Override - public void onFailure(Throwable e) { - } - }); - Assert.assertEquals("Charleston Road, California, US", waitAddress()); - } - - public void testGeocodeFarm() throws InterruptedException { - ReverseGeocoder reverseGeocoder = new GeocodeFarmReverseGeocoder(0); - - reverseGeocoder.getAddress(new AddressFormat(), 34.116302, -118.051519, new ReverseGeocoder.ReverseGeocoderCallback() { - @Override - public void onSuccess(String address) { - setAddress(address); - } - - @Override - public void onFailure(Throwable e) { - } - }); - Assert.assertEquals("Estrella Avenue, Arcadia, California, United States", waitAddress()); - } - -} diff --git a/test/org/traccar/geocoder/AddressFormatTest.java b/test/org/traccar/geocoder/AddressFormatTest.java new file mode 100644 index 000000000..85bb44fd1 --- /dev/null +++ b/test/org/traccar/geocoder/AddressFormatTest.java @@ -0,0 +1,32 @@ +package org.traccar.geocoder; + +import org.junit.Assert; +import org.junit.Test; + +public class AddressFormatTest { + + private void test(Address address, String format, String expected) { + Assert.assertEquals(expected, new AddressFormat(format).format(address)); + } + + @Test + public void testFormat() { + + Address address = new Address(); + address.setCountry("NZ"); + address.setSettlement("Auckland"); + address.setStreet("Queen St"); + address.setHouse("1A"); + + test(address, "%h %r %t %d %s %c %p", "1A Queen St Auckland NZ"); + test(address, "%h %r %t", "1A Queen St Auckland"); + test(address, "%h %r, %t", "1A Queen St, Auckland"); + test(address, "%h %r, %t %p", "1A Queen St, Auckland"); + test(address, "%t %d %c", "Auckland NZ"); + test(address, "%t, %d, %c", "Auckland, NZ"); + test(address, "%d %c", "NZ"); + test(address, "%d, %c", "NZ"); + test(address, "%p", ""); + } + +} diff --git a/test/org/traccar/geocoder/ReverseGeocoderTest.java b/test/org/traccar/geocoder/ReverseGeocoderTest.java new file mode 100644 index 000000000..73753c96c --- /dev/null +++ b/test/org/traccar/geocoder/ReverseGeocoderTest.java @@ -0,0 +1,114 @@ +package org.traccar.geocoder; + +import org.junit.Assert; +import org.junit.Test; + +public class ReverseGeocoderTest { + + private boolean enable = false; + + @Test + public void test() throws InterruptedException { + if (enable) { + testGeocodeFarm(); + } + } + + private String address; + + private synchronized String waitAddress() { + try { + wait(5000); + return address; + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + + private synchronized void setAddress(String address) { + this.address = address; + notifyAll(); + } + + public void testGoogle() throws InterruptedException { + ReverseGeocoder reverseGeocoder = new GoogleReverseGeocoder(); + + reverseGeocoder.getAddress(new AddressFormat(), 37.4217550, -122.0846330, new ReverseGeocoder.ReverseGeocoderCallback() { + @Override + public void onSuccess(String address) { + setAddress(address); + } + + @Override + public void onFailure(Throwable e) { + } + }); + Assert.assertEquals("1600 Amphitheatre Pkwy, Mountain View, CA, US", waitAddress()); + } + + public void testNominatim() throws InterruptedException { + ReverseGeocoder reverseGeocoder = new NominatimReverseGeocoder(); + + reverseGeocoder.getAddress(new AddressFormat(), 40.7337807, -73.9974401, new ReverseGeocoder.ReverseGeocoderCallback() { + @Override + public void onSuccess(String address) { + setAddress(address); + } + + @Override + public void onFailure(Throwable e) { + } + }); + Assert.assertEquals("35 West 9th Street, NYC, New York, US", waitAddress()); + } + + public void testGisgraphy() throws InterruptedException { + ReverseGeocoder reverseGeocoder = new GisgraphyReverseGeocoder(); + + reverseGeocoder.getAddress(new AddressFormat(), 48.8530000, 2.3400000, new ReverseGeocoder.ReverseGeocoderCallback() { + @Override + public void onSuccess(String address) { + setAddress(address); + } + + @Override + public void onFailure(Throwable e) { + } + }); + Assert.assertEquals("Rue du Jardinet, Paris, FR", waitAddress()); + } + + public void testOpenCage() throws InterruptedException { + ReverseGeocoder reverseGeocoder = new OpenCageReverseGeocoder( + "http://api.opencagedata.com/geocode/v1", "SECRET", 0); + + reverseGeocoder.getAddress(new AddressFormat(), 34.116302, -118.051519, new ReverseGeocoder.ReverseGeocoderCallback() { + @Override + public void onSuccess(String address) { + setAddress(address); + } + + @Override + public void onFailure(Throwable e) { + } + }); + Assert.assertEquals("Charleston Road, California, US", waitAddress()); + } + + public void testGeocodeFarm() throws InterruptedException { + ReverseGeocoder reverseGeocoder = new GeocodeFarmReverseGeocoder(0); + + reverseGeocoder.getAddress(new AddressFormat(), 34.116302, -118.051519, new ReverseGeocoder.ReverseGeocoderCallback() { + @Override + public void onSuccess(String address) { + setAddress(address); + } + + @Override + public void onFailure(Throwable e) { + } + }); + Assert.assertEquals("Estrella Avenue, Arcadia, California, United States", waitAddress()); + } + +} -- cgit v1.2.3