aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main/java/org/traccar/config/Keys.java9
-rw-r--r--src/main/java/org/traccar/database/DataManager.java16
-rw-r--r--src/main/java/org/traccar/handler/FilterHandler.java35
3 files changed, 29 insertions, 31 deletions
diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java
index c6a202d2f..a77204175 100644
--- a/src/main/java/org/traccar/config/Keys.java
+++ b/src/main/java/org/traccar/config/Keys.java
@@ -890,11 +890,12 @@ public final class Keys {
Collections.singletonList(KeyType.GLOBAL));
/**
- * If FALSE, then filter compares duplicates, distance or period only with the last received location.
- * Server expects all locations to come sequentially.
+ * If false, the server expects all locations to come sequentially (for each device). Filter checks for duplicates,
+ * distance, speed, or time period only against the location that was last received by server.
*
- * If TRUE, then filter compares duplicates, distance or period with Position's fixTime strictly before and after.
- * Server expects locations to come at random order, since tracking device might go offline.
+ * If true, the server expects locations to come at random order (since tracking device might go offline).
+ * Filter checks for duplicates, distance, speed, or time period against the preceding Position's.
+ * Important: setting to true can cause potential performance issues.
*/
public static final ConfigKey<Boolean> FILTER_RELATIVE = new ConfigKey<>(
"filter.relative",
diff --git a/src/main/java/org/traccar/database/DataManager.java b/src/main/java/org/traccar/database/DataManager.java
index 3f702f78a..d8401774e 100644
--- a/src/main/java/org/traccar/database/DataManager.java
+++ b/src/main/java/org/traccar/database/DataManager.java
@@ -340,20 +340,8 @@ public class DataManager {
}
}
- public Position getPrevPosition(long deviceId, Date date) throws SQLException {
- Collection<Position> positions = QueryBuilder.create(dataSource, getQuery("database.selectPrevPosition"))
- .setLong("deviceId", deviceId)
- .setDate("time", date)
- .executeQuery(Position.class);
- if (positions.isEmpty()) {
- return null;
- } else {
- return positions.iterator().next();
- }
- }
-
- public Position getNextPosition(long deviceId, Date date) throws SQLException {
- Collection<Position> positions = QueryBuilder.create(dataSource, getQuery("database.selectNextPosition"))
+ public Position getPrecedingPosition(long deviceId, Date date) throws SQLException {
+ Collection<Position> positions = QueryBuilder.create(dataSource, getQuery("database.selectPrecedingPosition"))
.setLong("deviceId", deviceId)
.setDate("time", date)
.executeQuery(Position.class);
diff --git a/src/main/java/org/traccar/handler/FilterHandler.java b/src/main/java/org/traccar/handler/FilterHandler.java
index 16e5ae2da..5287a7639 100644
--- a/src/main/java/org/traccar/handler/FilterHandler.java
+++ b/src/main/java/org/traccar/handler/FilterHandler.java
@@ -146,6 +146,7 @@ public class FilterHandler extends BaseDataHandler {
}
private boolean filter(Position position) {
+
if (skipAttributes(position)) {
return false;
}
@@ -173,43 +174,44 @@ public class FilterHandler extends BaseDataHandler {
}
// relative filtering
- if (filterDuplicate || filterDistance != 0 || filterMaxSpeed != 0 || filterMinPeriod != 0) {
- Position previous = null;
+ long deviceId = position.getDeviceId();
+ if (filterDuplicate || filterDistance > 0 || filterMaxSpeed > 0 || filterMinPeriod > 0) {
+ Position preceding = null;
if (filterRelative) {
try {
Date newFixTime = position.getFixTime();
- previous = Context.getDataManager().getPrevPosition(position.getDeviceId(), newFixTime);
+ preceding = Context.getDataManager().getPrecedingPosition(deviceId, newFixTime);
} catch (SQLException e) {
- LOGGER.warn("Error filtering position", e);
+ LOGGER.warn("Error retrieving preceding position; fallbacking to last received position.", e);
+ preceding = getLastReceivedPosition(deviceId);
}
} else {
- if (Context.getIdentityManager() != null) {
- previous = Context.getIdentityManager().getLastPosition(position.getDeviceId());
- }
+ preceding = getLastReceivedPosition(deviceId);
}
- if (skipLimit(position, previous)) {
+ if (skipLimit(position, preceding)) {
return false;
}
- if (filterDuplicate(position, previous)) {
+ if (filterDuplicate(position, preceding)) {
filterType.append("Duplicate ");
}
- if (filterDistance(position, previous)) {
+ if (filterDistance(position, preceding)) {
filterType.append("Distance ");
}
- if (filterMaxSpeed(position, previous)) {
+ if (filterMaxSpeed(position, preceding)) {
filterType.append("MaxSpeed ");
}
- if (filterMinPeriod(position, previous)) {
+ if (filterMinPeriod(position, preceding)) {
filterType.append("MinPeriod ");
}
}
if (filterType.length() > 0) {
+
StringBuilder message = new StringBuilder();
message.append("Position filtered by ");
message.append(filterType.toString());
message.append("filters from device: ");
- message.append(Context.getIdentityManager().getById(position.getDeviceId()).getUniqueId());
+ message.append(Context.getIdentityManager().getById(deviceId).getUniqueId());
LOGGER.info(message.toString());
return true;
@@ -218,6 +220,13 @@ public class FilterHandler extends BaseDataHandler {
return false;
}
+ private Position getLastReceivedPosition(long deviceId) {
+ if (Context.getIdentityManager() != null) {
+ return Context.getIdentityManager().getLastPosition(deviceId);
+ }
+ return null;
+ }
+
@Override
protected Position handlePosition(Position position) {
if (filter(position)) {