diff options
author | Anton Tananaev <anton.tananaev@gmail.com> | 2018-05-11 14:22:21 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-05-11 14:22:21 -0700 |
commit | 662b774234298c38a38c172d1dcb4668996045ac (patch) | |
tree | 7f46a605aabd630d3f07b7ec6f7d8713ed3be2ce | |
parent | a97c12829e99b63f1951bffc658c37ec180e5379 (diff) | |
parent | 3639bc6d289fa137d5dc7aaa47b67cd6a6bcc47d (diff) | |
download | trackermap-server-662b774234298c38a38c172d1dcb4668996045ac.tar.gz trackermap-server-662b774234298c38a38c172d1dcb4668996045ac.tar.bz2 trackermap-server-662b774234298c38a38c172d1dcb4668996045ac.zip |
Merge pull request #3870 from Abyss777/geo_overspeed
Add basic support of overspeeding inside geofences.
-rw-r--r-- | src/org/traccar/Context.java | 3 | ||||
-rw-r--r-- | src/org/traccar/events/OverspeedEventHandler.java | 41 | ||||
-rw-r--r-- | src/org/traccar/model/DeviceState.java | 10 | ||||
-rw-r--r-- | templates/mail/deviceOverspeed.vm | 2 | ||||
-rw-r--r-- | templates/sms/deviceOverspeed.vm | 2 | ||||
-rw-r--r-- | test/org/traccar/events/OverspeedEventHandlerTest.java | 29 |
6 files changed, 70 insertions, 17 deletions
diff --git a/src/org/traccar/Context.java b/src/org/traccar/Context.java index ee14eb1f7..23d0a983e 100644 --- a/src/org/traccar/Context.java +++ b/src/org/traccar/Context.java @@ -464,7 +464,8 @@ public final class Context { motionEventHandler = new MotionEventHandler(tripsConfig); overspeedEventHandler = new OverspeedEventHandler( Context.getConfig().getLong("event.overspeed.minimalDuration") * 1000, - Context.getConfig().getBoolean("event.overspeed.notRepeat")); + Context.getConfig().getBoolean("event.overspeed.notRepeat"), + Context.getConfig().getBoolean("event.overspeed.preferLowest")); } public static void init(IdentityManager testIdentityManager) { diff --git a/src/org/traccar/events/OverspeedEventHandler.java b/src/org/traccar/events/OverspeedEventHandler.java index cb658415c..4ebe43fda 100644 --- a/src/org/traccar/events/OverspeedEventHandler.java +++ b/src/org/traccar/events/OverspeedEventHandler.java @@ -1,5 +1,6 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2018 Andrey Kunitsyn (andrey@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,6 +24,7 @@ import org.traccar.Context; import org.traccar.model.Device; import org.traccar.model.DeviceState; import org.traccar.model.Event; +import org.traccar.model.Geofence; import org.traccar.model.Position; public class OverspeedEventHandler extends BaseEventHandler { @@ -30,11 +32,13 @@ public class OverspeedEventHandler extends BaseEventHandler { public static final String ATTRIBUTE_SPEED_LIMIT = "speedLimit"; private boolean notRepeat; + private boolean preferLowest; private long minimalDuration; - public OverspeedEventHandler(long minimalDuration, boolean notRepeat) { + public OverspeedEventHandler(long minimalDuration, boolean notRepeat, boolean preferLowest) { this.notRepeat = notRepeat; this.minimalDuration = minimalDuration; + this.preferLowest = preferLowest; } private Map<Event, Position> newEvent(DeviceState deviceState, double speedLimit) { @@ -42,8 +46,10 @@ public class OverspeedEventHandler extends BaseEventHandler { Event event = new Event(Event.TYPE_DEVICE_OVERSPEED, position.getDeviceId(), position.getId()); event.set("speed", deviceState.getOverspeedPosition().getSpeed()); event.set(ATTRIBUTE_SPEED_LIMIT, speedLimit); + event.setGeofenceId(deviceState.getOverspeedGeofenceId()); deviceState.setOverspeedState(notRepeat); deviceState.setOverspeedPosition(null); + deviceState.setOverspeedGeofenceId(0); return Collections.singletonMap(event, position); } @@ -61,7 +67,8 @@ public class OverspeedEventHandler extends BaseEventHandler { return result; } - public Map<Event, Position> updateOverspeedState(DeviceState deviceState, Position position, double speedLimit) { + public Map<Event, Position> updateOverspeedState( + DeviceState deviceState, Position position, double speedLimit, long geofenceId) { Map<Event, Position> result = null; Boolean oldOverspeed = deviceState.getOverspeedState(); @@ -71,12 +78,15 @@ public class OverspeedEventHandler extends BaseEventHandler { if (newOverspeed && !oldOverspeed) { if (deviceState.getOverspeedPosition() == null) { deviceState.setOverspeedPosition(position); + deviceState.setOverspeedGeofenceId(geofenceId); } } else if (oldOverspeed && !newOverspeed) { deviceState.setOverspeedState(false); deviceState.setOverspeedPosition(null); + deviceState.setOverspeedGeofenceId(0); } else { deviceState.setOverspeedPosition(null); + deviceState.setOverspeedGeofenceId(0); } Position overspeedPosition = deviceState.getOverspeedPosition(); if (overspeedPosition != null) { @@ -101,6 +111,28 @@ public class OverspeedEventHandler extends BaseEventHandler { } double speedLimit = Context.getDeviceManager().lookupAttributeDouble(deviceId, ATTRIBUTE_SPEED_LIMIT, 0, false); + + double geofenceSpeedLimit = 0; + long overspeedGeofenceId = 0; + + if (Context.getGeofenceManager() != null) { + for (long geofenceId : device.getGeofenceIds()) { + Geofence geofence = Context.getGeofenceManager().getById(geofenceId); + if (geofence != null) { + double currentSpeedLimit = geofence.getDouble(ATTRIBUTE_SPEED_LIMIT); + if (currentSpeedLimit > 0 && geofenceSpeedLimit == 0 + || preferLowest && currentSpeedLimit < geofenceSpeedLimit + || !preferLowest && currentSpeedLimit > geofenceSpeedLimit) { + geofenceSpeedLimit = currentSpeedLimit; + overspeedGeofenceId = geofenceId; + } + } + } + } + if (geofenceSpeedLimit > 0) { + speedLimit = geofenceSpeedLimit; + } + if (speedLimit == 0) { return null; } @@ -110,8 +142,9 @@ public class OverspeedEventHandler extends BaseEventHandler { if (deviceState.getOverspeedState() == null) { deviceState.setOverspeedState(position.getSpeed() > speedLimit); + deviceState.setOverspeedGeofenceId(position.getSpeed() > speedLimit ? overspeedGeofenceId : 0); } else { - result = updateOverspeedState(deviceState, position, speedLimit); + result = updateOverspeedState(deviceState, position, speedLimit, overspeedGeofenceId); } Context.getDeviceManager().setDeviceState(deviceId, deviceState); diff --git a/src/org/traccar/model/DeviceState.java b/src/org/traccar/model/DeviceState.java index f2d0ff614..75d6726ee 100644 --- a/src/org/traccar/model/DeviceState.java +++ b/src/org/traccar/model/DeviceState.java @@ -58,4 +58,14 @@ public class DeviceState { return overspeedPosition; } + private long overspeedGeofenceId; + + public void setOverspeedGeofenceId(long overspeedGeofenceId) { + this.overspeedGeofenceId = overspeedGeofenceId; + } + + public long getOverspeedGeofenceId() { + return overspeedGeofenceId; + } + } diff --git a/templates/mail/deviceOverspeed.vm b/templates/mail/deviceOverspeed.vm index b1f0a6734..e5e576f3a 100644 --- a/templates/mail/deviceOverspeed.vm +++ b/templates/mail/deviceOverspeed.vm @@ -12,7 +12,7 @@ <html> <body> Device: $device.name<br> -Exceeds the speed: $speedString<br> +Exceeds the speed: $speedString#{if}($geofence) in $geofence.name#{else}#{end}<br> Time: $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.serverTime, $locale, $timezone)<br> Point: <a href="$webUrl?eventId=$event.id">#{if}($position.address)$position.address#{else}$position.latitude°, $position.longitude°#{end}</a><br> </body> diff --git a/templates/sms/deviceOverspeed.vm b/templates/sms/deviceOverspeed.vm index f0b03c9e7..5e92f662c 100644 --- a/templates/sms/deviceOverspeed.vm +++ b/templates/sms/deviceOverspeed.vm @@ -7,4 +7,4 @@ #else #set($speedString = $numberTool.format("0.0 kn", $position.speed)) #end -$device.name exceeds the speed $speedString at $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.serverTime, $locale, $timezone) +$device.name exceeds the speed $speedString#{if}($geofence) in $geofence.name#{else}#{end} at $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.serverTime, $locale, $timezone) diff --git a/test/org/traccar/events/OverspeedEventHandlerTest.java b/test/org/traccar/events/OverspeedEventHandlerTest.java index d38367cd9..98fd0f87a 100644 --- a/test/org/traccar/events/OverspeedEventHandlerTest.java +++ b/test/org/traccar/events/OverspeedEventHandlerTest.java @@ -26,8 +26,8 @@ public class OverspeedEventHandlerTest extends BaseTest { return dateFormat.parse(time); } - private void testOverspeedWithPosition(boolean notRepeat) throws Exception { - OverspeedEventHandler overspeedEventHandler = new OverspeedEventHandler(15000, notRepeat); + private void testOverspeedWithPosition(boolean notRepeat, long geofenceId) throws Exception { + OverspeedEventHandler overspeedEventHandler = new OverspeedEventHandler(15000, notRepeat, false); Position position = new Position(); position.setTime(date("2017-01-01 00:00:00")); @@ -35,52 +35,58 @@ public class OverspeedEventHandlerTest extends BaseTest { DeviceState deviceState = new DeviceState(); deviceState.setOverspeedState(false); - Map<Event, Position> events = overspeedEventHandler.updateOverspeedState(deviceState, position, 40); + Map<Event, Position> events = overspeedEventHandler.updateOverspeedState(deviceState, position, 40, geofenceId); assertNull(events); assertFalse(deviceState.getOverspeedState()); assertEquals(position, deviceState.getOverspeedPosition()); + assertEquals(geofenceId, deviceState.getOverspeedGeofenceId()); Position nextPosition = new Position(); nextPosition.setTime(date("2017-01-01 00:00:10")); nextPosition.setSpeed(55); - events = overspeedEventHandler.updateOverspeedState(deviceState, nextPosition, 40); + events = overspeedEventHandler.updateOverspeedState(deviceState, nextPosition, 40, geofenceId); assertNull(events); nextPosition.setTime(date("2017-01-01 00:00:20")); - events = overspeedEventHandler.updateOverspeedState(deviceState, nextPosition, 40); + events = overspeedEventHandler.updateOverspeedState(deviceState, nextPosition, 40, geofenceId); assertNotNull(events); Event event = events.keySet().iterator().next(); assertEquals(Event.TYPE_DEVICE_OVERSPEED, event.getType()); assertEquals(50, event.getDouble("speed"), 0.1); assertEquals(40, event.getDouble(OverspeedEventHandler.ATTRIBUTE_SPEED_LIMIT), 0.1); + assertEquals(geofenceId, event.getGeofenceId()); assertEquals(notRepeat, deviceState.getOverspeedState()); assertNull(deviceState.getOverspeedPosition()); + assertEquals(0, deviceState.getOverspeedGeofenceId()); nextPosition.setTime(date("2017-01-01 00:00:30")); - events = overspeedEventHandler.updateOverspeedState(deviceState, nextPosition, 40); + events = overspeedEventHandler.updateOverspeedState(deviceState, nextPosition, 40, geofenceId); assertNull(events); assertEquals(notRepeat, deviceState.getOverspeedState()); if (notRepeat) { assertNull(deviceState.getOverspeedPosition()); + assertEquals(0, deviceState.getOverspeedGeofenceId()); } else { assertNotNull(deviceState.getOverspeedPosition()); + assertEquals(geofenceId, deviceState.getOverspeedGeofenceId()); } nextPosition.setTime(date("2017-01-01 00:00:40")); nextPosition.setSpeed(30); - events = overspeedEventHandler.updateOverspeedState(deviceState, nextPosition, 40); + events = overspeedEventHandler.updateOverspeedState(deviceState, nextPosition, 40, geofenceId); assertNull(events); assertFalse(deviceState.getOverspeedState()); assertNull(deviceState.getOverspeedPosition()); + assertEquals(0, deviceState.getOverspeedGeofenceId()); } private void testOverspeedWithStatus(boolean notRepeat) throws Exception { - OverspeedEventHandler overspeedEventHandler = new OverspeedEventHandler(15000, notRepeat); + OverspeedEventHandler overspeedEventHandler = new OverspeedEventHandler(15000, notRepeat, false); Position position = new Position(); position.setTime(new Date(System.currentTimeMillis() - 30000)); @@ -99,8 +105,11 @@ public class OverspeedEventHandlerTest extends BaseTest { @Test public void testOverspeedEventHandler() throws Exception { - testOverspeedWithPosition(false); - testOverspeedWithPosition(true); + testOverspeedWithPosition(false, 0); + testOverspeedWithPosition(true, 0); + + testOverspeedWithPosition(false, 1); + testOverspeedWithPosition(true, 1); testOverspeedWithStatus(false); testOverspeedWithStatus(true); |