From 3baeb26089a65ea7b65beedf2f3157dc2aab33a2 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 24 Jun 2012 16:10:33 +0400 Subject: Add reverse geocoding (fix #15) --- src/org/traccar/GenericPipelineFactory.java | 8 +++- src/org/traccar/GenericProtocolDecoder.java | 4 +- src/org/traccar/ReverseGeocoderHandler.java | 49 ++++++++++++++++++++++++ src/org/traccar/Server.java | 53 ++++++++++++++++---------- src/org/traccar/model/DatabaseDataManager.java | 1 + src/org/traccar/model/Position.java | 19 +++++++-- 6 files changed, 107 insertions(+), 27 deletions(-) create mode 100644 src/org/traccar/ReverseGeocoderHandler.java diff --git a/src/org/traccar/GenericPipelineFactory.java b/src/org/traccar/GenericPipelineFactory.java index 13a4cf6b6..c5e2cc812 100644 --- a/src/org/traccar/GenericPipelineFactory.java +++ b/src/org/traccar/GenericPipelineFactory.java @@ -19,6 +19,7 @@ import java.net.InetSocketAddress; import org.jboss.netty.buffer.ChannelBuffer; import org.jboss.netty.channel.*; import org.jboss.netty.handler.logging.LoggingHandler; +import org.traccar.geocode.ReverseGeocoder; import org.traccar.helper.Log; import org.traccar.model.DataManager; @@ -30,6 +31,7 @@ public abstract class GenericPipelineFactory implements ChannelPipelineFactory { private TrackerServer server; private DataManager dataManager; private Boolean loggerEnabled; + private ReverseGeocoder geocoder; /** * Open channel handler @@ -84,10 +86,11 @@ public abstract class GenericPipelineFactory implements ChannelPipelineFactory { } public GenericPipelineFactory( - TrackerServer server, DataManager dataManager, Boolean loggerEnabled) { + TrackerServer server, DataManager dataManager, Boolean loggerEnabled, ReverseGeocoder geocoder) { this.server = server; this.dataManager = dataManager; this.loggerEnabled = loggerEnabled; + this.geocoder = geocoder; } protected DataManager getDataManager() { @@ -103,6 +106,9 @@ public abstract class GenericPipelineFactory implements ChannelPipelineFactory { pipeline.addLast("logger", new StandardLoggingHandler()); } addSpecificHandlers(pipeline); + if (geocoder != null) { + pipeline.addLast("geocoder", new ReverseGeocoderHandler(geocoder)); + } pipeline.addLast("handler", new TrackerEventHandler(dataManager)); return pipeline; } diff --git a/src/org/traccar/GenericProtocolDecoder.java b/src/org/traccar/GenericProtocolDecoder.java index c2e7992bd..b6755f95e 100644 --- a/src/org/traccar/GenericProtocolDecoder.java +++ b/src/org/traccar/GenericProtocolDecoder.java @@ -37,7 +37,7 @@ public abstract class GenericProtocolDecoder extends OneToOneDecoder { public final void setDataManager(DataManager dataManager) { this.dataManager = dataManager; } - + /** * Return data manager */ @@ -70,7 +70,7 @@ public abstract class GenericProtocolDecoder extends OneToOneDecoder { setDataManager(dataManager); setResetDelay(resetDelay); } - + /** * Disconnect channel */ diff --git a/src/org/traccar/ReverseGeocoderHandler.java b/src/org/traccar/ReverseGeocoderHandler.java new file mode 100644 index 000000000..a7123bcec --- /dev/null +++ b/src/org/traccar/ReverseGeocoderHandler.java @@ -0,0 +1,49 @@ +/* + * Copyright 2012 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; + +import org.jboss.netty.channel.ChannelHandlerContext; +import org.jboss.netty.channel.MessageEvent; +import org.jboss.netty.channel.SimpleChannelHandler; +import org.traccar.geocode.ReverseGeocoder; +import org.traccar.model.Position; + +/** + * Reverse geocoding channel event handler + */ +public class ReverseGeocoderHandler extends SimpleChannelHandler { + + /** + * Geocoder object + */ + private ReverseGeocoder geocoder; + + public ReverseGeocoderHandler(ReverseGeocoder geocoder) { + this.geocoder = geocoder; + } + + @Override + public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) { + if (e.getMessage() instanceof Position) { + Position position = (Position) e.getMessage(); + if (geocoder != null) { + position.setAddress(geocoder.getAddress( + position.getLatitude(), position.getLongitude())); + } + } + } + +} diff --git a/src/org/traccar/Server.java b/src/org/traccar/Server.java index 81a1988d1..7167f6080 100644 --- a/src/org/traccar/Server.java +++ b/src/org/traccar/Server.java @@ -34,6 +34,8 @@ import org.jboss.netty.handler.codec.frame.DelimiterBasedFrameDecoder; import org.jboss.netty.handler.codec.frame.LengthFieldBasedFrameDecoder; import org.jboss.netty.handler.codec.string.StringDecoder; import org.jboss.netty.handler.codec.string.StringEncoder; +import org.traccar.geocode.GoogleReverseGeocoder; +import org.traccar.geocode.ReverseGeocoder; import org.traccar.helper.Log; import org.traccar.http.WebServer; import org.traccar.model.DataManager; @@ -65,6 +67,8 @@ public class Server { private WebServer webServer; + private ReverseGeocoder geocoder; + /** * Initialize */ @@ -80,6 +84,7 @@ public class Server { dataManager = new DatabaseDataManager(properties); initLogger(properties); + initGeocoder(properties); initXexunServer(properties); initGps103Server(properties); @@ -133,7 +138,7 @@ public class Server { /** * Initialize logger */ - public void initLogger(Properties properties) throws IOException { + private void initLogger(Properties properties) throws IOException { loggerEnabled = Boolean.valueOf(properties.getProperty("logger.enable")); @@ -168,6 +173,12 @@ public class Server { } } + private void initGeocoder(Properties properties) throws IOException { + if (Boolean.parseBoolean("geocoder.enable")) { + geocoder = new GoogleReverseGeocoder(); + } + } + private boolean isProtocolEnabled(Properties properties, String protocol) { String enabled = properties.getProperty(protocol + ".enable"); if (enabled != null) { @@ -195,7 +206,7 @@ public class Server { /** * Init Xexun server */ - public void initXexunServer(Properties properties) throws SQLException { + private void initXexunServer(Properties properties) throws SQLException { String protocol = "xexun"; if (isProtocolEnabled(properties, protocol)) { @@ -203,7 +214,7 @@ public class Server { TrackerServer server = new TrackerServer(getProtocolPort(properties, protocol)); final Integer resetDelay = getProtocolResetDelay(properties, protocol); - server.setPipelineFactory(new GenericPipelineFactory(server, dataManager, isLoggerEnabled()) { + server.setPipelineFactory(new GenericPipelineFactory(server, dataManager, isLoggerEnabled(), geocoder) { protected void addSpecificHandlers(ChannelPipeline pipeline) { pipeline.addLast("frameDecoder", new XexunFrameDecoder()); pipeline.addLast("stringDecoder", new StringDecoder()); @@ -218,7 +229,7 @@ public class Server { /** * Init Gps103 server */ - public void initGps103Server(Properties properties) throws SQLException { + private void initGps103Server(Properties properties) throws SQLException { String protocol = "gps103"; if (isProtocolEnabled(properties, protocol)) { @@ -226,7 +237,7 @@ public class Server { TrackerServer server = new TrackerServer(getProtocolPort(properties, protocol)); final Integer resetDelay = getProtocolResetDelay(properties, protocol); - server.setPipelineFactory(new GenericPipelineFactory(server, dataManager, isLoggerEnabled()) { + server.setPipelineFactory(new GenericPipelineFactory(server, dataManager, isLoggerEnabled(), geocoder) { protected void addSpecificHandlers(ChannelPipeline pipeline) { byte delimiter[] = { (byte) ';' }; pipeline.addLast("frameDecoder", @@ -244,7 +255,7 @@ public class Server { /** * Init Tk103 server */ - public void initTk103Server(Properties properties) throws SQLException { + private void initTk103Server(Properties properties) throws SQLException { String protocol = "tk103"; if (isProtocolEnabled(properties, protocol)) { @@ -252,7 +263,7 @@ public class Server { TrackerServer server = new TrackerServer(getProtocolPort(properties, protocol)); final Integer resetDelay = getProtocolResetDelay(properties, protocol); - server.setPipelineFactory(new GenericPipelineFactory(server, dataManager, isLoggerEnabled()) { + server.setPipelineFactory(new GenericPipelineFactory(server, dataManager, isLoggerEnabled(), geocoder) { protected void addSpecificHandlers(ChannelPipeline pipeline) { byte delimiter[] = { (byte) ')' }; pipeline.addLast("frameDecoder", @@ -270,7 +281,7 @@ public class Server { /** * Init Gl100 server */ - public void initGl100Server(Properties properties) throws SQLException { + private void initGl100Server(Properties properties) throws SQLException { String protocol = "gl100"; if (isProtocolEnabled(properties, protocol)) { @@ -278,7 +289,7 @@ public class Server { TrackerServer server = new TrackerServer(getProtocolPort(properties, protocol)); final Integer resetDelay = getProtocolResetDelay(properties, protocol); - server.setPipelineFactory(new GenericPipelineFactory(server, dataManager, isLoggerEnabled()) { + server.setPipelineFactory(new GenericPipelineFactory(server, dataManager, isLoggerEnabled(), geocoder) { protected void addSpecificHandlers(ChannelPipeline pipeline) { byte delimiter[] = { (byte) 0x0 }; pipeline.addLast("frameDecoder", @@ -296,7 +307,7 @@ public class Server { /** * Init Gl200 server */ - public void initGl200Server(Properties properties) throws SQLException { + private void initGl200Server(Properties properties) throws SQLException { String protocol = "gl200"; if (isProtocolEnabled(properties, protocol)) { @@ -304,7 +315,7 @@ public class Server { TrackerServer server = new TrackerServer(getProtocolPort(properties, protocol)); final Integer resetDelay = getProtocolResetDelay(properties, protocol); - server.setPipelineFactory(new GenericPipelineFactory(server, dataManager, isLoggerEnabled()) { + server.setPipelineFactory(new GenericPipelineFactory(server, dataManager, isLoggerEnabled(), geocoder) { protected void addSpecificHandlers(ChannelPipeline pipeline) { byte delimiter[] = { (byte) '$' }; pipeline.addLast("frameDecoder", @@ -322,7 +333,7 @@ public class Server { /** * Init T55 server */ - public void initT55Server(Properties properties) throws SQLException { + private void initT55Server(Properties properties) throws SQLException { String protocol = "t55"; if (isProtocolEnabled(properties, protocol)) { @@ -330,7 +341,7 @@ public class Server { TrackerServer server = new TrackerServer(getProtocolPort(properties, protocol)); final Integer resetDelay = getProtocolResetDelay(properties, protocol); - server.setPipelineFactory(new GenericPipelineFactory(server, dataManager, isLoggerEnabled()) { + server.setPipelineFactory(new GenericPipelineFactory(server, dataManager, isLoggerEnabled(), geocoder) { protected void addSpecificHandlers(ChannelPipeline pipeline) { byte delimiter[] = { (byte) '\r', (byte) '\n' }; pipeline.addLast("frameDecoder", @@ -348,7 +359,7 @@ public class Server { /** * Init Xexun 2 server */ - public void initXexun2Server(Properties properties) throws SQLException { + private void initXexun2Server(Properties properties) throws SQLException { String protocol = "xexun2"; if (isProtocolEnabled(properties, protocol)) { @@ -356,7 +367,7 @@ public class Server { TrackerServer server = new TrackerServer(getProtocolPort(properties, protocol)); final Integer resetDelay = getProtocolResetDelay(properties, protocol); - server.setPipelineFactory(new GenericPipelineFactory(server, dataManager, isLoggerEnabled()) { + server.setPipelineFactory(new GenericPipelineFactory(server, dataManager, isLoggerEnabled(), geocoder) { protected void addSpecificHandlers(ChannelPipeline pipeline) { byte delimiter[] = { (byte) '\n' }; // tracker bug \n\r pipeline.addLast("frameDecoder", @@ -373,7 +384,7 @@ public class Server { /** * Init AVL-08 server */ - public void initAvl08Server(Properties properties) throws SQLException { + private void initAvl08Server(Properties properties) throws SQLException { String protocol = "avl08"; if (isProtocolEnabled(properties, protocol)) { @@ -381,7 +392,7 @@ public class Server { TrackerServer server = new TrackerServer(getProtocolPort(properties, protocol)); final Integer resetDelay = getProtocolResetDelay(properties, protocol); - server.setPipelineFactory(new GenericPipelineFactory(server, dataManager, isLoggerEnabled()) { + server.setPipelineFactory(new GenericPipelineFactory(server, dataManager, isLoggerEnabled(), geocoder) { protected void addSpecificHandlers(ChannelPipeline pipeline) { byte delimiter[] = { (byte) '\r', (byte) '\n' }; pipeline.addLast("frameDecoder", @@ -398,7 +409,7 @@ public class Server { /** * Init Enfora server */ - public void initEnforaServer(Properties properties) throws SQLException { + private void initEnforaServer(Properties properties) throws SQLException { String protocol = "enfora"; if (isProtocolEnabled(properties, protocol)) { @@ -406,7 +417,7 @@ public class Server { TrackerServer server = new TrackerServer(getProtocolPort(properties, protocol)); final Integer resetDelay = getProtocolResetDelay(properties, protocol); - server.setPipelineFactory(new GenericPipelineFactory(server, dataManager, isLoggerEnabled()) { + server.setPipelineFactory(new GenericPipelineFactory(server, dataManager, isLoggerEnabled(), geocoder) { protected void addSpecificHandlers(ChannelPipeline pipeline) { pipeline.addLast("frameDecoder", new LengthFieldBasedFrameDecoder(1024, 0, 2, -2, 2)); pipeline.addLast("objectDecoder", new EnforaProtocolDecoder(getDataManager(), resetDelay)); @@ -420,7 +431,7 @@ public class Server { /** * Init Meiligao server */ - public void initMeiligaoServer(Properties properties) throws SQLException { + private void initMeiligaoServer(Properties properties) throws SQLException { String protocol = "meiligao"; if (isProtocolEnabled(properties, protocol)) { @@ -428,7 +439,7 @@ public class Server { TrackerServer server = new TrackerServer(getProtocolPort(properties, protocol)); final Integer resetDelay = getProtocolResetDelay(properties, protocol); - server.setPipelineFactory(new GenericPipelineFactory(server, dataManager, isLoggerEnabled()) { + server.setPipelineFactory(new GenericPipelineFactory(server, dataManager, isLoggerEnabled(), geocoder) { protected void addSpecificHandlers(ChannelPipeline pipeline) { pipeline.addLast("frameDecoder", new LengthFieldBasedFrameDecoder(1024, 2, 2, -4, 4)); pipeline.addLast("objectDecoder", new MeiligaoProtocolDecoder(getDataManager(), resetDelay)); diff --git a/src/org/traccar/model/DatabaseDataManager.java b/src/org/traccar/model/DatabaseDataManager.java index 8235a6170..f312c3dcd 100644 --- a/src/org/traccar/model/DatabaseDataManager.java +++ b/src/org/traccar/model/DatabaseDataManager.java @@ -229,6 +229,7 @@ public class DatabaseDataManager implements DataManager { queryAddPosition.setDouble("speed", position.getSpeed()); queryAddPosition.setDouble("course", position.getCourse()); queryAddPosition.setDouble("power", position.getPower()); + queryAddPosition.setString("address", position.getAddress()); queryAddPosition.setString("extended_info", position.getExtendedInfo()); queryAddPosition.executeUpdate(); diff --git a/src/org/traccar/model/Position.java b/src/org/traccar/model/Position.java index d2de726b1..b408dbbf2 100644 --- a/src/org/traccar/model/Position.java +++ b/src/org/traccar/model/Position.java @@ -26,7 +26,7 @@ public class Position { * Id */ private Long id; - + public Long getId() { return id; } @@ -99,12 +99,12 @@ public class Position { public void setLongitude(Double longitude) { this.longitude = longitude; } - + /** * Altitude */ private Double altitude; - + public Double getAltitude() { return altitude; } @@ -152,6 +152,19 @@ public class Position { this.power = power; } + /** + * Address + */ + private String address; + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + /** * Extended information in XML format */ -- cgit v1.2.3