From 87f6ffa67c2cd4b3e7ce72ed7257ea15526c0052 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 21 Sep 2015 10:07:27 +1200 Subject: Implement geocoder address caching --- src/org/traccar/Context.java | 7 +++--- .../traccar/geocode/GisgraphyReverseGeocoder.java | 6 ++--- src/org/traccar/geocode/GoogleReverseGeocoder.java | 6 ++++- src/org/traccar/geocode/JsonReverseGeocoder.java | 29 ++++++++++++++++++++-- .../traccar/geocode/NominatimReverseGeocoder.java | 6 ++--- 5 files changed, 42 insertions(+), 12 deletions(-) (limited to 'src/org/traccar') diff --git a/src/org/traccar/Context.java b/src/org/traccar/Context.java index 7b364d799..a25f2f65e 100644 --- a/src/org/traccar/Context.java +++ b/src/org/traccar/Context.java @@ -109,15 +109,16 @@ public class Context { if (config.getBoolean("geocoder.enable")) { String type = config.getString("geocoder.type", "google"); String url = config.getString("geocoder.url"); + int cacheSize = config.getInteger("geocoder.cacheSize"); switch (type) { case "google": - reverseGeocoder = new GoogleReverseGeocoder(); + reverseGeocoder = new GoogleReverseGeocoder(cacheSize); break; case "nominatim": - reverseGeocoder = new NominatimReverseGeocoder(url); + reverseGeocoder = new NominatimReverseGeocoder(url, cacheSize); break; case "gisgraphy": - reverseGeocoder = new GisgraphyReverseGeocoder(url); + reverseGeocoder = new GisgraphyReverseGeocoder(url, cacheSize); break; } } diff --git a/src/org/traccar/geocode/GisgraphyReverseGeocoder.java b/src/org/traccar/geocode/GisgraphyReverseGeocoder.java index 392a11e66..6e0e5a343 100644 --- a/src/org/traccar/geocode/GisgraphyReverseGeocoder.java +++ b/src/org/traccar/geocode/GisgraphyReverseGeocoder.java @@ -26,11 +26,11 @@ import java.net.URLConnection; public class GisgraphyReverseGeocoder extends JsonReverseGeocoder { public GisgraphyReverseGeocoder() { - this("http://services.gisgraphy.com/street/streetsearch"); + this("http://services.gisgraphy.com/street/streetsearch", 0); } - public GisgraphyReverseGeocoder(String url) { - super(url + "?format=json&lat=%f&lng=%f&from=1&to=1"); + public GisgraphyReverseGeocoder(String url, int cacheSize) { + super(url + "?format=json&lat=%f&lng=%f&from=1&to=1", cacheSize); } @Override diff --git a/src/org/traccar/geocode/GoogleReverseGeocoder.java b/src/org/traccar/geocode/GoogleReverseGeocoder.java index c37d4188f..667436cbe 100644 --- a/src/org/traccar/geocode/GoogleReverseGeocoder.java +++ b/src/org/traccar/geocode/GoogleReverseGeocoder.java @@ -22,7 +22,11 @@ import javax.json.JsonString; public class GoogleReverseGeocoder extends JsonReverseGeocoder { public GoogleReverseGeocoder() { - super("http://maps.googleapis.com/maps/api/geocode/json?latlng=%f,%f"); + this(0); + } + + public GoogleReverseGeocoder(int cacheSize) { + super("http://maps.googleapis.com/maps/api/geocode/json?latlng=%f,%f", cacheSize); } @Override diff --git a/src/org/traccar/geocode/JsonReverseGeocoder.java b/src/org/traccar/geocode/JsonReverseGeocoder.java index c43641245..442b8551c 100644 --- a/src/org/traccar/geocode/JsonReverseGeocoder.java +++ b/src/org/traccar/geocode/JsonReverseGeocoder.java @@ -25,18 +25,37 @@ import java.io.Reader; import java.net.HttpURLConnection; import java.net.URL; import java.net.URLConnection; +import java.util.AbstractMap; +import java.util.LinkedHashMap; +import java.util.Map; public abstract class JsonReverseGeocoder implements ReverseGeocoder { private final String url; - public JsonReverseGeocoder(String url) { + private Map, String> cache; + + public JsonReverseGeocoder(String url, final int cacheSize) { this.url = url; + if (cacheSize > 0) { + this.cache = new LinkedHashMap, String>() { + protected boolean removeEldestEntry(Map.Entry eldest) { + return size() > cacheSize; + } + }; + } } @Override public String getAddress(AddressFormat format, double latitude, double longitude) { + if (cache != null) { + String cachedAddress = cache.get(new AbstractMap.SimpleImmutableEntry<>(latitude, longitude)); + if (cachedAddress != null) { + return cachedAddress; + } + } + try { HttpURLConnection conn = (HttpURLConnection) new URL(String.format(url, latitude, longitude)).openConnection(); conn.setRequestProperty("Connection", "close"); // don't keep-alive connections @@ -46,7 +65,13 @@ public abstract class JsonReverseGeocoder implements ReverseGeocoder { Address address = parseAddress(reader.readObject()); while (streamReader.read() > 0); // make sure we reached the end if (address != null) { - return format.format(address); + String formattedAddress = format.format(address); + + if (cache != null) { + cache.put(new AbstractMap.SimpleImmutableEntry<>(latitude, longitude), formattedAddress); + } + + return formattedAddress; } } } finally { diff --git a/src/org/traccar/geocode/NominatimReverseGeocoder.java b/src/org/traccar/geocode/NominatimReverseGeocoder.java index 27c241c66..96c9a993d 100644 --- a/src/org/traccar/geocode/NominatimReverseGeocoder.java +++ b/src/org/traccar/geocode/NominatimReverseGeocoder.java @@ -30,11 +30,11 @@ import org.w3c.dom.Document; public class NominatimReverseGeocoder extends JsonReverseGeocoder { public NominatimReverseGeocoder() { - this("http://nominatim.openstreetmap.org/reverse"); + this("http://nominatim.openstreetmap.org/reverse", 0); } - public NominatimReverseGeocoder(String url) { - super(url + "?format=json&lat=%f&lon=%f&zoom=18&addressdetails=1"); + public NominatimReverseGeocoder(String url, int cacheSize) { + super(url + "?format=json&lat=%f&lon=%f&zoom=18&addressdetails=1", cacheSize); } @Override -- cgit v1.2.3