diff options
author | Anton Tananaev <anton.tananaev@gmail.com> | 2019-02-24 15:12:26 -0800 |
---|---|---|
committer | Anton Tananaev <anton.tananaev@gmail.com> | 2019-02-24 15:12:26 -0800 |
commit | d610b1ab5135503d1d39aa291190a860ddb952a9 (patch) | |
tree | 9742ce6f0fede6bb9bfa523d4ab5f59a9945dcc1 | |
parent | 78e8a550b66691bd61204698d43e82d958fce517 (diff) | |
download | traccar-server-d610b1ab5135503d1d39aa291190a860ddb952a9.tar.gz traccar-server-d610b1ab5135503d1d39aa291190a860ddb952a9.tar.bz2 traccar-server-d610b1ab5135503d1d39aa291190a860ddb952a9.zip |
Refactor geocoder handler
-rw-r--r-- | src/org/traccar/BasePipelineFactory.java | 10 | ||||
-rw-r--r-- | src/org/traccar/Context.java | 65 | ||||
-rw-r--r-- | src/org/traccar/MainEventHandler.java | 1 | ||||
-rw-r--r-- | src/org/traccar/MainModule.java | 57 | ||||
-rw-r--r-- | src/org/traccar/config/Keys.java | 68 | ||||
-rw-r--r-- | src/org/traccar/handler/GeocoderHandler.java (renamed from src/org/traccar/GeocoderHandler.java) | 32 |
6 files changed, 151 insertions, 82 deletions
diff --git a/src/org/traccar/BasePipelineFactory.java b/src/org/traccar/BasePipelineFactory.java index 082d666ac..8e6a62391 100644 --- a/src/org/traccar/BasePipelineFactory.java +++ b/src/org/traccar/BasePipelineFactory.java @@ -38,6 +38,7 @@ import org.traccar.handler.ComputedAttributesHandler; import org.traccar.handler.CopyAttributesHandler; import org.traccar.handler.DistanceHandler; import org.traccar.handler.FilterHandler; +import org.traccar.handler.GeocoderHandler; import org.traccar.handler.GeolocationHandler; import org.traccar.handler.HemisphereHandler; import org.traccar.handler.NetworkMessageHandler; @@ -56,7 +57,6 @@ public abstract class BasePipelineFactory extends ChannelInitializer<Channel> { private EngineHoursHandler engineHoursHandler; private MotionHandler motionHandler; - private GeocoderHandler geocoderHandler; private CopyAttributesHandler copyAttributesHandler; private ComputedAttributesHandler computedAttributesHandler; @@ -78,12 +78,6 @@ public abstract class BasePipelineFactory extends ChannelInitializer<Channel> { timeout = Context.getConfig().getInteger(Keys.SERVER_TIMEOUT); } - if (Context.getGeocoder() != null && !Context.getConfig().getBoolean("geocoder.ignorePositions")) { - geocoderHandler = new GeocoderHandler( - Context.getGeocoder(), - Context.getConfig().getBoolean("geocoder.processInvalidPositions")); - } - motionHandler = new MotionHandler(Context.getTripsConfig().getSpeedThreshold()); if (Context.getConfig().getBoolean("processing.engineHours.enable")) { @@ -170,7 +164,7 @@ public abstract class BasePipelineFactory extends ChannelInitializer<Channel> { addHandlers( pipeline, Main.getInjector().getInstance(FilterHandler.class), - geocoderHandler, + Main.getInjector().getInstance(GeocoderHandler.class), motionHandler, engineHoursHandler, copyAttributesHandler, diff --git a/src/org/traccar/Context.java b/src/org/traccar/Context.java index e507406e8..2f8432645 100644 --- a/src/org/traccar/Context.java +++ b/src/org/traccar/Context.java @@ -43,20 +43,7 @@ import org.traccar.database.PermissionsManager; import org.traccar.database.UsersManager; import org.traccar.events.MotionEventHandler; import org.traccar.events.OverspeedEventHandler; -import org.traccar.geocoder.AddressFormat; -import org.traccar.geocoder.BanGeocoder; -import org.traccar.geocoder.BingMapsGeocoder; -import org.traccar.geocoder.FactualGeocoder; -import org.traccar.geocoder.GeocodeFarmGeocoder; -import org.traccar.geocoder.GeocodeXyzGeocoder; import org.traccar.geocoder.Geocoder; -import org.traccar.geocoder.GisgraphyGeocoder; -import org.traccar.geocoder.GoogleGeocoder; -import org.traccar.geocoder.HereGeocoder; -import org.traccar.geocoder.MapQuestGeocoder; -import org.traccar.geocoder.MapmyIndiaGeocoder; -import org.traccar.geocoder.NominatimGeocoder; -import org.traccar.geocoder.OpenCageGeocoder; import org.traccar.helper.Log; import org.traccar.helper.SanitizerModule; import org.traccar.model.Attribute; @@ -164,10 +151,8 @@ public final class Context { return permissionsManager; } - private static Geocoder geocoder; - public static Geocoder getGeocoder() { - return geocoder; + return Main.getInjector() != null ? Main.getInjector().getInstance(Geocoder.class) : null; } private static WebServer webServer; @@ -292,50 +277,6 @@ public final class Context { } - public static Geocoder initGeocoder() { - String type = config.getString("geocoder.type", "google"); - String url = config.getString("geocoder.url"); - String id = config.getString("geocoder.id"); - String key = config.getString("geocoder.key"); - String language = config.getString("geocoder.language"); - - String formatString = config.getString("geocoder.format"); - AddressFormat addressFormat; - if (formatString != null) { - addressFormat = new AddressFormat(formatString); - } else { - addressFormat = new AddressFormat(); - } - - int cacheSize = config.getInteger("geocoder.cacheSize"); - switch (type) { - case "nominatim": - return new NominatimGeocoder(url, key, language, cacheSize, addressFormat); - case "gisgraphy": - return new GisgraphyGeocoder(url, cacheSize, addressFormat); - case "mapquest": - return new MapQuestGeocoder(url, key, cacheSize, addressFormat); - case "opencage": - return new OpenCageGeocoder(url, key, cacheSize, addressFormat); - case "bingmaps": - return new BingMapsGeocoder(url, key, cacheSize, addressFormat); - case "factual": - return new FactualGeocoder(url, key, cacheSize, addressFormat); - case "geocodefarm": - return new GeocodeFarmGeocoder(key, language, cacheSize, addressFormat); - case "geocodexyz": - return new GeocodeXyzGeocoder(key, cacheSize, addressFormat); - case "ban": - return new BanGeocoder(cacheSize, addressFormat); - case "here": - return new HereGeocoder(id, key, language, cacheSize, addressFormat); - case "mapmyindia": - return new MapmyIndiaGeocoder(url, key, cacheSize, addressFormat); - default: - return new GoogleGeocoder(key, language, cacheSize, addressFormat); - } - } - public static void init(String configFile) throws Exception { try { @@ -381,10 +322,6 @@ public final class Context { identityManager = deviceManager; - if (config.getBoolean("geocoder.enable")) { - geocoder = initGeocoder(); - } - if (config.getBoolean("web.enable")) { webServer = new WebServer(config); } diff --git a/src/org/traccar/MainEventHandler.java b/src/org/traccar/MainEventHandler.java index 1137bfc24..80c05e3c7 100644 --- a/src/org/traccar/MainEventHandler.java +++ b/src/org/traccar/MainEventHandler.java @@ -24,6 +24,7 @@ import io.netty.handler.timeout.IdleStateEvent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.database.StatisticsManager; +import org.traccar.handler.GeocoderHandler; import org.traccar.helper.DateUtil; import org.traccar.model.Position; diff --git a/src/org/traccar/MainModule.java b/src/org/traccar/MainModule.java index 0e5c7d858..c6ca65088 100644 --- a/src/org/traccar/MainModule.java +++ b/src/org/traccar/MainModule.java @@ -24,6 +24,20 @@ import org.traccar.config.Keys; import org.traccar.database.DataManager; import org.traccar.database.IdentityManager; import org.traccar.database.StatisticsManager; +import org.traccar.geocoder.AddressFormat; +import org.traccar.geocoder.BanGeocoder; +import org.traccar.geocoder.BingMapsGeocoder; +import org.traccar.geocoder.FactualGeocoder; +import org.traccar.geocoder.GeocodeFarmGeocoder; +import org.traccar.geocoder.GeocodeXyzGeocoder; +import org.traccar.geocoder.Geocoder; +import org.traccar.geocoder.GisgraphyGeocoder; +import org.traccar.geocoder.GoogleGeocoder; +import org.traccar.geocoder.HereGeocoder; +import org.traccar.geocoder.MapQuestGeocoder; +import org.traccar.geocoder.MapmyIndiaGeocoder; +import org.traccar.geocoder.NominatimGeocoder; +import org.traccar.geocoder.OpenCageGeocoder; import org.traccar.geolocation.GeolocationProvider; import org.traccar.geolocation.GoogleGeolocationProvider; import org.traccar.geolocation.MozillaGeolocationProvider; @@ -73,6 +87,49 @@ public class MainModule extends AbstractModule { @Singleton @Provides + public static Geocoder provideGeocoder(Config config) { + if (config.getBoolean(Keys.GEOCODER_ENABLE)) { + String type = config.getString(Keys.GEOCODER_TYPE, "google"); + String url = config.getString(Keys.GEOCODER_URL); + String id = config.getString(Keys.GEOCODER_ID); + String key = config.getString(Keys.GEOCODER_KEY); + String language = config.getString(Keys.GEOCODER_LANGUAGE); + String formatString = config.getString(Keys.GEOCODER_FORMAT); + AddressFormat addressFormat = formatString != null ? new AddressFormat(formatString) : new AddressFormat(); + + int cacheSize = config.getInteger(Keys.GEOCODER_CACHE_SIZE); + switch (type) { + case "nominatim": + return new NominatimGeocoder(url, key, language, cacheSize, addressFormat); + case "gisgraphy": + return new GisgraphyGeocoder(url, cacheSize, addressFormat); + case "mapquest": + return new MapQuestGeocoder(url, key, cacheSize, addressFormat); + case "opencage": + return new OpenCageGeocoder(url, key, cacheSize, addressFormat); + case "bingmaps": + return new BingMapsGeocoder(url, key, cacheSize, addressFormat); + case "factual": + return new FactualGeocoder(url, key, cacheSize, addressFormat); + case "geocodefarm": + return new GeocodeFarmGeocoder(key, language, cacheSize, addressFormat); + case "geocodexyz": + return new GeocodeXyzGeocoder(key, cacheSize, addressFormat); + case "ban": + return new BanGeocoder(cacheSize, addressFormat); + case "here": + return new HereGeocoder(id, key, language, cacheSize, addressFormat); + case "mapmyindia": + return new MapmyIndiaGeocoder(url, key, cacheSize, addressFormat); + default: + return new GoogleGeocoder(key, language, cacheSize, addressFormat); + } + } + return null; + } + + @Singleton + @Provides public static GeolocationProvider provideGeolocationProvider(Config config) { if (config.getBoolean(Keys.GEOLOCATION_ENABLE)) { String type = config.getString(Keys.GEOLOCATION_TYPE, "mozilla"); diff --git a/src/org/traccar/config/Keys.java b/src/org/traccar/config/Keys.java index fddc70bba..7449bfdf5 100644 --- a/src/org/traccar/config/Keys.java +++ b/src/org/traccar/config/Keys.java @@ -180,6 +180,74 @@ public final class Keys { "processing.remoteAddress.enable", Boolean.class); /** + * Boolean flag to enable or disable reverse geocoder. + */ + public static final ConfigKey GEOCODER_ENABLE = new ConfigKey( + "geocoder.enable", Boolean.class); + + /** + * Reverse geocoder type. Check reverse geocoding documentation for more info. By default (if the value is not + * specified) server uses Google API. + */ + public static final ConfigKey GEOCODER_TYPE = new ConfigKey( + "geocoder.type", String.class); + + /** + * Geocoder server URL. Applicable only to Nominatim and Gisgraphy providers. + */ + public static final ConfigKey GEOCODER_URL = new ConfigKey( + "geocoder.url", String.class); + + /** + * App id for use with Here provider. + */ + public static final ConfigKey GEOCODER_ID = new ConfigKey( + "geocoder.id", String.class); + + /** + * Provider API key. Most providers require API keys. + */ + public static final ConfigKey GEOCODER_KEY = new ConfigKey( + "geocoder.key", String.class); + + /** + * Language parameter for providers that support localization (e.g. Google and Nominatim). + */ + public static final ConfigKey GEOCODER_LANGUAGE = new ConfigKey( + "geocoder.language", String.class); + + /** + * Address format string. Default value is %h %r, %t, %s, %c. See AddressFormat for more info. + */ + public static final ConfigKey GEOCODER_FORMAT = new ConfigKey( + "geocoder.format", String.class); + + /** + * Cache size for geocoding results. + */ + public static final ConfigKey GEOCODER_CACHE_SIZE = new ConfigKey( + "geocoder.cacheSize", Integer.class); + + /** + * Disable automatic reverse geocoding requests for all positions. + */ + public static final ConfigKey GEOCODER_IGNORE_POSITIONS = new ConfigKey( + "geocoder.ignorePositions", Boolean.class); + + /** + * Boolean flag to apply reverse geocoding to invalid positions. + */ + public static final ConfigKey GEOCODER_PROCESS_INVALID_POSITIONS = new ConfigKey( + "geocoder.processInvalidPositions", Boolean.class); + + /** + * Optional parameter to specify minimum distance for new reverse geocoding request. If distance is less than + * specified value (in meters), then Traccar will reuse last known address. + */ + public static final ConfigKey GEOCODER_REUSE_DISTANCE = new ConfigKey( + "geocoder.reuseDistance", Integer.class); + + /** * Boolean flag to enable LBS location resolution. Some devices send cell towers information and WiFi point when GPS * location is not available. Traccar can determine coordinates based on that information using third party * services. Default value is false. diff --git a/src/org/traccar/GeocoderHandler.java b/src/org/traccar/handler/GeocoderHandler.java index 4154e287c..b96f01b3a 100644 --- a/src/org/traccar/GeocoderHandler.java +++ b/src/org/traccar/handler/GeocoderHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 2019 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. @@ -13,13 +13,17 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.traccar; +package org.traccar.handler; import io.netty.channel.ChannelHandler; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.traccar.Context; +import org.traccar.config.Config; +import org.traccar.config.Keys; +import org.traccar.database.IdentityManager; import org.traccar.database.StatisticsManager; import org.traccar.geocoder.Geocoder; import org.traccar.model.Position; @@ -30,23 +34,29 @@ public class GeocoderHandler extends ChannelInboundHandlerAdapter { private static final Logger LOGGER = LoggerFactory.getLogger(GeocoderHandler.class); private final Geocoder geocoder; + private final IdentityManager identityManager; + private final StatisticsManager statisticsManager; + private final boolean ignorePositions; private final boolean processInvalidPositions; private final int geocoderReuseDistance; - public GeocoderHandler(Geocoder geocoder, boolean processInvalidPositions) { + public GeocoderHandler( + Config config, Geocoder geocoder, IdentityManager identityManager, StatisticsManager statisticsManager) { this.geocoder = geocoder; - this.processInvalidPositions = processInvalidPositions; - - geocoderReuseDistance = Context.getConfig().getInteger("geocoder.reuseDistance", 0); + this.identityManager = identityManager; + this.statisticsManager = statisticsManager; + ignorePositions = Context.getConfig().getBoolean(Keys.GEOCODER_IGNORE_POSITIONS); + processInvalidPositions = config.getBoolean(Keys.GEOCODER_PROCESS_INVALID_POSITIONS); + geocoderReuseDistance = config.getInteger(Keys.GEOCODER_REUSE_DISTANCE, 0); } @Override - public void channelRead(final ChannelHandlerContext ctx, Object message) throws Exception { - if (message instanceof Position) { + public void channelRead(final ChannelHandlerContext ctx, Object message) { + if (message instanceof Position && !ignorePositions) { final Position position = (Position) message; if (processInvalidPositions || position.getValid()) { if (geocoderReuseDistance != 0) { - Position lastPosition = Context.getIdentityManager().getLastPosition(position.getDeviceId()); + Position lastPosition = identityManager.getLastPosition(position.getDeviceId()); if (lastPosition != null && lastPosition.getAddress() != null && position.getDouble(Position.KEY_DISTANCE) <= geocoderReuseDistance) { position.setAddress(lastPosition.getAddress()); @@ -55,7 +65,9 @@ public class GeocoderHandler extends ChannelInboundHandlerAdapter { } } - Main.getInjector().getInstance(StatisticsManager.class).registerGeocoderRequest(); + if (statisticsManager != null) { + statisticsManager.registerGeocoderRequest(); + } geocoder.getAddress(position.getLatitude(), position.getLongitude(), new Geocoder.ReverseGeocoderCallback() { |