diff options
author | Anton Tananaev <anton.tananaev@gmail.com> | 2017-08-16 23:14:36 +1200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-08-16 23:14:36 +1200 |
commit | e8739edc4e2b3a945c2b0eeec6286f7ef59037cf (patch) | |
tree | 4f804a49c612c38f73fab724e1ce982261238e78 /src/org | |
parent | 7820541530ea9891c001cbd8c53cc6340380a077 (diff) | |
parent | 5d3eb5136b96c8667021ef4d9452b4008ff40e42 (diff) | |
download | traccar-server-e8739edc4e2b3a945c2b0eeec6286f7ef59037cf.tar.gz traccar-server-e8739edc4e2b3a945c2b0eeec6286f7ef59037cf.tar.bz2 traccar-server-e8739edc4e2b3a945c2b0eeec6286f7ef59037cf.zip |
Merge pull request #3447 from Abyss777/new_trips_detector
Reimplement trips detector using MotionEventHandler
Diffstat (limited to 'src/org')
-rw-r--r-- | src/org/traccar/Context.java | 1 | ||||
-rw-r--r-- | src/org/traccar/events/MotionEventHandler.java | 5 | ||||
-rw-r--r-- | src/org/traccar/reports/ReportUtils.java | 138 | ||||
-rw-r--r-- | src/org/traccar/reports/Stops.java | 9 | ||||
-rw-r--r-- | src/org/traccar/reports/Trips.java | 9 | ||||
-rw-r--r-- | src/org/traccar/reports/model/TripsConfig.java | 13 |
6 files changed, 65 insertions, 110 deletions
diff --git a/src/org/traccar/Context.java b/src/org/traccar/Context.java index aa7e6acf9..10fdd9f29 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, config.getBoolean("report.trip.useIgnition")); } 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 8c39bb9dc..6a5370d15 100644 --- a/src/org/traccar/reports/ReportUtils.java +++ b/src/org/traccar/reports/ReportUtils.java @@ -26,7 +26,10 @@ 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; @@ -235,12 +238,27 @@ public final class ReportUtils { } + private static <T extends BaseReport> T calculateTripOrStop(ArrayList<Position> positions, int startIndex, + int endIndex, boolean ignoreOdometer, Class<T> 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<Position> 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()) { - 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) { @@ -250,100 +268,48 @@ public final class ReportUtils { } } - public static Collection<BaseReport> detectTripsAndStops(TripsConfig tripsConfig, boolean ignoreOdometer, - double speedThreshold, Collection<Position> positionCollection, boolean trips) { - - Collection<BaseReport> result = new ArrayList<>(); + public static <T extends BaseReport> Collection<T> detectTripsAndStops(Collection<Position> positionCollection, + TripsConfig tripsConfig, boolean ignoreOdometer, double speedThreshold, Class<T> reportClass) { + Collection<T> result = new ArrayList<>(); ArrayList<Position> positions = new ArrayList<>(positionCollection); if (positions != null && !positions.isEmpty()) { - int previousStartParkingIndex = 0; - int startParkingIndex = -1; - int previousEndParkingIndex = 0; - int endParkingIndex = 0; - - boolean isMoving = false; - boolean isLast = false; - boolean skipped = false; - boolean tripFiltered = false; - + boolean trips = reportClass.equals(TripReport.class); + MotionEventHandler motionHandler = new MotionEventHandler(tripsConfig); + DeviceState deviceState = new DeviceState(); + deviceState.setMotionState(isMoving(positions, 0, tripsConfig, speedThreshold)); + int startEventIndex = trips == deviceState.getMotionState() ? 0 : -1; + int startNoEventIndex = -1; 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; + Event event = motionHandler.updateMotionState(deviceState, positions.get(i), + isMoving(positions, i, tripsConfig, speedThreshold)); + if (deviceState.getMotionPosition() != null && startEventIndex == -1 + && trips != deviceState.getMotionState()) { + startEventIndex = i; + startNoEventIndex = -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(); - startParkingIndex = i; + if (trips == deviceState.getMotionState()) { + if (startNoEventIndex == -1) { + startNoEventIndex = i; + } else if (deviceState.getMotionPosition() == null) { + startNoEventIndex = -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; - } - startParkingIndex = -1; + if (startEventIndex != -1 && startNoEventIndex != -1 && event != null + && trips != deviceState.getMotionState()) { + result.add(calculateTripOrStop(positions, startEventIndex, startNoEventIndex, + ignoreOdometer, reportClass)); + startEventIndex = -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 (startEventIndex != -1) { + if (startNoEventIndex != -1 || !trips) { + result.add(calculateTripOrStop(positions, startEventIndex, + startNoEventIndex != -1 ? startNoEventIndex : positions.size() - 1, + ignoreOdometer, reportClass)); } } } - return result; } } diff --git a/src/org/traccar/reports/Stops.java b/src/org/traccar/reports/Stops.java index 3f7f674b5..1e72cc927 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<? extends BaseReport> result = ReportUtils.detectTripsAndStops( - Context.getTripsConfig(), ignoreOdometer, speedThreshold, - Context.getDataManager().getPositions(deviceId, from, to), false); + Collection<StopReport> result = ReportUtils.detectTripsAndStops( + Context.getDataManager().getPositions(deviceId, from, to), + Context.getTripsConfig(), ignoreOdometer, speedThreshold, StopReport.class); - return (Collection<StopReport>) result; + return result; } public static Collection<StopReport> getObjects( diff --git a/src/org/traccar/reports/Trips.java b/src/org/traccar/reports/Trips.java index a4dcf00f1..1ee62e87c 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<? extends BaseReport> result = ReportUtils.detectTripsAndStops( - Context.getTripsConfig(), ignoreOdometer, speedThreshold, - Context.getDataManager().getPositions(deviceId, from, to), true); + Collection<TripReport> result = ReportUtils.detectTripsAndStops( + Context.getDataManager().getPositions(deviceId, from, to), + Context.getTripsConfig(), ignoreOdometer, speedThreshold, TripReport.class); - return (Collection<TripReport>) result; + return result; } public static Collection<TripReport> getObjects(long userId, Collection<Long> deviceIds, Collection<Long> groupIds, diff --git a/src/org/traccar/reports/model/TripsConfig.java b/src/org/traccar/reports/model/TripsConfig.java index 2e2403619..22fddd072 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, boolean useIgnition) { + long minimalNoDataDuration, boolean useIgnition) { this.minimalTripDistance = minimalTripDistance; this.minimalTripDuration = minimalTripDuration; this.minimalParkingDuration = minimalParkingDuration; - this.greedyParking = greedyParking; this.minimalNoDataDuration = minimalNoDataDuration; this.useIgnition = useIgnition; } @@ -61,16 +60,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() { |