From f1ee1017d62ec0d1b6b1ca56c297537870f1d32b Mon Sep 17 00:00:00 2001 From: Abyss777 Date: Mon, 14 Aug 2017 15:34:48 +0500 Subject: Reimplement trips detector using MotionEventHandler --- src/org/traccar/reports/ReportUtils.java | 147 ++++++++++++-------------- src/org/traccar/reports/Stops.java | 9 +- src/org/traccar/reports/Trips.java | 9 +- test/org/traccar/reports/ReportUtilsTest.java | 75 ++++++------- 4 files changed, 109 insertions(+), 131 deletions(-) diff --git a/src/org/traccar/reports/ReportUtils.java b/src/org/traccar/reports/ReportUtils.java index 8c39bb9dc..91dc2e019 100644 --- a/src/org/traccar/reports/ReportUtils.java +++ b/src/org/traccar/reports/ReportUtils.java @@ -26,9 +26,11 @@ import org.jxls.transform.Transformer; import org.jxls.transform.poi.PoiTransformer; import org.jxls.util.TransformerFactory; import org.traccar.Context; +import org.traccar.events.MotionEventHandler; +import org.traccar.model.DeviceState; import org.traccar.model.Driver; +import org.traccar.model.Event; import org.traccar.model.Position; -import org.traccar.reports.model.BaseReport; import org.traccar.reports.model.StopReport; import org.traccar.reports.model.TripReport; import org.traccar.reports.model.TripsConfig; @@ -237,8 +239,11 @@ public final class ReportUtils { private static boolean isMoving(ArrayList positions, int index, TripsConfig tripsConfig, double speedThreshold) { - if (tripsConfig.getMinimalNoDataDuration() > 0 && index < positions.size() - 1 + if (tripsConfig.getMinimalNoDataDuration() > 0 && (index < positions.size() - 1 && positions.get(index + 1).getFixTime().getTime() - positions.get(index).getFixTime().getTime() + >= tripsConfig.getMinimalNoDataDuration()) + || index > 0 + && positions.get(index).getFixTime().getTime() - positions.get(index - 1).getFixTime().getTime() >= tripsConfig.getMinimalNoDataDuration()) { return false; } @@ -250,100 +255,80 @@ public final class ReportUtils { } } - public static Collection detectTripsAndStops(TripsConfig tripsConfig, boolean ignoreOdometer, - double speedThreshold, Collection positionCollection, boolean trips) { - - Collection result = new ArrayList<>(); + public static Collection detectTrips(Collection positionCollection, TripsConfig tripsConfig, + boolean ignoreOdometer, double speedThreshold) { + Collection result = new ArrayList<>(); ArrayList positions = new ArrayList<>(positionCollection); if (positions != null && !positions.isEmpty()) { - int previousStartParkingIndex = 0; + MotionEventHandler motionHandler = new MotionEventHandler(tripsConfig); + DeviceState deviceState = new DeviceState(); + deviceState.setMotionState(isMoving(positions, 0, tripsConfig, speedThreshold)); + int startTripIndex = deviceState.getMotionState() ? 0 : -1; int startParkingIndex = -1; - int previousEndParkingIndex = 0; - int endParkingIndex = 0; - - boolean isMoving = false; - boolean isLast = false; - boolean skipped = false; - boolean tripFiltered = false; - for (int i = 0; i < positions.size(); i++) { - isMoving = isMoving(positions, i, tripsConfig, speedThreshold); - isLast = i == positions.size() - 1; - - if ((isMoving || isLast) && startParkingIndex != -1) { - if (!skipped || previousEndParkingIndex == 0) { - previousEndParkingIndex = endParkingIndex; - } - endParkingIndex = i; + positions.get(i).set(Position.KEY_MOTION, isMoving(positions, i, tripsConfig, speedThreshold)); + Event event = motionHandler.updateMotionState(deviceState, positions.get(i)); + if (startTripIndex == -1 && !deviceState.getMotionState() && deviceState.getMotionPosition() != null) { + startTripIndex = i; + startParkingIndex = -1; } - if (!isMoving && startParkingIndex == -1) { - if (tripsConfig.getGreedyParking()) { - long tripDuration = positions.get(i).getFixTime().getTime() - - positions.get(endParkingIndex).getFixTime().getTime(); - double tripDistance = ReportUtils.calculateDistance(positions.get(endParkingIndex), - positions.get(i), false); - tripFiltered = tripDuration < tripsConfig.getMinimalTripDuration() - && tripDistance < tripsConfig.getMinimalTripDistance(); - if (tripFiltered) { - startParkingIndex = previousStartParkingIndex; - endParkingIndex = previousEndParkingIndex; - tripFiltered = false; - } else { - previousStartParkingIndex = i; - startParkingIndex = i; - } - } else { - long tripDuration = positions.get(i).getFixTime().getTime() - - positions.get(previousEndParkingIndex).getFixTime().getTime(); - double tripDistance = ReportUtils.calculateDistance(positions.get(previousEndParkingIndex), - positions.get(i), false); - tripFiltered = tripDuration < tripsConfig.getMinimalTripDuration() - && tripDistance < tripsConfig.getMinimalTripDistance(); + if (deviceState.getMotionState()) { + if (startParkingIndex == -1) { startParkingIndex = i; + } else if (deviceState.getMotionPosition() == null) { + startParkingIndex = -1; } } - if (startParkingIndex != -1 && (endParkingIndex > startParkingIndex || isLast)) { - long parkingDuration = positions.get(endParkingIndex).getFixTime().getTime() - - positions.get(startParkingIndex).getFixTime().getTime(); - if ((parkingDuration >= tripsConfig.getMinimalParkingDuration() || isLast) - && previousEndParkingIndex < startParkingIndex) { - if (!tripFiltered) { - if (trips) { - result.add(calculateTrip( - positions, previousEndParkingIndex, startParkingIndex, ignoreOdometer)); - } else { - if (result.isEmpty() && previousEndParkingIndex > previousStartParkingIndex) { - long previousParkingDuration = positions.get(previousEndParkingIndex) - .getFixTime().getTime() - positions.get(previousStartParkingIndex) - .getFixTime().getTime(); - if (previousParkingDuration >= tripsConfig.getMinimalParkingDuration()) { - result.add(calculateStop(positions, previousStartParkingIndex, - previousEndParkingIndex)); - } - } - result.add(calculateStop(positions, startParkingIndex, isLast ? i : endParkingIndex)); - } - } - previousEndParkingIndex = endParkingIndex; - skipped = false; - } else { - skipped = true; + if (startTripIndex != -1 && startParkingIndex != -1 && event != null && !deviceState.getMotionState()) { + result.add(calculateTrip(positions, startTripIndex, startParkingIndex, ignoreOdometer)); + startTripIndex = -1; + } + } + if (startTripIndex != -1 && startParkingIndex != -1) { + result.add(calculateTrip(positions, startTripIndex, startParkingIndex, ignoreOdometer)); + } + } + return result; + } + + public static Collection detectStops(Collection positionCollection, TripsConfig tripsConfig, + boolean ignoreOdometer, double speedThreshold) { + Collection result = new ArrayList<>(); + + ArrayList positions = new ArrayList<>(positionCollection); + if (positions != null && !positions.isEmpty()) { + MotionEventHandler motionHandler = new MotionEventHandler(tripsConfig); + DeviceState deviceState = new DeviceState(); + deviceState.setMotionState(isMoving(positions, 0, tripsConfig, speedThreshold)); + int startTripIndex = -1; + int startParkingIndex = deviceState.getMotionState() ? -1 : 0; + for (int i = 0; i < positions.size(); i++) { + boolean isMoving = isMoving(positions, i, tripsConfig, speedThreshold); + positions.get(i).set(Position.KEY_MOTION, isMoving); + Event event = motionHandler.updateMotionState(deviceState, positions.get(i)); + if (startParkingIndex == -1 && deviceState.getMotionState() + && deviceState.getMotionPosition() != null) { + startParkingIndex = i; + startTripIndex = -1; + } + if (!deviceState.getMotionState()) { + if (startTripIndex == -1) { + startTripIndex = i; + } else if (deviceState.getMotionPosition() == null) { + startTripIndex = -1; } + } + if (startParkingIndex != -1 && startTripIndex != -1 && event != null && deviceState.getMotionState()) { + result.add(calculateStop(positions, startParkingIndex, startTripIndex)); startParkingIndex = -1; } } - if (result.isEmpty() && !trips) { - int end = isMoving && !tripsConfig.getGreedyParking() - ? Math.max(endParkingIndex, previousEndParkingIndex) : positions.size() - 1; - long parkingDuration = positions.get(end).getFixTime().getTime() - - positions.get(previousStartParkingIndex).getFixTime().getTime(); - if (parkingDuration >= tripsConfig.getMinimalParkingDuration()) { - result.add(calculateStop(positions, previousStartParkingIndex, end)); - } + if (startParkingIndex != -1) { + result.add(calculateStop(positions, startParkingIndex, + startTripIndex != -1 ? startTripIndex : positions.size() - 1)); } } - return result; } } diff --git a/src/org/traccar/reports/Stops.java b/src/org/traccar/reports/Stops.java index 3f7f674b5..68fdef334 100644 --- a/src/org/traccar/reports/Stops.java +++ b/src/org/traccar/reports/Stops.java @@ -30,7 +30,6 @@ import org.apache.poi.ss.util.WorkbookUtil; import org.traccar.Context; import org.traccar.model.Device; import org.traccar.model.Group; -import org.traccar.reports.model.BaseReport; import org.traccar.reports.model.DeviceReport; import org.traccar.reports.model.StopReport; @@ -45,11 +44,11 @@ public final class Stops { boolean ignoreOdometer = Context.getDeviceManager() .lookupAttributeBoolean(deviceId, "report.ignoreOdometer", false, true); - Collection result = ReportUtils.detectTripsAndStops( - Context.getTripsConfig(), ignoreOdometer, speedThreshold, - Context.getDataManager().getPositions(deviceId, from, to), false); + Collection result = ReportUtils.detectStops( + Context.getDataManager().getPositions(deviceId, from, to), + Context.getTripsConfig(), ignoreOdometer, speedThreshold); - return (Collection) result; + return result; } public static Collection getObjects( diff --git a/src/org/traccar/reports/Trips.java b/src/org/traccar/reports/Trips.java index a4dcf00f1..bb39cf493 100644 --- a/src/org/traccar/reports/Trips.java +++ b/src/org/traccar/reports/Trips.java @@ -29,7 +29,6 @@ import org.apache.poi.ss.util.WorkbookUtil; import org.traccar.Context; import org.traccar.model.Device; import org.traccar.model.Group; -import org.traccar.reports.model.BaseReport; import org.traccar.reports.model.DeviceReport; import org.traccar.reports.model.TripReport; @@ -44,11 +43,11 @@ public final class Trips { boolean ignoreOdometer = Context.getDeviceManager() .lookupAttributeBoolean(deviceId, "report.ignoreOdometer", false, true); - Collection result = ReportUtils.detectTripsAndStops( - Context.getTripsConfig(), ignoreOdometer, speedThreshold, - Context.getDataManager().getPositions(deviceId, from, to), true); + Collection result = ReportUtils.detectTrips( + Context.getDataManager().getPositions(deviceId, from, to), + Context.getTripsConfig(), ignoreOdometer, speedThreshold); - return (Collection) result; + return result; } public static Collection getObjects(long userId, Collection deviceIds, Collection groupIds, diff --git a/test/org/traccar/reports/ReportUtilsTest.java b/test/org/traccar/reports/ReportUtilsTest.java index adcdf5875..1b552baa3 100644 --- a/test/org/traccar/reports/ReportUtilsTest.java +++ b/test/org/traccar/reports/ReportUtilsTest.java @@ -11,13 +11,13 @@ import java.text.SimpleDateFormat; import java.util.Arrays; import java.util.Collection; import java.util.Date; +import java.util.Iterator; import java.util.TimeZone; import org.junit.Assert; import org.junit.Test; import org.traccar.BaseTest; import org.traccar.model.Position; -import org.traccar.reports.model.BaseReport; import org.traccar.reports.model.StopReport; import org.traccar.reports.model.TripReport; import org.traccar.reports.model.TripsConfig; @@ -81,12 +81,12 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 180000, false, 900000); - Collection result = ReportUtils.detectTripsAndStops(tripsConfig, false, 0.01, data, true); + Collection trips = ReportUtils.detectTrips(data, tripsConfig, false, 0.01); - assertNotNull(result); - assertFalse(result.isEmpty()); + assertNotNull(trips); + assertFalse(trips.isEmpty()); - TripReport itemTrip = (TripReport) result.iterator().next(); + TripReport itemTrip = trips.iterator().next(); assertEquals(date("2016-01-01 00:02:00.000"), itemTrip.getStartTime()); assertEquals(date("2016-01-01 00:05:00.000"), itemTrip.getEndTime()); @@ -95,12 +95,20 @@ public class ReportUtilsTest extends BaseTest { assertEquals(10, itemTrip.getMaxSpeed(), 0.01); assertEquals(3000, itemTrip.getDistance(), 0.01); - result = ReportUtils.detectTripsAndStops(tripsConfig, false, 0.01, data, false); + Collection stops = ReportUtils.detectStops(data, tripsConfig, false, 0.01); - assertNotNull(result); - assertFalse(result.isEmpty()); + assertNotNull(stops); + assertFalse(stops.isEmpty()); - StopReport itemStop = (StopReport) result.iterator().next(); + Iterator iterator = stops.iterator(); + + StopReport itemStop = iterator.next(); + + assertEquals(date("2016-01-01 00:00:00.000"), itemStop.getStartTime()); + assertEquals(date("2016-01-01 00:02:00.000"), itemStop.getEndTime()); + assertEquals(120000, itemStop.getDuration()); + + itemStop = iterator.next(); assertEquals(date("2016-01-01 00:05:00.000"), itemStop.getStartTime()); assertEquals(date("2016-01-01 00:07:00.000"), itemStop.getEndTime()); @@ -121,12 +129,12 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, false, 900000); - Collection result = ReportUtils.detectTripsAndStops(tripsConfig, false, 0.01, data, false); + Collection result = ReportUtils.detectStops(data, tripsConfig, false, 0.01); assertNotNull(result); assertFalse(result.isEmpty()); - StopReport itemStop = (StopReport) result.iterator().next(); + StopReport itemStop = result.iterator().next(); assertEquals(date("2016-01-01 00:00:00.000"), itemStop.getStartTime()); assertEquals(date("2016-01-01 00:05:00.000"), itemStop.getEndTime()); @@ -147,32 +155,19 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, false, 900000); - Collection result = ReportUtils.detectTripsAndStops(tripsConfig, false, 0.01, data, false); + Collection result = ReportUtils.detectStops(data, tripsConfig, false, 0.01); assertNotNull(result); assertFalse(result.isEmpty()); - StopReport itemStop = (StopReport) result.iterator().next(); + StopReport itemStop = result.iterator().next(); assertEquals(date("2016-01-01 00:00:00.000"), itemStop.getStartTime()); assertEquals(date("2016-01-01 00:04:00.000"), itemStop.getEndTime()); assertEquals(240000, itemStop.getDuration()); - tripsConfig.setGreedyParking(true); - - result = ReportUtils.detectTripsAndStops(tripsConfig, false, 0.01, data, false); - - assertNotNull(result); - assertFalse(result.isEmpty()); - - itemStop = (StopReport) result.iterator().next(); - - assertEquals(date("2016-01-01 00:00:00.000"), itemStop.getStartTime()); - assertEquals(date("2016-01-01 00:05:00.000"), itemStop.getEndTime()); - assertEquals(300000, itemStop.getDuration()); - } - + @Test public void testDetectStopsStartedFromTrip() throws ParseException { @@ -186,16 +181,16 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, false, 900000); - Collection result = ReportUtils.detectTripsAndStops(tripsConfig, false, 0.01, data, false); + Collection result = ReportUtils.detectStops(data, tripsConfig, false, 0.01); assertNotNull(result); assertFalse(result.isEmpty()); - StopReport itemStop = (StopReport) result.iterator().next(); + StopReport itemStop = result.iterator().next(); - assertEquals(date("2016-01-01 00:00:00.000"), itemStop.getStartTime()); + assertEquals(date("2016-01-01 00:02:00.000"), itemStop.getStartTime()); assertEquals(date("2016-01-01 00:05:00.000"), itemStop.getEndTime()); - assertEquals(300000, itemStop.getDuration()); + assertEquals(180000, itemStop.getDuration()); } @@ -212,7 +207,7 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, false, 900000); - Collection result = ReportUtils.detectTripsAndStops(tripsConfig, false, 0.01, data, false); + Collection result = ReportUtils.detectStops(data, tripsConfig, false, 0.01); assertNotNull(result); assertTrue(result.isEmpty()); @@ -234,12 +229,12 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 200000, 200000, false, 900000); - Collection result = ReportUtils.detectTripsAndStops(tripsConfig, false, 0.01, data, true); + Collection trips = ReportUtils.detectTrips(data, tripsConfig, false, 0.01); - assertNotNull(result); - assertFalse(result.isEmpty()); + assertNotNull(trips); + assertFalse(trips.isEmpty()); - TripReport itemTrip = (TripReport) result.iterator().next(); + TripReport itemTrip = trips.iterator().next(); assertEquals(date("2016-01-01 00:00:00.000"), itemTrip.getStartTime()); assertEquals(date("2016-01-01 00:04:00.000"), itemTrip.getEndTime()); @@ -248,12 +243,12 @@ public class ReportUtilsTest extends BaseTest { assertEquals(7, itemTrip.getMaxSpeed(), 0.01); assertEquals(600, itemTrip.getDistance(), 0.01); - result = ReportUtils.detectTripsAndStops(tripsConfig, false, 0.01, data, false); + Collection stops = ReportUtils.detectStops(data, tripsConfig, false, 0.01); - assertNotNull(result); - assertFalse(result.isEmpty()); + assertNotNull(stops); + assertFalse(stops.isEmpty()); - StopReport itemStop = (StopReport) result.iterator().next(); + StopReport itemStop = stops.iterator().next(); assertEquals(date("2016-01-01 00:04:00.000"), itemStop.getStartTime()); assertEquals(date("2016-01-01 00:23:00.000"), itemStop.getEndTime()); -- cgit v1.2.3 From 60dea5494b10f52433166a8785edc12860679bc3 Mon Sep 17 00:00:00 2001 From: Abyss777 Date: Tue, 15 Aug 2017 15:15:49 +0500 Subject: Remove greadyParking --- src/org/traccar/Context.java | 1 - src/org/traccar/reports/model/TripsConfig.java | 13 +------------ test/org/traccar/events/MotionEventHandlerTest.java | 4 ++-- test/org/traccar/reports/ReportUtilsTest.java | 12 ++++++------ 4 files changed, 9 insertions(+), 21 deletions(-) diff --git a/src/org/traccar/Context.java b/src/org/traccar/Context.java index a69b1786d..0d2a05b7a 100644 --- a/src/org/traccar/Context.java +++ b/src/org/traccar/Context.java @@ -255,7 +255,6 @@ public final class Context { config.getLong("report.trip.minimalTripDistance", 500), config.getLong("report.trip.minimalTripDuration", 300) * 1000, config.getLong("report.trip.minimalParkingDuration", 300) * 1000, - config.getBoolean("report.trip.greedyParking"), config.getLong("report.trip.minimalNoDataDuration", 3600) * 1000); } diff --git a/src/org/traccar/reports/model/TripsConfig.java b/src/org/traccar/reports/model/TripsConfig.java index 7067781d7..4898c1389 100644 --- a/src/org/traccar/reports/model/TripsConfig.java +++ b/src/org/traccar/reports/model/TripsConfig.java @@ -22,11 +22,10 @@ public class TripsConfig { } public TripsConfig(double minimalTripDistance, long minimalTripDuration, - long minimalParkingDuration, boolean greedyParking, long minimalNoDataDuration) { + long minimalParkingDuration, long minimalNoDataDuration) { this.minimalTripDistance = minimalTripDistance; this.minimalTripDuration = minimalTripDuration; this.minimalParkingDuration = minimalParkingDuration; - this.greedyParking = greedyParking; this.minimalNoDataDuration = minimalNoDataDuration; } @@ -60,16 +59,6 @@ public class TripsConfig { this.minimalParkingDuration = minimalParkingDuration; } - private boolean greedyParking; - - public boolean getGreedyParking() { - return greedyParking; - } - - public void setGreedyParking(boolean greedyParking) { - this.greedyParking = greedyParking; - } - private long minimalNoDataDuration; public long getMinimalNoDataDuration() { diff --git a/test/org/traccar/events/MotionEventHandlerTest.java b/test/org/traccar/events/MotionEventHandlerTest.java index 6b7b9daee..0543d86fe 100644 --- a/test/org/traccar/events/MotionEventHandlerTest.java +++ b/test/org/traccar/events/MotionEventHandlerTest.java @@ -29,7 +29,7 @@ public class MotionEventHandlerTest extends BaseTest { @Test public void testMotionWithPosition() throws Exception { MotionEventHandler motionEventHandler = new MotionEventHandler( - new TripsConfig(500, 300 * 1000, 300 * 1000, false, 0)); + new TripsConfig(500, 300 * 1000, 300 * 1000, 0)); Position position = new Position(); position.setTime(date("2017-01-01 00:00:00")); @@ -68,7 +68,7 @@ public class MotionEventHandlerTest extends BaseTest { @Test public void testMotionWithStatus() throws Exception { MotionEventHandler motionEventHandler = new MotionEventHandler( - new TripsConfig(500, 300 * 1000, 300 * 1000, false, 0)); + new TripsConfig(500, 300 * 1000, 300 * 1000, 0)); Position position = new Position(); position.setTime(new Date(System.currentTimeMillis() - 360000)); diff --git a/test/org/traccar/reports/ReportUtilsTest.java b/test/org/traccar/reports/ReportUtilsTest.java index 1b552baa3..14d8d87e0 100644 --- a/test/org/traccar/reports/ReportUtilsTest.java +++ b/test/org/traccar/reports/ReportUtilsTest.java @@ -79,7 +79,7 @@ public class ReportUtilsTest extends BaseTest { position("2016-01-01 00:06:00.000", 0, 3000), position("2016-01-01 00:07:00.000", 0, 3000)); - TripsConfig tripsConfig = new TripsConfig(500, 300000, 180000, false, 900000); + TripsConfig tripsConfig = new TripsConfig(500, 300000, 180000, 900000); Collection trips = ReportUtils.detectTrips(data, tripsConfig, false, 0.01); @@ -127,7 +127,7 @@ public class ReportUtilsTest extends BaseTest { position("2016-01-01 00:04:00.000", 1, 0), position("2016-01-01 00:05:00.000", 0, 0)); - TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, false, 900000); + TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000); Collection result = ReportUtils.detectStops(data, tripsConfig, false, 0.01); @@ -153,7 +153,7 @@ public class ReportUtilsTest extends BaseTest { position("2016-01-01 00:04:00.000", 1, 0), position("2016-01-01 00:05:00.000", 2, 0)); - TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, false, 900000); + TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000); Collection result = ReportUtils.detectStops(data, tripsConfig, false, 0.01); @@ -179,7 +179,7 @@ public class ReportUtilsTest extends BaseTest { position("2016-01-01 00:04:00.000", 0, 0), position("2016-01-01 00:05:00.000", 0, 0)); - TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, false, 900000); + TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000); Collection result = ReportUtils.detectStops(data, tripsConfig, false, 0.01); @@ -205,7 +205,7 @@ public class ReportUtilsTest extends BaseTest { position("2016-01-01 00:04:00.000", 5, 0), position("2016-01-01 00:05:00.000", 5, 0)); - TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, false, 900000); + TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000); Collection result = ReportUtils.detectStops(data, tripsConfig, false, 0.01); @@ -227,7 +227,7 @@ public class ReportUtilsTest extends BaseTest { position("2016-01-01 00:24:00.000", 5, 800), position("2016-01-01 00:25:00.000", 5, 900)); - TripsConfig tripsConfig = new TripsConfig(500, 200000, 200000, false, 900000); + TripsConfig tripsConfig = new TripsConfig(500, 200000, 200000, 900000); Collection trips = ReportUtils.detectTrips(data, tripsConfig, false, 0.01); -- cgit v1.2.3 From 9b9c715cf0d9604be71a35e5e6e5428a3a891ba9 Mon Sep 17 00:00:00 2001 From: Abyss777 Date: Tue, 15 Aug 2017 15:26:49 +0500 Subject: Remove intermediate variable --- src/org/traccar/reports/ReportUtils.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/org/traccar/reports/ReportUtils.java b/src/org/traccar/reports/ReportUtils.java index 91dc2e019..75f300b1d 100644 --- a/src/org/traccar/reports/ReportUtils.java +++ b/src/org/traccar/reports/ReportUtils.java @@ -304,8 +304,7 @@ public final class ReportUtils { int startTripIndex = -1; int startParkingIndex = deviceState.getMotionState() ? -1 : 0; for (int i = 0; i < positions.size(); i++) { - boolean isMoving = isMoving(positions, i, tripsConfig, speedThreshold); - positions.get(i).set(Position.KEY_MOTION, isMoving); + positions.get(i).set(Position.KEY_MOTION, isMoving(positions, i, tripsConfig, speedThreshold)); Event event = motionHandler.updateMotionState(deviceState, positions.get(i)); if (startParkingIndex == -1 && deviceState.getMotionState() && deviceState.getMotionPosition() != null) { -- cgit v1.2.3 From 668d0c65609cc510ad9da3be4fc7aafaa3ca427d Mon Sep 17 00:00:00 2001 From: Abyss777 Date: Wed, 16 Aug 2017 11:04:41 +0500 Subject: Combine trips and stops detectors and some optimization --- src/org/traccar/events/MotionEventHandler.java | 5 +- src/org/traccar/reports/ReportUtils.java | 114 +++++++++++-------------- src/org/traccar/reports/Stops.java | 4 +- src/org/traccar/reports/Trips.java | 4 +- test/org/traccar/reports/ReportUtilsTest.java | 16 ++-- 5 files changed, 68 insertions(+), 75 deletions(-) diff --git a/src/org/traccar/events/MotionEventHandler.java b/src/org/traccar/events/MotionEventHandler.java index 8c2d4c56c..b96898fc1 100644 --- a/src/org/traccar/events/MotionEventHandler.java +++ b/src/org/traccar/events/MotionEventHandler.java @@ -61,11 +61,14 @@ public class MotionEventHandler extends BaseEventHandler { } public Event updateMotionState(DeviceState deviceState, Position position) { + return updateMotionState(deviceState, position, position.getBoolean(Position.KEY_MOTION)); + } + + public Event updateMotionState(DeviceState deviceState, Position position, boolean newMotion) { Event result = null; Boolean oldMotion = deviceState.getMotionState(); long currentTime = position.getFixTime().getTime(); - boolean newMotion = position.getBoolean(Position.KEY_MOTION); if (newMotion != oldMotion) { if (deviceState.getMotionPosition() == null) { deviceState.setMotionPosition(position); diff --git a/src/org/traccar/reports/ReportUtils.java b/src/org/traccar/reports/ReportUtils.java index 75f300b1d..cd13b28e6 100644 --- a/src/org/traccar/reports/ReportUtils.java +++ b/src/org/traccar/reports/ReportUtils.java @@ -31,6 +31,7 @@ import org.traccar.model.DeviceState; import org.traccar.model.Driver; import org.traccar.model.Event; import org.traccar.model.Position; +import org.traccar.reports.model.BaseReport; import org.traccar.reports.model.StopReport; import org.traccar.reports.model.TripReport; import org.traccar.reports.model.TripsConfig; @@ -239,13 +240,16 @@ public final class ReportUtils { private static boolean isMoving(ArrayList positions, int index, TripsConfig tripsConfig, double speedThreshold) { - if (tripsConfig.getMinimalNoDataDuration() > 0 && (index < positions.size() - 1 - && positions.get(index + 1).getFixTime().getTime() - positions.get(index).getFixTime().getTime() - >= tripsConfig.getMinimalNoDataDuration()) - || index > 0 - && positions.get(index).getFixTime().getTime() - positions.get(index - 1).getFixTime().getTime() - >= tripsConfig.getMinimalNoDataDuration()) { - return false; + if (tripsConfig.getMinimalNoDataDuration() > 0) { + boolean beforeGap = index < positions.size() - 1 + && positions.get(index + 1).getFixTime().getTime() - positions.get(index).getFixTime().getTime() + >= tripsConfig.getMinimalNoDataDuration(); + boolean afterGap = index > 0 + && positions.get(index).getFixTime().getTime() - positions.get(index - 1).getFixTime().getTime() + >= tripsConfig.getMinimalNoDataDuration(); + if (beforeGap || afterGap) { + return false; + } } if (positions.get(index).getAttributes().containsKey(Position.KEY_MOTION) && positions.get(index).getAttributes().get(Position.KEY_MOTION) instanceof Boolean) { @@ -255,76 +259,62 @@ public final class ReportUtils { } } - public static Collection detectTrips(Collection positionCollection, TripsConfig tripsConfig, - boolean ignoreOdometer, double speedThreshold) { - Collection result = new ArrayList<>(); + public static Collection detectTripsAndStops(Collection positionCollection, + TripsConfig tripsConfig, boolean ignoreOdometer, double speedThreshold, Class reportClass) { + Collection result = new ArrayList<>(); ArrayList positions = new ArrayList<>(positionCollection); if (positions != null && !positions.isEmpty()) { + boolean trips = reportClass.equals(TripReport.class); MotionEventHandler motionHandler = new MotionEventHandler(tripsConfig); DeviceState deviceState = new DeviceState(); deviceState.setMotionState(isMoving(positions, 0, tripsConfig, speedThreshold)); - int startTripIndex = deviceState.getMotionState() ? 0 : -1; - int startParkingIndex = -1; + int startTripIndex = trips && deviceState.getMotionState() ? 0 : -1; + int startParkingIndex = !trips && !deviceState.getMotionState() ? 0 : -1; for (int i = 0; i < positions.size(); i++) { - positions.get(i).set(Position.KEY_MOTION, isMoving(positions, i, tripsConfig, speedThreshold)); - Event event = motionHandler.updateMotionState(deviceState, positions.get(i)); - if (startTripIndex == -1 && !deviceState.getMotionState() && deviceState.getMotionPosition() != null) { - startTripIndex = i; - startParkingIndex = -1; - } - if (deviceState.getMotionState()) { - if (startParkingIndex == -1) { - startParkingIndex = i; - } else if (deviceState.getMotionPosition() == null) { + Event event = motionHandler.updateMotionState(deviceState, positions.get(i), + isMoving(positions, i, tripsConfig, speedThreshold)); + if (deviceState.getMotionPosition() != null) { + if (trips && startTripIndex == -1 && !deviceState.getMotionState()) { + startTripIndex = i; startParkingIndex = -1; + } else if (!trips && startParkingIndex == -1 && deviceState.getMotionState()) { + startParkingIndex = i; + startTripIndex = -1; } } - if (startTripIndex != -1 && startParkingIndex != -1 && event != null && !deviceState.getMotionState()) { - result.add(calculateTrip(positions, startTripIndex, startParkingIndex, ignoreOdometer)); - startTripIndex = -1; - } - } - if (startTripIndex != -1 && startParkingIndex != -1) { - result.add(calculateTrip(positions, startTripIndex, startParkingIndex, ignoreOdometer)); - } - } - return result; - } - - public static Collection detectStops(Collection positionCollection, TripsConfig tripsConfig, - boolean ignoreOdometer, double speedThreshold) { - Collection result = new ArrayList<>(); - - ArrayList positions = new ArrayList<>(positionCollection); - if (positions != null && !positions.isEmpty()) { - MotionEventHandler motionHandler = new MotionEventHandler(tripsConfig); - DeviceState deviceState = new DeviceState(); - deviceState.setMotionState(isMoving(positions, 0, tripsConfig, speedThreshold)); - int startTripIndex = -1; - int startParkingIndex = deviceState.getMotionState() ? -1 : 0; - for (int i = 0; i < positions.size(); i++) { - positions.get(i).set(Position.KEY_MOTION, isMoving(positions, i, tripsConfig, speedThreshold)); - Event event = motionHandler.updateMotionState(deviceState, positions.get(i)); - if (startParkingIndex == -1 && deviceState.getMotionState() - && deviceState.getMotionPosition() != null) { - startParkingIndex = i; - startTripIndex = -1; + if (trips) { + if (deviceState.getMotionState()) { + if (startParkingIndex == -1) { + startParkingIndex = i; + } else if (deviceState.getMotionPosition() == null) { + startParkingIndex = -1; + } + } + } else { + if (!deviceState.getMotionState()) { + if (startTripIndex == -1) { + startTripIndex = i; + } else if (deviceState.getMotionPosition() == null) { + startTripIndex = -1; + } + } } - if (!deviceState.getMotionState()) { - if (startTripIndex == -1) { - startTripIndex = i; - } else if (deviceState.getMotionPosition() == null) { + if (startTripIndex != -1 && startParkingIndex != -1 && event != null) { + if (trips && !deviceState.getMotionState()) { + result.add((T) calculateTrip(positions, startTripIndex, startParkingIndex, ignoreOdometer)); startTripIndex = -1; + } else if (!trips && deviceState.getMotionState()) { + result.add((T) calculateStop(positions, startParkingIndex, startTripIndex)); + startParkingIndex = -1; } } - if (startParkingIndex != -1 && startTripIndex != -1 && event != null && deviceState.getMotionState()) { - result.add(calculateStop(positions, startParkingIndex, startTripIndex)); - startParkingIndex = -1; - } } - if (startParkingIndex != -1) { - result.add(calculateStop(positions, startParkingIndex, + if (trips && startTripIndex != -1 && startParkingIndex != -1) { + result.add((T) calculateTrip(positions, startTripIndex, startParkingIndex, ignoreOdometer)); + } + if (!trips && startParkingIndex != -1) { + result.add((T) calculateStop(positions, startParkingIndex, startTripIndex != -1 ? startTripIndex : positions.size() - 1)); } } diff --git a/src/org/traccar/reports/Stops.java b/src/org/traccar/reports/Stops.java index 68fdef334..1e72cc927 100644 --- a/src/org/traccar/reports/Stops.java +++ b/src/org/traccar/reports/Stops.java @@ -44,9 +44,9 @@ public final class Stops { boolean ignoreOdometer = Context.getDeviceManager() .lookupAttributeBoolean(deviceId, "report.ignoreOdometer", false, true); - Collection result = ReportUtils.detectStops( + Collection result = ReportUtils.detectTripsAndStops( Context.getDataManager().getPositions(deviceId, from, to), - Context.getTripsConfig(), ignoreOdometer, speedThreshold); + Context.getTripsConfig(), ignoreOdometer, speedThreshold, StopReport.class); return result; } diff --git a/src/org/traccar/reports/Trips.java b/src/org/traccar/reports/Trips.java index bb39cf493..1ee62e87c 100644 --- a/src/org/traccar/reports/Trips.java +++ b/src/org/traccar/reports/Trips.java @@ -43,9 +43,9 @@ public final class Trips { boolean ignoreOdometer = Context.getDeviceManager() .lookupAttributeBoolean(deviceId, "report.ignoreOdometer", false, true); - Collection result = ReportUtils.detectTrips( + Collection result = ReportUtils.detectTripsAndStops( Context.getDataManager().getPositions(deviceId, from, to), - Context.getTripsConfig(), ignoreOdometer, speedThreshold); + Context.getTripsConfig(), ignoreOdometer, speedThreshold, TripReport.class); return result; } diff --git a/test/org/traccar/reports/ReportUtilsTest.java b/test/org/traccar/reports/ReportUtilsTest.java index c74109550..c82853161 100644 --- a/test/org/traccar/reports/ReportUtilsTest.java +++ b/test/org/traccar/reports/ReportUtilsTest.java @@ -81,7 +81,7 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 180000, 900000, false); - Collection trips = ReportUtils.detectTrips(data, tripsConfig, false, 0.01); + Collection trips = ReportUtils.detectTripsAndStops(data, tripsConfig, false, 0.01, TripReport.class); assertNotNull(trips); assertFalse(trips.isEmpty()); @@ -95,7 +95,7 @@ public class ReportUtilsTest extends BaseTest { assertEquals(10, itemTrip.getMaxSpeed(), 0.01); assertEquals(3000, itemTrip.getDistance(), 0.01); - Collection stops = ReportUtils.detectStops(data, tripsConfig, false, 0.01); + Collection stops = ReportUtils.detectTripsAndStops(data, tripsConfig, false, 0.01, StopReport.class); assertNotNull(stops); assertFalse(stops.isEmpty()); @@ -129,7 +129,7 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false); - Collection result = ReportUtils.detectStops(data, tripsConfig, false, 0.01); + Collection result = ReportUtils.detectTripsAndStops(data, tripsConfig, false, 0.01, StopReport.class); assertNotNull(result); assertFalse(result.isEmpty()); @@ -155,7 +155,7 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false); - Collection result = ReportUtils.detectStops(data, tripsConfig, false, 0.01); + Collection result = ReportUtils.detectTripsAndStops(data, tripsConfig, false, 0.01, StopReport.class); assertNotNull(result); assertFalse(result.isEmpty()); @@ -181,7 +181,7 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false); - Collection result = ReportUtils.detectStops(data, tripsConfig, false, 0.01); + Collection result = ReportUtils.detectTripsAndStops(data, tripsConfig, false, 0.01, StopReport.class); assertNotNull(result); assertFalse(result.isEmpty()); @@ -207,7 +207,7 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false); - Collection result = ReportUtils.detectStops(data, tripsConfig, false, 0.01); + Collection result = ReportUtils.detectTripsAndStops(data, tripsConfig, false, 0.01, StopReport.class); assertNotNull(result); assertTrue(result.isEmpty()); @@ -229,7 +229,7 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 200000, 200000, 900000, false); - Collection trips = ReportUtils.detectTrips(data, tripsConfig, false, 0.01); + Collection trips = ReportUtils.detectTripsAndStops(data, tripsConfig, false, 0.01, TripReport.class); assertNotNull(trips); assertFalse(trips.isEmpty()); @@ -243,7 +243,7 @@ public class ReportUtilsTest extends BaseTest { assertEquals(7, itemTrip.getMaxSpeed(), 0.01); assertEquals(600, itemTrip.getDistance(), 0.01); - Collection stops = ReportUtils.detectStops(data, tripsConfig, false, 0.01); + Collection stops = ReportUtils.detectTripsAndStops(data, tripsConfig, false, 0.01, StopReport.class); assertNotNull(stops); assertFalse(stops.isEmpty()); -- cgit v1.2.3 From 3224a87a5a533737cfe5edf3b67c2f3e84fe8496 Mon Sep 17 00:00:00 2001 From: Abyss777 Date: Wed, 16 Aug 2017 15:08:51 +0500 Subject: Combine detection logic and unwrap gap check --- src/org/traccar/reports/ReportUtils.java | 89 +++++++++++++++----------------- 1 file changed, 43 insertions(+), 46 deletions(-) diff --git a/src/org/traccar/reports/ReportUtils.java b/src/org/traccar/reports/ReportUtils.java index cd13b28e6..db2d59a5d 100644 --- a/src/org/traccar/reports/ReportUtils.java +++ b/src/org/traccar/reports/ReportUtils.java @@ -238,16 +238,30 @@ public final class ReportUtils { } + private static T calculateTripOrStop(ArrayList positions, int startIndex, + int endIndex, boolean ignoreOdometer, Class reportClass) { + if (reportClass.equals(TripReport.class)) { + return (T) calculateTrip(positions, startIndex, endIndex, ignoreOdometer); + } else { + return (T) calculateStop(positions, startIndex, endIndex); + } + } + private static boolean isMoving(ArrayList positions, int index, TripsConfig tripsConfig, double speedThreshold) { if (tripsConfig.getMinimalNoDataDuration() > 0) { - boolean beforeGap = index < positions.size() - 1 - && positions.get(index + 1).getFixTime().getTime() - positions.get(index).getFixTime().getTime() - >= tripsConfig.getMinimalNoDataDuration(); - boolean afterGap = index > 0 - && positions.get(index).getFixTime().getTime() - positions.get(index - 1).getFixTime().getTime() - >= tripsConfig.getMinimalNoDataDuration(); - if (beforeGap || afterGap) { + long positionsDfference = 0; + if (index < positions.size() - 1) { + positionsDfference = positions.get(index + 1).getFixTime().getTime() + - positions.get(index).getFixTime().getTime(); + } + if (positionsDfference >= tripsConfig.getMinimalNoDataDuration()) { + return false; + } else if (index > 0) { + positionsDfference = positions.get(index).getFixTime().getTime() + - positions.get(index - 1).getFixTime().getTime(); + } + if (positionsDfference >= tripsConfig.getMinimalNoDataDuration()) { return false; } } @@ -269,53 +283,36 @@ public final class ReportUtils { MotionEventHandler motionHandler = new MotionEventHandler(tripsConfig); DeviceState deviceState = new DeviceState(); deviceState.setMotionState(isMoving(positions, 0, tripsConfig, speedThreshold)); - int startTripIndex = trips && deviceState.getMotionState() ? 0 : -1; - int startParkingIndex = !trips && !deviceState.getMotionState() ? 0 : -1; + int startEventIndex = trips == deviceState.getMotionState() ? 0 : -1; + int startNoEventIndex = -1; for (int i = 0; i < positions.size(); i++) { Event event = motionHandler.updateMotionState(deviceState, positions.get(i), isMoving(positions, i, tripsConfig, speedThreshold)); - if (deviceState.getMotionPosition() != null) { - if (trips && startTripIndex == -1 && !deviceState.getMotionState()) { - startTripIndex = i; - startParkingIndex = -1; - } else if (!trips && startParkingIndex == -1 && deviceState.getMotionState()) { - startParkingIndex = i; - startTripIndex = -1; - } + if (deviceState.getMotionPosition() != null && startEventIndex == -1 + && trips != deviceState.getMotionState()) { + startEventIndex = i; + startNoEventIndex = -1; } - if (trips) { - if (deviceState.getMotionState()) { - if (startParkingIndex == -1) { - startParkingIndex = i; - } else if (deviceState.getMotionPosition() == null) { - startParkingIndex = -1; - } - } - } else { - if (!deviceState.getMotionState()) { - if (startTripIndex == -1) { - startTripIndex = i; - } else if (deviceState.getMotionPosition() == null) { - startTripIndex = -1; - } + if (trips == deviceState.getMotionState()) { + if (startNoEventIndex == -1) { + startNoEventIndex = i; + } else if (deviceState.getMotionPosition() == null) { + startNoEventIndex = -1; } } - if (startTripIndex != -1 && startParkingIndex != -1 && event != null) { - if (trips && !deviceState.getMotionState()) { - result.add((T) calculateTrip(positions, startTripIndex, startParkingIndex, ignoreOdometer)); - startTripIndex = -1; - } else if (!trips && deviceState.getMotionState()) { - result.add((T) calculateStop(positions, startParkingIndex, startTripIndex)); - startParkingIndex = -1; - } + if (startEventIndex != -1 && startNoEventIndex != -1 && event != null + && trips != deviceState.getMotionState()) { + result.add(calculateTripOrStop(positions, startEventIndex, startNoEventIndex, + ignoreOdometer, reportClass)); + startEventIndex = -1; } } - if (trips && startTripIndex != -1 && startParkingIndex != -1) { - result.add((T) calculateTrip(positions, startTripIndex, startParkingIndex, ignoreOdometer)); - } - if (!trips && startParkingIndex != -1) { - result.add((T) calculateStop(positions, startParkingIndex, - startTripIndex != -1 ? startTripIndex : positions.size() - 1)); + if (startEventIndex != -1) { + if (startNoEventIndex != -1 || !trips) { + result.add(calculateTripOrStop(positions, startEventIndex, + startNoEventIndex != -1 ? startNoEventIndex : positions.size() - 1, + ignoreOdometer, reportClass)); + } } } return result; -- cgit v1.2.3 From 5d3eb5136b96c8667021ef4d9452b4008ff40e42 Mon Sep 17 00:00:00 2001 From: Abyss777 Date: Wed, 16 Aug 2017 16:13:26 +0500 Subject: Revert check for gap --- src/org/traccar/reports/ReportUtils.java | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/src/org/traccar/reports/ReportUtils.java b/src/org/traccar/reports/ReportUtils.java index db2d59a5d..6a5370d15 100644 --- a/src/org/traccar/reports/ReportUtils.java +++ b/src/org/traccar/reports/ReportUtils.java @@ -250,18 +250,13 @@ public final class ReportUtils { private static boolean isMoving(ArrayList positions, int index, TripsConfig tripsConfig, double speedThreshold) { if (tripsConfig.getMinimalNoDataDuration() > 0) { - long positionsDfference = 0; - if (index < positions.size() - 1) { - positionsDfference = positions.get(index + 1).getFixTime().getTime() - - positions.get(index).getFixTime().getTime(); - } - if (positionsDfference >= tripsConfig.getMinimalNoDataDuration()) { - return false; - } else if (index > 0) { - positionsDfference = positions.get(index).getFixTime().getTime() - - positions.get(index - 1).getFixTime().getTime(); - } - if (positionsDfference >= tripsConfig.getMinimalNoDataDuration()) { + boolean beforeGap = index < positions.size() - 1 + && positions.get(index + 1).getFixTime().getTime() - positions.get(index).getFixTime().getTime() + >= tripsConfig.getMinimalNoDataDuration(); + boolean afterGap = index > 0 + && positions.get(index).getFixTime().getTime() - positions.get(index - 1).getFixTime().getTime() + >= tripsConfig.getMinimalNoDataDuration(); + if (beforeGap || afterGap) { return false; } } -- cgit v1.2.3