aboutsummaryrefslogtreecommitdiff
path: root/src/org/traccar/geocoder
diff options
context:
space:
mode:
Diffstat (limited to 'src/org/traccar/geocoder')
-rw-r--r--src/org/traccar/geocoder/Address.java100
-rw-r--r--src/org/traccar/geocoder/AddressFormat.java80
-rw-r--r--src/org/traccar/geocoder/BingMapsReverseGeocoder.java59
-rw-r--r--src/org/traccar/geocoder/FactualReverseGeocoder.java57
-rw-r--r--src/org/traccar/geocoder/GeocodeFarmReverseGeocoder.java61
-rw-r--r--src/org/traccar/geocoder/GisgraphyReverseGeocoder.java52
-rw-r--r--src/org/traccar/geocoder/GoogleReverseGeocoder.java86
-rw-r--r--src/org/traccar/geocoder/JsonReverseGeocoder.java89
-rw-r--r--src/org/traccar/geocoder/MapQuestReverseGeocoder.java62
-rw-r--r--src/org/traccar/geocoder/NominatimReverseGeocoder.java81
-rw-r--r--src/org/traccar/geocoder/OpenCageReverseGeocoder.java73
-rw-r--r--src/org/traccar/geocoder/ReverseGeocoder.java30
12 files changed, 830 insertions, 0 deletions
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<Map.Entry<Double, Double>, String> cache;
+
+ public JsonReverseGeocoder(String url, final int cacheSize) {
+ this.url = url;
+ if (cacheSize > 0) {
+ this.cache = Collections.synchronizedMap(new LinkedHashMap<Map.Entry<Double, Double>, 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);
+
+}