aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--debug.xml4
-rw-r--r--src/org/traccar/BasePipelineFactory.java9
-rw-r--r--src/org/traccar/DistanceHandler.java59
-rw-r--r--src/org/traccar/model/Event.java1
-rw-r--r--test/org/traccar/DistanceHandlerTest.java22
-rw-r--r--web/app/store/DistanceUnits.js20
-rw-r--r--web/app/store/SpeedUnits.js4
-rw-r--r--web/app/view/report/Report.js1
-rw-r--r--web/app/view/state/StateController.js17
9 files changed, 128 insertions, 9 deletions
diff --git a/debug.xml b/debug.xml
index 85cdb46b8..ceee553ce 100644
--- a/debug.xml
+++ b/debug.xml
@@ -18,13 +18,15 @@
<entry key='geocoder.type'>nominatim</entry>
<entry key='geocoder.url'>http://nominatim.openstreetmap.org/reverse</entry>
+ <entry key='distance.enable'>true</entry>
+
<!--<entry key='filter.enable'>true</entry>
<entry key='filter.limit'>3600</entry>
<entry key='filter.invalid'>true</entry>
<entry key='filter.zero'>true</entry>
<entry key='filter.duplicate'>true</entry>
<entry key='filter.distance'>50</entry>-->
-
+
<!--<entry key='forward.enable'>true</entry>
<entry key='forward.url'>http://example.com:8080/gprmc/Data?id={uniqueId}&amp;code=0x0000&amp;gprmc={gprmc}</entry>-->
diff --git a/src/org/traccar/BasePipelineFactory.java b/src/org/traccar/BasePipelineFactory.java
index 4d8b0ffc4..216e48709 100644
--- a/src/org/traccar/BasePipelineFactory.java
+++ b/src/org/traccar/BasePipelineFactory.java
@@ -25,7 +25,6 @@ import org.jboss.netty.channel.ChannelPipelineFactory;
import org.jboss.netty.channel.ChannelStateEvent;
import org.jboss.netty.channel.Channels;
import org.jboss.netty.channel.DownstreamMessageEvent;
-import org.jboss.netty.channel.ExceptionEvent;
import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.channel.SimpleChannelHandler;
import org.jboss.netty.handler.logging.LoggingHandler;
@@ -38,6 +37,7 @@ public abstract class BasePipelineFactory implements ChannelPipelineFactory {
private int resetDelay;
private FilterHandler filterHandler;
+ private DistanceHandler distanceHandler;
private ReverseGeocoderHandler reverseGeocoderHandler;
protected class OpenChannelHandler extends SimpleChannelHandler {
@@ -96,6 +96,10 @@ public abstract class BasePipelineFactory implements ChannelPipelineFactory {
reverseGeocoderHandler = new ReverseGeocoderHandler(
Context.getReverseGeocoder(), Context.getConfig().getBoolean("geocode.processInvalidPositions"));
}
+
+ if (Context.getConfig().getBoolean("distance.enable")) {
+ distanceHandler = new DistanceHandler();
+ }
}
protected abstract void addSpecificHandlers(ChannelPipeline pipeline);
@@ -114,6 +118,9 @@ public abstract class BasePipelineFactory implements ChannelPipelineFactory {
if (filterHandler != null) {
pipeline.addLast("filter", filterHandler);
}
+ if (distanceHandler != null) {
+ pipeline.addLast("distance", distanceHandler);
+ }
if (reverseGeocoderHandler != null) {
pipeline.addLast("geocoder", reverseGeocoderHandler);
}
diff --git a/src/org/traccar/DistanceHandler.java b/src/org/traccar/DistanceHandler.java
new file mode 100644
index 000000000..57dddfe87
--- /dev/null
+++ b/src/org/traccar/DistanceHandler.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2015 Amila Silva
+ *
+ * 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.traccar.helper.DistanceCalculator;
+import org.traccar.model.Event;
+import org.traccar.model.Position;
+
+import java.math.BigDecimal;
+
+public class DistanceHandler extends BaseDataHandler {
+
+ private Position getLastPosition(long deviceId) {
+ if (Context.getConnectionManager() != null) {
+ return Context.getConnectionManager().getLastPosition(deviceId);
+ }
+ return null;
+ }
+
+ public Position calculateDistance(Position position) {
+
+ double distance = 0.0;
+
+ Position last = getLastPosition(position.getDeviceId());
+ if (last != null) {
+ if (last.getOther().containsKey(Event.KEY_DISTANCE)) {
+ distance = ((Number) last.getOther().get(Event.KEY_DISTANCE)).doubleValue();
+ }
+
+ distance += DistanceCalculator.distance(
+ position.getLatitude(), position.getLongitude(),
+ last.getLatitude(), last.getLongitude());
+
+ distance = BigDecimal.valueOf(distance).setScale(2).doubleValue();
+ }
+
+ position.set(Event.KEY_DISTANCE, distance);
+ return position;
+ }
+
+ @Override
+ protected Position handlePosition(Position position) {
+ return calculateDistance(position);
+ }
+
+}
diff --git a/src/org/traccar/model/Event.java b/src/org/traccar/model/Event.java
index df9a9a8e5..831ae31b3 100644
--- a/src/org/traccar/model/Event.java
+++ b/src/org/traccar/model/Event.java
@@ -78,6 +78,7 @@ public abstract class Event {
public static final String KEY_CHARGE = "charge";
public static final String KEY_IP = "ip";
public static final String KEY_ARCHIVE = "archive";
+ public static final String KEY_DISTANCE = "distance";
// Starts with 1 not 0
public static final String PREFIX_TEMP = "temp";
diff --git a/test/org/traccar/DistanceHandlerTest.java b/test/org/traccar/DistanceHandlerTest.java
new file mode 100644
index 000000000..8afeb83f0
--- /dev/null
+++ b/test/org/traccar/DistanceHandlerTest.java
@@ -0,0 +1,22 @@
+package org.traccar;
+
+import org.junit.Test;
+import org.traccar.model.Event;
+import org.traccar.model.Position;
+
+import static org.junit.Assert.assertEquals;
+
+public class DistanceHandlerTest {
+
+ @Test
+ public void testCalculateDistance() throws Exception {
+
+ DistanceHandler distanceHandler = new DistanceHandler();
+
+ Position position = distanceHandler.calculateDistance(new Position());
+
+ assertEquals(0.0, position.getOther().get(Event.KEY_DISTANCE));
+
+ }
+
+}
diff --git a/web/app/store/DistanceUnits.js b/web/app/store/DistanceUnits.js
index 506f1077c..653bf6efb 100644
--- a/web/app/store/DistanceUnits.js
+++ b/web/app/store/DistanceUnits.js
@@ -20,5 +20,23 @@ Ext.define('Traccar.store.DistanceUnits', {
data: [
{'key': 'km', 'name': strings.sharedKm},
{'key': 'mi', 'name': strings.sharedMi}
- ]
+ ],
+
+ convert: function(value, unit) {
+ switch (unit) {
+ case 'km':
+ return Math.round(value * 0.1) / 100;
+ case 'mi':
+ return Math.round(value * 0.0621371) / 100;
+ }
+ return value;
+ },
+
+ getUnitName: function(unit) {
+ if (unit) {
+ return this.findRecord('key', unit).get('name');
+ } else {
+ return '';
+ }
+ }
});
diff --git a/web/app/store/SpeedUnits.js b/web/app/store/SpeedUnits.js
index 78686fbb9..15c52625f 100644
--- a/web/app/store/SpeedUnits.js
+++ b/web/app/store/SpeedUnits.js
@@ -25,9 +25,9 @@ Ext.define('Traccar.store.SpeedUnits', {
convert: function(value, unit) {
switch (unit) {
case 'kmh':
- return value * 1.852;
+ return Math.round(value * 1.852 * 10) / 10;
case 'mph':
- return value * 1.15078;
+ return Math.round(value * 1.15078 * 10) / 10;
}
return value;
},
diff --git a/web/app/view/report/Report.js b/web/app/view/report/Report.js
index ff8cc7b3d..535be942b 100644
--- a/web/app/view/report/Report.js
+++ b/web/app/view/report/Report.js
@@ -90,7 +90,6 @@ Ext.define('Traccar.view.report.Report', {
return speedUnits.convert(value, unit) + ' ' + speedUnits.getUnitName(unit);
}
},
- { text: strings.positionCourse, dataIndex: 'course', flex: 1 },
{ text: strings.positionAddress, dataIndex: 'address', flex: 1 }
]
diff --git a/web/app/view/state/StateController.js b/web/app/view/state/StateController.js
index 58b63120b..58bc5c55c 100644
--- a/web/app/view/state/StateController.js
+++ b/web/app/view/state/StateController.js
@@ -76,17 +76,20 @@ Ext.define('Traccar.view.state.StateController', {
updatePosition: function(position) {
var other;
+ var value;
+ var unit;
var store = Ext.getStore('Parameters');
store.removeAll();
for (var key in position.data) {
if (position.data.hasOwnProperty(key) && this.keys[key] !== undefined) {
- var value = position.get(key);
+ value = position.get(key);
if (key === 'speed') {
var speedUnits = Ext.getStore('SpeedUnits');
- var unit = Traccar.getApplication().getUser().get('speedUnit') || Traccar.getApplication().getServer().get('speedUnit') || '';
+ unit = Traccar.getApplication().getUser().get('speedUnit') || Traccar.getApplication().getServer().get('speedUnit') || '';
value = speedUnits.convert(value, unit) + ' ' + speedUnits.getUnitName(unit);
}
+
store.add(Ext.create('Traccar.model.Parameter', {
priority: this.keys[key].priority,
name: this.keys[key].name,
@@ -103,12 +106,20 @@ Ext.define('Traccar.view.state.StateController', {
}
for (var key in other) {
if (other.hasOwnProperty(key)) {
+
+ value = other[key];
+ if (key === 'distance' || key === 'odometer') {
+ var distanceUnits = Ext.getStore('DistanceUnits');
+ unit = Traccar.getApplication().getUser().get('distanceUnit') || Traccar.getApplication().getServer().get('distanceUnit') || '';
+ value = distanceUnits.convert(value, unit) + ' ' + distanceUnits.getUnitName(unit);
+ }
+
store.add(Ext.create('Traccar.model.Parameter', {
priority: 999,
name: key.replace(/^./, function (match) {
return match.toUpperCase();
}),
- value: other[key]
+ value: value
}));
}
}