aboutsummaryrefslogtreecommitdiff
path: root/src/org/traccar/reports/ReportUtils.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/org/traccar/reports/ReportUtils.java')
-rw-r--r--src/org/traccar/reports/ReportUtils.java190
1 files changed, 188 insertions, 2 deletions
diff --git a/src/org/traccar/reports/ReportUtils.java b/src/org/traccar/reports/ReportUtils.java
index 84d3b3a77..252e7caad 100644
--- a/src/org/traccar/reports/ReportUtils.java
+++ b/src/org/traccar/reports/ReportUtils.java
@@ -1,6 +1,6 @@
/*
- * Copyright 2016 Anton Tananaev (anton@traccar.org)
- * Copyright 2016 Andrey Kunitsyn (andrey@traccar.org)
+ * Copyright 2016 - 2017 Anton Tananaev (anton@traccar.org)
+ * Copyright 2016 - 2017 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.
@@ -27,6 +27,10 @@ import org.jxls.transform.poi.PoiTransformer;
import org.jxls.util.TransformerFactory;
import org.traccar.Context;
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;
import java.io.IOException;
import java.io.InputStream;
@@ -123,4 +127,186 @@ public final class ReportUtils {
transformer.write();
}
+ public static TripsConfig initTripsConfig() {
+ return new TripsConfig(
+ Context.getConfig().getLong("report.trip.minimalTripDuration", 300) * 1000,
+ Context.getConfig().getLong("report.trip.minimalTripDistance", 500),
+ Context.getConfig().getLong("report.trip.minimalParkingDuration", 300) * 1000,
+ Context.getConfig().getBoolean("report.trip.greedyParking"));
+ }
+
+ private static TripReport calculateTrip(
+ ArrayList<Position> positions, int startIndex, int endIndex, boolean ignoreOdometer) {
+ Position startTrip = positions.get(startIndex);
+ Position endTrip = positions.get(endIndex);
+
+ double speedMax = 0.0;
+ double speedSum = 0.0;
+ for (int i = startIndex; i <= endIndex; i++) {
+ double speed = positions.get(i).getSpeed();
+ speedSum += speed;
+ if (speed > speedMax) {
+ speedMax = speed;
+ }
+ }
+
+ TripReport trip = new TripReport();
+
+ long tripDuration = endTrip.getFixTime().getTime() - startTrip.getFixTime().getTime();
+ long deviceId = startTrip.getDeviceId();
+ trip.setDeviceId(deviceId);
+ trip.setDeviceName(Context.getIdentityManager().getDeviceById(deviceId).getName());
+
+ trip.setStartPositionId(startTrip.getId());
+ trip.setStartLat(startTrip.getLatitude());
+ trip.setStartLon(startTrip.getLongitude());
+ trip.setStartTime(startTrip.getFixTime());
+ trip.setStartAddress(startTrip.getAddress());
+
+ trip.setEndPositionId(endTrip.getId());
+ trip.setEndLat(endTrip.getLatitude());
+ trip.setEndLon(endTrip.getLongitude());
+ trip.setEndTime(endTrip.getFixTime());
+ trip.setEndAddress(endTrip.getAddress());
+
+ trip.setDistance(calculateDistance(startTrip, endTrip, !ignoreOdometer));
+ trip.setDuration(tripDuration);
+ trip.setAverageSpeed(speedSum / (endIndex - startIndex));
+ trip.setMaxSpeed(speedMax);
+ trip.setSpentFuel(calculateFuel(startTrip, endTrip));
+
+ return trip;
+ }
+
+ private static StopReport calculateStop(ArrayList<Position> positions, int startIndex, int endIndex) {
+ Position startStop = positions.get(startIndex);
+ Position endStop = positions.get(endIndex);
+
+ StopReport stop = new StopReport();
+
+ long deviceId = startStop.getDeviceId();
+ stop.setDeviceId(deviceId);
+ stop.setDeviceName(Context.getIdentityManager().getDeviceById(deviceId).getName());
+
+ stop.setPositionId(startStop.getId());
+ stop.setLatitude(startStop.getLatitude());
+ stop.setLongitude(startStop.getLongitude());
+ stop.setStartTime(startStop.getFixTime());
+ stop.setAddress(startStop.getAddress());
+ stop.setEndTime(endStop.getFixTime());
+
+ long stopDuration = endStop.getFixTime().getTime() - startStop.getFixTime().getTime();
+ stop.setDuration(stopDuration);
+ stop.setSpentFuel(calculateFuel(startStop, endStop));
+
+ long engineHours = 0;
+ for (int i = startIndex + 1; i <= endIndex; i++) {
+ if (positions.get(i).getBoolean(Position.KEY_IGNITION)
+ && positions.get(i - 1).getBoolean(Position.KEY_IGNITION)) {
+ engineHours += positions.get(i).getFixTime().getTime() - positions.get(i - 1).getFixTime().getTime();
+ }
+ }
+ stop.setEngineHours(engineHours);
+
+ return stop;
+
+ }
+
+ public static Collection<BaseReport> detectTripsAndStops(TripsConfig tripsConfig,
+ boolean ignoreOdometer, double speedThreshold,
+ Collection<Position> positionCollection, boolean trips) {
+
+ Collection<BaseReport> 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;
+
+ for (int i = 0; i < positions.size(); i++) {
+ isMoving = positions.get(i).getSpeed() > speedThreshold;
+ isLast = i == positions.size() - 1;
+
+ if ((isMoving || isLast) && startParkingIndex != -1) {
+ if (!skipped || previousEndParkingIndex == 0) {
+ previousEndParkingIndex = endParkingIndex;
+ }
+ endParkingIndex = i;
+ }
+ 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 (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, endParkingIndex));
+ }
+ }
+ previousEndParkingIndex = endParkingIndex;
+ skipped = false;
+ } else {
+ skipped = true;
+ }
+ 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));
+ }
+ }
+ }
+
+ return result;
+ }
}