aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAbyss777 <abyss@fox5.ru>2016-06-14 18:05:05 +0500
committerAbyss777 <abyss@fox5.ru>2016-06-14 18:05:05 +0500
commitb588b3c723cad4629dcecbce8983933f7ff2a255 (patch)
treeee1ed23c7c02ded8ca92c904e6f4f21aacfda8d8
parent185c0830e17b6969977026d4be27e34878bb3db9 (diff)
downloadtrackermap-server-b588b3c723cad4629dcecbce8983933f7ff2a255.tar.gz
trackermap-server-b588b3c723cad4629dcecbce8983933f7ff2a255.tar.bz2
trackermap-server-b588b3c723cad4629dcecbce8983933f7ff2a255.zip
- Overlapping geofences
- Simplified user-device link
-rw-r--r--debug.xml14
-rw-r--r--setup/unix/traccar.xml14
-rw-r--r--setup/windows/traccar.xml14
-rw-r--r--src/org/traccar/BaseEventHandler.java12
-rw-r--r--src/org/traccar/Context.java11
-rw-r--r--src/org/traccar/api/resource/DeviceGeofenceResource.java14
-rw-r--r--src/org/traccar/database/ConnectionManager.java19
-rw-r--r--src/org/traccar/database/DataManager.java19
-rw-r--r--src/org/traccar/database/GeofenceManager.java65
-rw-r--r--src/org/traccar/database/NotificationManager.java42
-rw-r--r--src/org/traccar/events/CommandResultEventHandler.java9
-rw-r--r--src/org/traccar/events/GeofenceEventHandler.java70
-rw-r--r--src/org/traccar/events/MotionEventHandler.java30
-rw-r--r--src/org/traccar/events/OverspeedEventHandler.java12
-rw-r--r--src/org/traccar/model/Device.java11
-rw-r--r--src/org/traccar/model/DeviceGeofence.java (renamed from src/org/traccar/model/UserDeviceGeofence.java)12
-rw-r--r--src/org/traccar/model/Geofence.java2
-rw-r--r--test/org/traccar/geofence/GeofenceCircleTest.java6
-rw-r--r--test/org/traccar/geofence/GeofencePolygonTest.java6
19 files changed, 225 insertions, 157 deletions
diff --git a/debug.xml b/debug.xml
index bc09b9f48..f04ceb271 100644
--- a/debug.xml
+++ b/debug.xml
@@ -147,7 +147,7 @@
</entry>
<entry key='database.updateDeviceStatus'>
- UPDATE devices SET status = :status, lastUpdate = :lastUpdate, motion = :motion, geofenceId = :geofenceId WHERE id = :id;
+ UPDATE devices SET status = :status, lastUpdate = :lastUpdate, motion = :motion WHERE id = :id;
</entry>
<entry key='database.deleteDevice'>
@@ -267,16 +267,16 @@
DELETE FROM group_geofence WHERE groupId = :groupId AND geofenceId = :geofenceId;
</entry>
- <entry key='database.selectUserDeviceGeofences'>
- SELECT userId, deviceId, geofenceId FROM user_device_geofence;
+ <entry key='database.selectDeviceGeofences'>
+ SELECT deviceId, geofenceId FROM device_geofence;
</entry>
- <entry key='database.linkUserDeviceGeofence'>
- INSERT INTO user_device_geofence (userId, deviceId, geofenceId) VALUES (:userId, :deviceId, :geofenceId);
+ <entry key='database.linkDeviceGeofence'>
+ INSERT INTO device_geofence (deviceId, geofenceId) VALUES (:deviceId, :geofenceId);
</entry>
- <entry key='database.unlinkUserDeviceGeofence'>
- DELETE FROM user_device_geofence WHERE userId = :userId AND deviceId = :deviceId AND geofenceId = :geofenceId;
+ <entry key='database.unlinkDeviceGeofence'>
+ DELETE FROM device_geofence WHERE deviceId = :deviceId AND geofenceId = :geofenceId;
</entry>
<!-- PROTOCOL CONFIG -->
diff --git a/setup/unix/traccar.xml b/setup/unix/traccar.xml
index 37ff31bbe..ab739e4d6 100644
--- a/setup/unix/traccar.xml
+++ b/setup/unix/traccar.xml
@@ -118,7 +118,7 @@
</entry>
<entry key='database.updateDeviceStatus'>
- UPDATE devices SET status = :status, lastUpdate = :lastUpdate, motion = :motion, geofenceId = :geofenceId WHERE id = :id;
+ UPDATE devices SET status = :status, lastUpdate = :lastUpdate, motion = :motion WHERE id = :id;
</entry>
<entry key='database.deleteDevice'>
@@ -238,16 +238,16 @@
DELETE FROM group_geofence WHERE groupId = :groupId AND geofenceId = :geofenceId;
</entry>
- <entry key='database.selectUserDeviceGeofences'>
- SELECT userId, deviceId, geofenceId FROM user_device_geofence;
+ <entry key='database.selectDeviceGeofences'>
+ SELECT deviceId, geofenceId FROM device_geofence;
</entry>
- <entry key='database.linkUserDeviceGeofence'>
- INSERT INTO user_device_geofence (userId, deviceId, geofenceId) VALUES (:userId, :deviceId, :geofenceId);
+ <entry key='database.linkDeviceGeofence'>
+ INSERT INTO device_geofence (deviceId, geofenceId) VALUES (:deviceId, :geofenceId);
</entry>
- <entry key='database.unlinkUserDeviceGeofence'>
- DELETE FROM user_device_geofence WHERE userId = :userId AND deviceId = :deviceId AND geofenceId = :geofenceId;
+ <entry key='database.unlinkDeviceGeofence'>
+ DELETE FROM device_geofence WHERE deviceId = :deviceId AND geofenceId = :geofenceId;
</entry>
<!-- PROTOCOL CONFIG -->
diff --git a/setup/windows/traccar.xml b/setup/windows/traccar.xml
index 5f86e53b0..17f2ab4f3 100644
--- a/setup/windows/traccar.xml
+++ b/setup/windows/traccar.xml
@@ -118,7 +118,7 @@
</entry>
<entry key='database.updateDeviceStatus'>
- UPDATE devices SET status = :status, lastUpdate = :lastUpdate, motion = :motion, geofenceId = :geofenceId WHERE id = :id;
+ UPDATE devices SET status = :status, lastUpdate = :lastUpdate, motion = :motion WHERE id = :id;
</entry>
<entry key='database.deleteDevice'>
@@ -238,16 +238,16 @@
DELETE FROM group_geofence WHERE groupId = :groupId AND geofenceId = :geofenceId;
</entry>
- <entry key='database.selectUserDeviceGeofences'>
- SELECT userId, deviceId, geofenceId FROM user_device_geofence;
+ <entry key='database.selectDeviceGeofences'>
+ SELECT deviceId, geofenceId FROM device_geofence;
</entry>
- <entry key='database.linkUserDeviceGeofence'>
- INSERT INTO user_device_geofence (userId, deviceId, geofenceId) VALUES (:userId, :deviceId, :geofenceId);
+ <entry key='database.linkDeviceGeofence'>
+ INSERT INTO device_geofence (deviceId, geofenceId) VALUES (:deviceId, :geofenceId);
</entry>
- <entry key='database.unlinkUserDeviceGeofence'>
- DELETE FROM user_device_geofence WHERE userId = :userId AND deviceId = :deviceId AND geofenceId = :geofenceId;
+ <entry key='database.unlinkDeviceGeofence'>
+ DELETE FROM device_geofence WHERE deviceId = :deviceId AND geofenceId = :geofenceId;
</entry>
<!-- PROTOCOL CONFIG -->
diff --git a/src/org/traccar/BaseEventHandler.java b/src/org/traccar/BaseEventHandler.java
index 3e3317f0a..16d911dac 100644
--- a/src/org/traccar/BaseEventHandler.java
+++ b/src/org/traccar/BaseEventHandler.java
@@ -1,5 +1,7 @@
package org.traccar;
+import java.util.Collection;
+
import org.traccar.model.Device;
import org.traccar.model.Event;
import org.traccar.model.Position;
@@ -23,13 +25,15 @@ public abstract class BaseEventHandler extends BaseDataHandler {
}
}
- Event event = analizePosition(position);
- if (event != null) {
- Context.getConnectionManager().updateEvent(event, position);
+ Collection<Event> events = analizePosition(position);
+ if (events != null) {
+ for (Event event : events) {
+ Context.getNotificationManager().updateEvent(event, position);
+ }
}
return position;
}
- protected abstract Event analizePosition(Position position);
+ protected abstract Collection<Event> analizePosition(Position position);
}
diff --git a/src/org/traccar/Context.java b/src/org/traccar/Context.java
index b78d11e7b..6f99ff97d 100644
--- a/src/org/traccar/Context.java
+++ b/src/org/traccar/Context.java
@@ -19,6 +19,7 @@ import com.ning.http.client.AsyncHttpClient;
import org.traccar.database.ConnectionManager;
import org.traccar.database.DataManager;
import org.traccar.database.IdentityManager;
+import org.traccar.database.NotificationManager;
import org.traccar.database.PermissionsManager;
import org.traccar.database.GeofenceManager;
import org.traccar.geocode.BingMapsReverseGeocoder;
@@ -106,6 +107,12 @@ public final class Context {
return geofenceManager;
}
+ private static NotificationManager notificationManager;
+
+ public static NotificationManager getNotificationManager() {
+ return notificationManager;
+ }
+
private static final AsyncHttpClient ASYNC_HTTP_CLIENT = new AsyncHttpClient();
public static AsyncHttpClient getAsyncHttpClient() {
@@ -184,9 +191,11 @@ public final class Context {
permissionsManager = new PermissionsManager(dataManager);
+ connectionManager = new ConnectionManager(dataManager);
+
geofenceManager = new GeofenceManager(dataManager);
- connectionManager = new ConnectionManager(dataManager);
+ notificationManager = new NotificationManager(dataManager);
serverManager = new ServerManager();
diff --git a/src/org/traccar/api/resource/DeviceGeofenceResource.java b/src/org/traccar/api/resource/DeviceGeofenceResource.java
index dc7014d79..99d64292b 100644
--- a/src/org/traccar/api/resource/DeviceGeofenceResource.java
+++ b/src/org/traccar/api/resource/DeviceGeofenceResource.java
@@ -17,7 +17,7 @@ package org.traccar.api.resource;
import org.traccar.Context;
import org.traccar.api.BaseResource;
-import org.traccar.model.UserDeviceGeofence;
+import org.traccar.model.DeviceGeofence;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
@@ -35,25 +35,21 @@ import java.sql.SQLException;
public class DeviceGeofenceResource extends BaseResource {
@POST
- public Response add(UserDeviceGeofence entity) throws SQLException {
+ public Response add(DeviceGeofence entity) throws SQLException {
Context.getPermissionsManager().checkReadonly(getUserId());
- Context.getPermissionsManager().checkUser(getUserId(), entity.getUserId());
Context.getPermissionsManager().checkDevice(getUserId(), entity.getDeviceId());
Context.getPermissionsManager().checkGeofence(getUserId(), entity.getGeofenceId());
- Context.getDataManager().linkUserDeviceGeofence(entity.getUserId(),
- entity.getDeviceId(), entity.getGeofenceId());
+ Context.getDataManager().linkDeviceGeofence(entity.getDeviceId(), entity.getGeofenceId());
Context.getGeofenceManager().refresh();
return Response.ok(entity).build();
}
@DELETE
- public Response remove(UserDeviceGeofence entity) throws SQLException {
+ public Response remove(DeviceGeofence entity) throws SQLException {
Context.getPermissionsManager().checkReadonly(getUserId());
- Context.getPermissionsManager().checkUser(getUserId(), entity.getUserId());
Context.getPermissionsManager().checkDevice(getUserId(), entity.getDeviceId());
Context.getPermissionsManager().checkGeofence(getUserId(), entity.getGeofenceId());
- Context.getDataManager().unlinkUserDeviceGeofence(entity.getUserId(), entity.getDeviceId(),
- entity.getGeofenceId());
+ Context.getDataManager().unlinkDeviceGeofence(entity.getDeviceId(), entity.getGeofenceId());
Context.getGeofenceManager().refresh();
return Response.noContent().build();
}
diff --git a/src/org/traccar/database/ConnectionManager.java b/src/org/traccar/database/ConnectionManager.java
index 6e47dfad3..4f12c44d4 100644
--- a/src/org/traccar/database/ConnectionManager.java
+++ b/src/org/traccar/database/ConnectionManager.java
@@ -94,7 +94,7 @@ public class ConnectionManager {
if (status.equals(Device.STATUS_ONLINE)) {
event.setType(Event.TYPE_DEVICE_ONLINE);
}
- updateEvent(event, null);
+ Context.getNotificationManager().updateEvent(event, null);
}
device.setStatus(status);
@@ -147,19 +147,10 @@ public class ConnectionManager {
}
}
- public synchronized void updateEvent(Event event, Position position) {
- long deviceId = event.getDeviceId();
- try {
- Context.getDataManager().addEvent(event);
- } catch (SQLException error) {
- Log.warning(error);
- }
- for (long userId : Context.getPermissionsManager().getDeviceUsers(deviceId)) {
- if (listeners.containsKey(userId) && (event.getGeofenceId() == 0
- || Context.getGeofenceManager().checkGeofence(userId, event.getGeofenceId()))) {
- for (UpdateListener listener : listeners.get(userId)) {
- listener.onUpdateEvent(event, position);
- }
+ public synchronized void updateEvent(long userId, Event event, Position position) {
+ if (listeners.containsKey(userId)) {
+ for (UpdateListener listener : listeners.get(userId)) {
+ listener.onUpdateEvent(event, position);
}
}
}
diff --git a/src/org/traccar/database/DataManager.java b/src/org/traccar/database/DataManager.java
index 30334b78b..2b09e2fb0 100644
--- a/src/org/traccar/database/DataManager.java
+++ b/src/org/traccar/database/DataManager.java
@@ -55,7 +55,7 @@ import org.traccar.model.GroupPermission;
import org.traccar.model.Position;
import org.traccar.model.Server;
import org.traccar.model.User;
-import org.traccar.model.UserDeviceGeofence;
+import org.traccar.model.DeviceGeofence;
import org.traccar.model.GeofencePermission;
import com.zaxxer.hikari.HikariConfig;
@@ -372,7 +372,6 @@ public class DataManager implements IdentityManager {
Device cachedDevice = getDeviceById(device.getId());
cachedDevice.setStatus(device.getStatus());
cachedDevice.setMotion(device.getMotion());
- cachedDevice.setGeofenceId(device.getGeofenceId());
}
public void removeDevice(long deviceId) throws SQLException {
@@ -596,22 +595,20 @@ public class DataManager implements IdentityManager {
.executeUpdate();
}
- public Collection<UserDeviceGeofence> getUserDeviceGeofences() throws SQLException {
- return QueryBuilder.create(dataSource, getQuery("database.selectUserDeviceGeofences"))
- .executeQuery(UserDeviceGeofence.class);
+ public Collection<DeviceGeofence> getDeviceGeofences() throws SQLException {
+ return QueryBuilder.create(dataSource, getQuery("database.selectDeviceGeofences"))
+ .executeQuery(DeviceGeofence.class);
}
- public void linkUserDeviceGeofence(long userId, long deviceId, long geofenceId) throws SQLException {
- QueryBuilder.create(dataSource, getQuery("database.linkUserDeviceGeofence"))
- .setLong("userId", userId)
+ public void linkDeviceGeofence(long deviceId, long geofenceId) throws SQLException {
+ QueryBuilder.create(dataSource, getQuery("database.linkDeviceGeofence"))
.setLong("deviceId", deviceId)
.setLong("geofenceId", geofenceId)
.executeUpdate();
}
- public void unlinkUserDeviceGeofence(long userId, long deviceId, long geofenceId) throws SQLException {
- QueryBuilder.create(dataSource, getQuery("database.unlinkUserDeviceGeofence"))
- .setLong("userId", userId)
+ public void unlinkDeviceGeofence(long deviceId, long geofenceId) throws SQLException {
+ QueryBuilder.create(dataSource, getQuery("database.unlinkDeviceGeofence"))
.setLong("deviceId", deviceId)
.setLong("geofenceId", geofenceId)
.executeUpdate();
diff --git a/src/org/traccar/database/GeofenceManager.java b/src/org/traccar/database/GeofenceManager.java
index 64afc876c..b551bc467 100644
--- a/src/org/traccar/database/GeofenceManager.java
+++ b/src/org/traccar/database/GeofenceManager.java
@@ -1,20 +1,24 @@
package org.traccar.database;
import java.sql.SQLException;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
+import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
+import org.traccar.Context;
import org.traccar.helper.Log;
import org.traccar.model.Device;
import org.traccar.model.Geofence;
import org.traccar.model.GroupGeofence;
-import org.traccar.model.UserDeviceGeofence;
+import org.traccar.model.Position;
+import org.traccar.model.DeviceGeofence;
import org.traccar.model.GeofencePermission;
public class GeofenceManager {
@@ -25,8 +29,8 @@ public class GeofenceManager {
private final Map<Long, Set<Long>> userGeofences = new HashMap<>();
private final Map<Long, Set<Long>> groupGeofences = new HashMap<>();
+ private final Map<Long, Set<Long>> deviceGeofencesWithGroups = new HashMap<>();
private final Map<Long, Set<Long>> deviceGeofences = new HashMap<>();
- private final Map<Long, Map<Long, Set<Long>>> userDeviceGeofences = new HashMap<>();
private final ReadWriteLock deviceGeofencesLock = new ReentrantReadWriteLock();
private final ReadWriteLock geofencesLock = new ReentrantReadWriteLock();
@@ -54,17 +58,17 @@ public class GeofenceManager {
public Set<Long> getAllDeviceGeofences(long deviceId) {
deviceGeofencesLock.readLock().lock();
try {
- return getDeviceGeofences(deviceGeofences, deviceId);
+ return getDeviceGeofences(deviceGeofencesWithGroups, deviceId);
} finally {
deviceGeofencesLock.readLock().unlock();
}
}
- public Set<Long> getUserDeviceGeofences(long userId, long deviceId) {
+ public Set<Long> getDeviceGeofences(long deviceId) {
deviceGeofencesLock.readLock().lock();
try {
- return getUserDeviceGeofencesUnlocked(userId, deviceId);
+ return getDeviceGeofences(deviceGeofences, deviceId);
} finally {
deviceGeofencesLock.readLock().unlock();
}
@@ -77,13 +81,6 @@ public class GeofenceManager {
return deviceGeofences.get(deviceId);
}
- private Set<Long> getUserDeviceGeofencesUnlocked(long userId, long deviceId) {
- if (!userDeviceGeofences.containsKey(userId)) {
- userDeviceGeofences.put(userId, new HashMap<Long, Set<Long>>());
- }
- return getDeviceGeofences(userDeviceGeofences.get(userId), deviceId);
- }
-
public final void refresh() {
if (dataManager != null) {
try {
@@ -107,24 +104,38 @@ public class GeofenceManager {
}
deviceGeofences.clear();
+ deviceGeofencesWithGroups.clear();
- for (Map.Entry<Long, Map<Long, Set<Long>>> deviceGeofence : userDeviceGeofences.entrySet()) {
- deviceGeofence.getValue().clear();
+ for (DeviceGeofence deviceGeofence : dataManager.getDeviceGeofences()) {
+ getDeviceGeofences(deviceGeofences, deviceGeofence.getDeviceId())
+ .add(deviceGeofence.getGeofenceId());
+ getDeviceGeofences(deviceGeofencesWithGroups, deviceGeofence.getDeviceId())
+ .add(deviceGeofence.getGeofenceId());
}
- userDeviceGeofences.clear();
- for (UserDeviceGeofence userDeviceGeofence : dataManager.getUserDeviceGeofences()) {
- getDeviceGeofences(deviceGeofences, userDeviceGeofence.getDeviceId())
- .add(userDeviceGeofence.getGeofenceId());
- getUserDeviceGeofencesUnlocked(userDeviceGeofence.getUserId(), userDeviceGeofence.getDeviceId())
- .add(userDeviceGeofence.getGeofenceId());
- }
for (Device device : dataManager.getAllDevices()) {
long groupId = device.getGroupId();
while (groupId != 0) {
- getDeviceGeofences(deviceGeofences, device.getId()).addAll(getGroupGeofences(groupId));
+ getDeviceGeofences(deviceGeofencesWithGroups,
+ device.getId()).addAll(getGroupGeofences(groupId));
groupId = dataManager.getGroupById(groupId).getGroupId();
}
+ List<Long> deviceGeofenceIds = device.getGeofenceIds();
+ if (deviceGeofenceIds == null) {
+ deviceGeofenceIds = new ArrayList<Long>();
+ } else {
+ deviceGeofenceIds.clear();
+ }
+ Position lastPosition = Context.getConnectionManager().getLastPosition(device.getId());
+ if (lastPosition != null) {
+ for (Long geofenceId : deviceGeofencesWithGroups.get(device.getId())) {
+ if (getGeofence(geofenceId).getGeometry()
+ .containsPoint(lastPosition.getLatitude(), lastPosition.getLongitude())) {
+ deviceGeofenceIds.add(geofenceId);
+ }
+ }
+ }
+ device.setGeofenceIds(deviceGeofenceIds);
}
} finally {
@@ -188,4 +199,14 @@ public class GeofenceManager {
return getUserGeofencesIds(userId).contains(geofenceId);
}
+ public List<Long> getCurrentDeviceGeofences(Position position) {
+ List<Long> result = new ArrayList<Long>();
+ for (Long geofenceId : getAllDeviceGeofences(position.getDeviceId())) {
+ if (getGeofence(geofenceId).getGeometry().containsPoint(position.getLatitude(), position.getLongitude())) {
+ result.add(geofenceId);
+ }
+ }
+ return result;
+ }
+
}
diff --git a/src/org/traccar/database/NotificationManager.java b/src/org/traccar/database/NotificationManager.java
new file mode 100644
index 000000000..8c8e958c8
--- /dev/null
+++ b/src/org/traccar/database/NotificationManager.java
@@ -0,0 +1,42 @@
+package org.traccar.database;
+
+import java.sql.SQLException;
+import java.util.Collection;
+import java.util.Set;
+
+import org.traccar.Context;
+import org.traccar.helper.Log;
+import org.traccar.model.Event;
+import org.traccar.model.Position;
+
+public class NotificationManager {
+
+ private final DataManager dataManager;
+
+ public NotificationManager(DataManager dataManager) {
+ this.dataManager = dataManager;
+ }
+
+ public void updateEvent(Event event, Position position) {
+ try {
+ dataManager.addEvent(event);
+ } catch (SQLException error) {
+ Log.warning(error);
+ }
+
+ Set<Long> users = Context.getPermissionsManager().getDeviceUsers(event.getDeviceId());
+ for (Long userId : users) {
+ if (event.getGeofenceId() == 0
+ || Context.getGeofenceManager().checkGeofence(userId, event.getGeofenceId())) {
+ Context.getConnectionManager().updateEvent(userId, event, position);
+ }
+ }
+ }
+
+ public void updateEvents(Collection<Event> events, Position position) {
+
+ for (Event event : events) {
+ updateEvent(event, position);
+ }
+ }
+}
diff --git a/src/org/traccar/events/CommandResultEventHandler.java b/src/org/traccar/events/CommandResultEventHandler.java
index 23c62566a..9dbdb4b4c 100644
--- a/src/org/traccar/events/CommandResultEventHandler.java
+++ b/src/org/traccar/events/CommandResultEventHandler.java
@@ -1,5 +1,8 @@
package org.traccar.events;
+import java.util.ArrayList;
+import java.util.Collection;
+
import org.traccar.BaseEventHandler;
import org.traccar.model.Event;
import org.traccar.model.Position;
@@ -7,10 +10,12 @@ import org.traccar.model.Position;
public class CommandResultEventHandler extends BaseEventHandler {
@Override
- protected Event analizePosition(Position position) {
+ protected Collection<Event> analizePosition(Position position) {
Object commandResult = position.getAttributes().get(Position.KEY_RESULT);
if (commandResult != null) {
- return new Event(Event.TYPE_COMMAND_RESULT, position.getDeviceId(), position.getId());
+ Collection<Event> events = new ArrayList<>();
+ events.add(new Event(Event.TYPE_COMMAND_RESULT, position.getDeviceId(), position.getId()));
+ return events;
}
return null;
}
diff --git a/src/org/traccar/events/GeofenceEventHandler.java b/src/org/traccar/events/GeofenceEventHandler.java
index bf9060ca1..ed63b6f7d 100644
--- a/src/org/traccar/events/GeofenceEventHandler.java
+++ b/src/org/traccar/events/GeofenceEventHandler.java
@@ -1,7 +1,9 @@
package org.traccar.events;
import java.sql.SQLException;
-import java.util.Set;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
import org.traccar.BaseEventHandler;
import org.traccar.Context;
@@ -25,50 +27,52 @@ public class GeofenceEventHandler extends BaseEventHandler {
}
@Override
- protected Event analizePosition(Position position) {
- Event event = null;
- if (!isLastPosition() || !position.getValid()) {
- return event;
+ protected Collection<Event> analizePosition(Position position) {
+ if (!isLastPosition() || !position.getValid()) {
+ return null;
}
Device device = dataManager.getDeviceById(position.getDeviceId());
if (device == null) {
- return event;
+ return null;
}
- Set<Long> geofences = geofenceManager.getAllDeviceGeofences(position.getDeviceId());
- if (geofences == null) {
- return event;
- }
- long geofenceId = 0;
- for (Long geofence : geofences) {
- if (geofenceManager.getGeofence(geofence).getGeometry()
- .containsPoint(position.getLatitude(), position.getLongitude())) {
- geofenceId = geofence;
- break;
- }
+ List<Long> currentGeofences = geofenceManager.getCurrentDeviceGeofences(position);
+ List<Long> oldGeofences = new ArrayList<Long>();
+ if (device.getGeofenceIds() != null) {
+ oldGeofences.addAll(device.getGeofenceIds());
}
+ List<Long> newGeofences = new ArrayList<Long>(currentGeofences);
+ newGeofences.removeAll(oldGeofences);
+ oldGeofences.removeAll(currentGeofences);
- if (device.getGeofenceId() != geofenceId) {
- try {
- if (geofenceId == 0) {
- event = new Event(Event.TYPE_GEOFENCE_EXIT, position.getDeviceId(), position.getId());
- event.setGeofenceId(device.getGeofenceId());
- } else {
- event = new Event(Event.TYPE_GEOFENCE_ENTER, position.getDeviceId(), position.getId());
+ device.setGeofenceIds(currentGeofences);
+
+ Collection<Event> events = new ArrayList<>();
+ try {
+ if (dataManager.getLastEvents(position.getDeviceId(),
+ Event.TYPE_GEOFENCE_ENTER, suppressRepeated).isEmpty()) {
+ for (Long geofenceId : newGeofences) {
+ Event event = new Event(Event.TYPE_GEOFENCE_ENTER, position.getDeviceId(), position.getId());
event.setGeofenceId(geofenceId);
+ events.add(event);
}
- if (event != null && !dataManager.getLastEvents(
- position.getDeviceId(), event.getType(), suppressRepeated).isEmpty()) {
- event = null;
+ }
+ } catch (SQLException error) {
+ Log.warning(error);
+ }
+ try {
+ if (dataManager.getLastEvents(position.getDeviceId(),
+ Event.TYPE_GEOFENCE_EXIT, suppressRepeated).isEmpty()) {
+ for (Long geofenceId : oldGeofences) {
+ Event event = new Event(Event.TYPE_GEOFENCE_EXIT, position.getDeviceId(), position.getId());
+ event.setGeofenceId(geofenceId);
+ events.add(event);
}
- device.setGeofenceId(geofenceId);
- dataManager.updateDeviceStatus(device);
- } catch (SQLException error) {
- Log.warning(error);
}
-
+ } catch (SQLException error) {
+ Log.warning(error);
}
- return event;
+ return events;
}
}
diff --git a/src/org/traccar/events/MotionEventHandler.java b/src/org/traccar/events/MotionEventHandler.java
index 306fa8a4e..54b6b922d 100644
--- a/src/org/traccar/events/MotionEventHandler.java
+++ b/src/org/traccar/events/MotionEventHandler.java
@@ -1,6 +1,8 @@
package org.traccar.events;
import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Collection;
import org.traccar.BaseEventHandler;
import org.traccar.Context;
@@ -19,18 +21,17 @@ public class MotionEventHandler extends BaseEventHandler {
}
@Override
- protected Event analizePosition(Position position) {
- Event event = null;
-
+ protected Collection<Event> analizePosition(Position position) {
+ Collection<Event> result = null;
if (!isLastPosition()) {
- return event;
+ return null;
}
double speed = position.getSpeed();
boolean valid = position.getValid();
Device device = Context.getIdentityManager().getDeviceById(position.getDeviceId());
if (device == null) {
- return event;
+ return null;
}
String motion = device.getMotion();
if (motion == null) {
@@ -38,21 +39,26 @@ public class MotionEventHandler extends BaseEventHandler {
}
if (valid && speed > SPEED_THRESHOLD && !motion.equals(Device.STATUS_MOVING)) {
Context.getConnectionManager().updateDevice(position.getDeviceId(), Device.STATUS_MOVING, null);
- event = new Event(Event.TYPE_DEVICE_MOVING, position.getDeviceId(), position.getId());
+ result = new ArrayList<>();
+ result.add(new Event(Event.TYPE_DEVICE_MOVING, position.getDeviceId(), position.getId()));
} else if (valid && speed < SPEED_THRESHOLD && motion.equals(Device.STATUS_MOVING)) {
Context.getConnectionManager().updateDevice(position.getDeviceId(), Device.STATUS_STOPPED, null);
- event = new Event(Event.TYPE_DEVICE_STOPPED, position.getDeviceId(), position.getId());
+ result = new ArrayList<>();
+ result.add(new Event(Event.TYPE_DEVICE_STOPPED, position.getDeviceId(), position.getId()));
}
try {
- if (event != null && !Context.getDataManager().getLastEvents(
- position.getDeviceId(), event.getType(), suppressRepeated).isEmpty()) {
- event = null;
+ if (result != null && !result.isEmpty()) {
+ for (Event event : result) {
+ if (!Context.getDataManager().getLastEvents(position.getDeviceId(),
+ event.getType(), suppressRepeated).isEmpty()) {
+ event = null;
+ }
+ }
}
-
} catch (SQLException error) {
Log.warning(error);
}
- return event;
+ return result;
}
}
diff --git a/src/org/traccar/events/OverspeedEventHandler.java b/src/org/traccar/events/OverspeedEventHandler.java
index 30410ff32..152fe6f22 100644
--- a/src/org/traccar/events/OverspeedEventHandler.java
+++ b/src/org/traccar/events/OverspeedEventHandler.java
@@ -1,6 +1,8 @@
package org.traccar.events;
import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Collection;
import org.traccar.BaseEventHandler;
import org.traccar.Context;
@@ -20,10 +22,10 @@ public class OverspeedEventHandler extends BaseEventHandler {
}
@Override
- protected Event analizePosition(Position position) {
- Event event = null;
+ protected Collection<Event> analizePosition(Position position) {
+ Collection<Event> events = new ArrayList<>();
if (!isLastPosition()) {
- return event;
+ return null;
}
double speed = position.getSpeed();
boolean valid = position.getValid();
@@ -32,14 +34,14 @@ public class OverspeedEventHandler extends BaseEventHandler {
try {
if (Context.getDataManager().getLastEvents(
position.getDeviceId(), Event.TYPE_DEVICE_OVERSPEED, suppressRepeated).isEmpty()) {
- event = new Event(Event.TYPE_DEVICE_OVERSPEED, position.getDeviceId(), position.getId());
+ events.add(new Event(Event.TYPE_DEVICE_OVERSPEED, position.getDeviceId(), position.getId()));
}
} catch (SQLException error) {
Log.warning(error);
}
}
- return event;
+ return events;
}
}
diff --git a/src/org/traccar/model/Device.java b/src/org/traccar/model/Device.java
index 45c3d46dc..c42eb3718 100644
--- a/src/org/traccar/model/Device.java
+++ b/src/org/traccar/model/Device.java
@@ -16,6 +16,7 @@
package org.traccar.model;
import java.util.Date;
+import java.util.List;
public class Device {
@@ -114,13 +115,13 @@ public class Device {
this.motion = motion;
}
- private long geofenceId;
+ private List<Long> geofenceIds;
- public long getGeofenceId() {
- return geofenceId;
+ public List<Long> getGeofenceIds() {
+ return geofenceIds;
}
- public void setGeofenceId(long geofenceId) {
- this.geofenceId = geofenceId;
+ public void setGeofenceIds(List<Long> geofenceIds) {
+ this.geofenceIds = geofenceIds;
}
}
diff --git a/src/org/traccar/model/UserDeviceGeofence.java b/src/org/traccar/model/DeviceGeofence.java
index c84aa46b8..f55c8ca69 100644
--- a/src/org/traccar/model/UserDeviceGeofence.java
+++ b/src/org/traccar/model/DeviceGeofence.java
@@ -1,16 +1,6 @@
package org.traccar.model;
-public class UserDeviceGeofence {
-
- private long userId;
-
- public long getUserId() {
- return userId;
- }
-
- public void setUserId(long userId) {
- this.userId = userId;
- }
+public class DeviceGeofence {
private long deviceId;
diff --git a/src/org/traccar/model/Geofence.java b/src/org/traccar/model/Geofence.java
index 0723c21e0..300d8fb74 100644
--- a/src/org/traccar/model/Geofence.java
+++ b/src/org/traccar/model/Geofence.java
@@ -60,7 +60,7 @@ public class Geofence extends Extensible {
}
public void setGeometry(GeofenceGeometry geometry) {
- area = geometry.toWKT();
+ area = geometry.toWkt();
this.geometry = geometry;
}
diff --git a/test/org/traccar/geofence/GeofenceCircleTest.java b/test/org/traccar/geofence/GeofenceCircleTest.java
index 820f34e34..52c214b53 100644
--- a/test/org/traccar/geofence/GeofenceCircleTest.java
+++ b/test/org/traccar/geofence/GeofenceCircleTest.java
@@ -12,11 +12,11 @@ public class GeofenceCircleTest {
String test = "CIRCLE (55.75414 37.6204, 100)";
GeofenceGeometry geofenceGeometry = new GeofenceCircle();
try {
- geofenceGeometry.fromWKT(test);
+ geofenceGeometry.fromWkt(test);
} catch (ParseException e){
Assert.assertTrue("ParseExceprion: " + e.getMessage(), true);
}
- Assert.assertEquals(geofenceGeometry.toWKT(), test);
+ Assert.assertEquals(geofenceGeometry.toWkt(), test);
}
@Test
@@ -24,7 +24,7 @@ public class GeofenceCircleTest {
String test = "CIRCLE (55.75414 37.6204, 100)";
GeofenceGeometry geofenceGeometry = new GeofenceCircle();
try {
- geofenceGeometry.fromWKT(test);
+ geofenceGeometry.fromWkt(test);
} catch (ParseException e){
Assert.assertTrue("ParseExceprion: " + e.getMessage(), true);
}
diff --git a/test/org/traccar/geofence/GeofencePolygonTest.java b/test/org/traccar/geofence/GeofencePolygonTest.java
index cc0ed77ad..8711a3696 100644
--- a/test/org/traccar/geofence/GeofencePolygonTest.java
+++ b/test/org/traccar/geofence/GeofencePolygonTest.java
@@ -12,11 +12,11 @@ public class GeofencePolygonTest {
String test = "POLYGON (55.75474 37.61823, 55.75513 37.61888, 55.7535 37.6222, 55.75315 37.62165)";
GeofenceGeometry geofenceGeometry = new GeofencePolygon();
try {
- geofenceGeometry.fromWKT(test);
+ geofenceGeometry.fromWkt(test);
} catch (ParseException e){
Assert.assertTrue("ParseExceprion: " + e.getMessage(), true);
}
- Assert.assertEquals(geofenceGeometry.toWKT(), test);
+ Assert.assertEquals(geofenceGeometry.toWkt(), test);
}
@Test
@@ -24,7 +24,7 @@ public class GeofencePolygonTest {
String test = "POLYGON (55.75474 37.61823, 55.75513 37.61888, 55.7535 37.6222, 55.75315 37.62165)";
GeofenceGeometry geofenceGeometry = new GeofencePolygon();
try {
- geofenceGeometry.fromWKT(test);
+ geofenceGeometry.fromWkt(test);
} catch (ParseException e){
Assert.assertTrue("ParseExceprion: " + e.getMessage(), true);
}