diff options
author | Anton Tananaev <anton.tananaev@gmail.com> | 2015-05-07 15:39:42 +1200 |
---|---|---|
committer | Anton Tananaev <anton.tananaev@gmail.com> | 2015-05-07 15:39:42 +1200 |
commit | 953852e6e984f8a639cf1a5ac4116fff755d538a (patch) | |
tree | 1902beb226bfa2ba7b60b20a310b376e8e86ce76 /src/org/traccar | |
parent | 6a07fc479021dbf61143d432285c573faf38d6b9 (diff) | |
download | traccar-server-953852e6e984f8a639cf1a5ac4116fff755d538a.tar.gz traccar-server-953852e6e984f8a639cf1a5ac4116fff755d538a.tar.bz2 traccar-server-953852e6e984f8a639cf1a5ac4116fff755d538a.zip |
Add Gisgraphy reverse geocoder
Diffstat (limited to 'src/org/traccar')
-rw-r--r-- | src/org/traccar/Context.java | 3 | ||||
-rw-r--r-- | src/org/traccar/ReverseGeocoderHandler.java | 7 | ||||
-rw-r--r-- | src/org/traccar/geocode/AddressFormat.java | 4 | ||||
-rw-r--r-- | src/org/traccar/geocode/GisgraphyReverseGeocoder.java | 67 | ||||
-rw-r--r-- | src/org/traccar/geocode/GoogleReverseGeocoder.java | 62 | ||||
-rw-r--r-- | src/org/traccar/geocode/NominatimReverseGeocoder.java | 49 | ||||
-rw-r--r-- | src/org/traccar/geocode/ReverseGeocoder.java | 2 |
7 files changed, 161 insertions, 33 deletions
diff --git a/src/org/traccar/Context.java b/src/org/traccar/Context.java index a180a64ab..ca45a34d6 100644 --- a/src/org/traccar/Context.java +++ b/src/org/traccar/Context.java @@ -17,6 +17,7 @@ package org.traccar; import org.traccar.database.DataCache; import org.traccar.database.DataManager; +import org.traccar.geocode.GisgraphyReverseGeocoder; import org.traccar.geocode.GoogleReverseGeocoder; import org.traccar.geocode.NominatimReverseGeocoder; import org.traccar.geocode.ReverseGeocoder; @@ -97,6 +98,8 @@ public class Context { String type = properties.getProperty("geocoder.type"); if (type != null && type.equals("nominatim")) { reverseGeocoder = new NominatimReverseGeocoder(properties.getProperty("geocoder.url")); + } if (type != null && type.equals("gisgraphy")) { + reverseGeocoder = new GisgraphyReverseGeocoder(properties.getProperty("geocoder.url")); } else { reverseGeocoder = new GoogleReverseGeocoder(); } diff --git a/src/org/traccar/ReverseGeocoderHandler.java b/src/org/traccar/ReverseGeocoderHandler.java index e48a11424..73254673c 100644 --- a/src/org/traccar/ReverseGeocoderHandler.java +++ b/src/org/traccar/ReverseGeocoderHandler.java @@ -19,6 +19,7 @@ import java.util.List; import org.jboss.netty.channel.Channel; import org.jboss.netty.channel.ChannelHandlerContext; import org.jboss.netty.handler.codec.oneone.OneToOneDecoder; +import org.traccar.geocode.AddressFormat; import org.traccar.geocode.ReverseGeocoder; import org.traccar.model.Event; import org.traccar.model.Position; @@ -27,10 +28,12 @@ public class ReverseGeocoderHandler extends OneToOneDecoder { private final ReverseGeocoder geocoder; private final boolean processInvalidPositions; + private final AddressFormat addressFormat; public ReverseGeocoderHandler(ReverseGeocoder geocoder, boolean processInvalidPositions ) { this.geocoder = geocoder; this.processInvalidPositions = processInvalidPositions; + addressFormat = new AddressFormat(); } @Override @@ -44,14 +47,14 @@ public class ReverseGeocoderHandler extends OneToOneDecoder { if (processInvalidPositions || position.getValid()) { position.setAddress(geocoder.getAddress( - position.getLatitude(), position.getLongitude())); + addressFormat, position.getLatitude(), position.getLongitude())); } } else if (msg instanceof List) { List<Position> positions = (List<Position>) msg; for (Position position : positions) { if (processInvalidPositions || position.getValid()) { position.setAddress(geocoder.getAddress( - position.getLatitude(), position.getLongitude())); + addressFormat, position.getLatitude(), position.getLongitude())); } } } diff --git a/src/org/traccar/geocode/AddressFormat.java b/src/org/traccar/geocode/AddressFormat.java index 972326975..a90de8c5e 100644 --- a/src/org/traccar/geocode/AddressFormat.java +++ b/src/org/traccar/geocode/AddressFormat.java @@ -35,6 +35,10 @@ public class AddressFormat extends Format { private final String format; + public AddressFormat() { + this("%h %r, %t, %s, %c"); + } + public AddressFormat(String format) { this.format = format; } diff --git a/src/org/traccar/geocode/GisgraphyReverseGeocoder.java b/src/org/traccar/geocode/GisgraphyReverseGeocoder.java new file mode 100644 index 000000000..9d513a6f5 --- /dev/null +++ b/src/org/traccar/geocode/GisgraphyReverseGeocoder.java @@ -0,0 +1,67 @@ +/* + * Copyright 2015 Anton Tananaev (anton.tananaev@gmail.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.geocode; + +import org.traccar.helper.Log; + +import javax.json.Json; +import javax.json.JsonObject; +import java.io.InputStreamReader; +import java.net.URL; +import java.net.URLConnection; + +public class GisgraphyReverseGeocoder implements ReverseGeocoder { + + private final String url; + + public GisgraphyReverseGeocoder() { + this("http://services.gisgraphy.com/street/streetsearch"); + } + + public GisgraphyReverseGeocoder(String url) { + this.url = url + "?format=json&lat=%f&lng=%f&from=1&to=1"; + } + + @Override + public String getAddress(AddressFormat format, double latitude, double longitude) { + + try { + Address address = new Address(); + URLConnection conn = new URL(String.format(url, latitude, longitude)).openConnection(); + + JsonObject json = Json.createReader(new InputStreamReader(conn.getInputStream())).readObject(); + JsonObject result = json.getJsonArray("result").getJsonObject(0); + + if (result.containsKey("name")) { + address.setStreet(result.getString("name")); + } + if (result.containsKey("isIn")) { + address.setSettlement(result.getString("isIn")); + } + if (result.containsKey("countryCode")) { + address.setCountry(result.getString("countryCode")); + } + + return format.format(address); + + } catch(Exception error) { + Log.warning(error); + } + + return null; + } + +} diff --git a/src/org/traccar/geocode/GoogleReverseGeocoder.java b/src/org/traccar/geocode/GoogleReverseGeocoder.java index 4ec6e10af..dae9915d8 100644 --- a/src/org/traccar/geocode/GoogleReverseGeocoder.java +++ b/src/org/traccar/geocode/GoogleReverseGeocoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 - 2013 Anton Tananaev (anton.tananaev@gmail.com) + * Copyright 2012 - 2015 Anton Tananaev (anton.tananaev@gmail.com) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,42 +15,62 @@ */ package org.traccar.geocode; -import java.io.BufferedReader; -import java.io.IOException; import java.io.InputStreamReader; import java.net.URL; import java.net.URLConnection; -import java.nio.charset.Charset; import org.traccar.helper.Log; +import javax.json.*; + public class GoogleReverseGeocoder implements ReverseGeocoder { - private final static String MARKER = "\"formatted_address\" : \""; + private final String url = "http://maps.googleapis.com/maps/api/geocode/json?latlng=%f,%f"; @Override - public String getAddress(double latitude, double longitude) { + public String getAddress(AddressFormat format, double latitude, double longitude) { try { - URL url = new URL("http://maps.googleapis.com/maps/api/geocode/json?latlng=" + latitude + "," + longitude + "&sensor=false"); - URLConnection connection = url.openConnection(); - - connection.setRequestProperty("Content-Type", "application/json;charset=UTF-8"); - - BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream(),Charset.forName("UTF-8"))); - - // Find address line - String line; - while ((line = reader.readLine()) != null) { - int index = line.indexOf(MARKER); - if (index != -1) { - return line.substring(index + MARKER.length(), line.length() - 2); + Address address = new Address(); + URLConnection conn = new URL(String.format(url, latitude, longitude)).openConnection(); + + JsonObject json = Json.createReader(new InputStreamReader(conn.getInputStream())).readObject(); + JsonObject result = (JsonObject) json.getJsonArray("results").get(0); + JsonArray components = result.getJsonArray("address_components"); + + for (JsonObject component : components.getValuesAs(JsonObject.class)) { + + String value = component.getString("short_name"); + + for (JsonString type : component.getJsonArray("types").getValuesAs(JsonString.class)) { + if (type.getString().equals("street_number")) { + address.setHouse(value); + break; + } else if (type.getString().equals("route")) { + address.setStreet(value); + break; + } else if (type.getString().equals("locality")) { + address.setSettlement(value); + break; + } else if (type.getString().equals("administrative_area_level_2")) { + address.setDistrict(value); + break; + } else if (type.getString().equals("administrative_area_level_1")) { + address.setState(value); + break; + } else if (type.getString().equals("country")) { + address.setCountry(value); + break; + } else if (type.getString().equals("postal_code")) { + address.setPostcode(value); + break; + } } } - reader.close(); + return format.format(address); - } catch(IOException error) { + } catch(Exception error) { Log.warning(error); } diff --git a/src/org/traccar/geocode/NominatimReverseGeocoder.java b/src/org/traccar/geocode/NominatimReverseGeocoder.java index c9393da42..911e0fa71 100644 --- a/src/org/traccar/geocode/NominatimReverseGeocoder.java +++ b/src/org/traccar/geocode/NominatimReverseGeocoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2014 Anton Tananaev (anton.tananaev@gmail.com) + * Copyright 2014 - 2015 Anton Tananaev (anton.tananaev@gmail.com) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,8 +15,12 @@ */ package org.traccar.geocode; +import java.io.InputStreamReader; import java.net.URL; import java.net.URLConnection; +import javax.json.Json; +import javax.json.JsonArray; +import javax.json.JsonObject; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; @@ -26,23 +30,50 @@ import org.w3c.dom.Document; public class NominatimReverseGeocoder implements ReverseGeocoder { private final String url; + + public NominatimReverseGeocoder() { + this("http://nominatim.openstreetmap.org/reverse"); + } public NominatimReverseGeocoder(String url) { - this.url = url + "?format=xml&lat=%f&lon=%f&zoom=18&addressdetails=0"; + this.url = url + "?format=json&lat=%f&lon=%f&zoom=18&addressdetails=1"; } @Override - public String getAddress(double latitude, double longitude) { + public String getAddress(AddressFormat format, double latitude, double longitude) { try { - + Address address = new Address(); URLConnection conn = new URL(String.format(url, latitude, longitude)).openConnection(); - DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); - DocumentBuilder builder = factory.newDocumentBuilder(); - Document doc = builder.parse(conn.getInputStream()); - - return doc.getFirstChild().getLastChild().getFirstChild().getNodeValue(); + JsonObject json = Json.createReader(new InputStreamReader(conn.getInputStream())).readObject().getJsonObject("address"); + + if (json.containsKey("house_number")) { + address.setHouse(json.getString("house_number")); + } + if (json.containsKey("road")) { + address.setStreet(json.getString("road")); + } + if (json.containsKey("village")) { + address.setSettlement(json.getString("village")); + } + if (json.containsKey("city")) { + address.setSettlement(json.getString("city")); + } + if (json.containsKey("state_district")) { + address.setDistrict(json.getString("state_district")); + } + if (json.containsKey("state")) { + address.setState(json.getString("state")); + } + if (json.containsKey("country_code")) { + address.setCountry(json.getString("country_code").toUpperCase()); + } + if (json.containsKey("postcode")) { + address.setPostcode(json.getString("postcode")); + } + + return format.format(address); } catch(Exception error) { Log.warning(error); diff --git a/src/org/traccar/geocode/ReverseGeocoder.java b/src/org/traccar/geocode/ReverseGeocoder.java index 67ce68ac2..b19a6b7ce 100644 --- a/src/org/traccar/geocode/ReverseGeocoder.java +++ b/src/org/traccar/geocode/ReverseGeocoder.java @@ -17,6 +17,6 @@ package org.traccar.geocode; public interface ReverseGeocoder { - public String getAddress(double latitude, double longitude); + public String getAddress(AddressFormat format, double latitude, double longitude); } |