aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/main/java/org/traccar/web/client/Traccar.java18
-rw-r--r--src/main/java/org/traccar/web/client/controller/DeviceController.java12
-rw-r--r--src/main/java/org/traccar/web/client/controller/MapController.java45
-rw-r--r--src/main/java/org/traccar/web/client/database/DatabaseService.java2
-rw-r--r--src/main/java/org/traccar/web/client/database/DatabaseServiceAsync.java2
-rw-r--r--src/main/java/org/traccar/web/client/i18n/ApplicationConstants.java9
-rw-r--r--src/main/java/org/traccar/web/client/view/DevicePanel.java8
-rw-r--r--src/main/java/org/traccar/web/client/view/MapPanel.java128
-rw-r--r--src/main/java/org/traccar/web/server/database/DatabaseServiceImpl.java15
-rw-r--r--src/main/java/org/traccar/web/shared/model/Position.java62
10 files changed, 266 insertions, 35 deletions
diff --git a/src/main/java/org/traccar/web/client/Traccar.java b/src/main/java/org/traccar/web/client/Traccar.java
index 6da9e01..5ea75cf 100644
--- a/src/main/java/org/traccar/web/client/Traccar.java
+++ b/src/main/java/org/traccar/web/client/Traccar.java
@@ -1,5 +1,7 @@
package org.traccar.web.client;
+import java.util.List;
+
import org.traccar.web.client.controller.ArchiveController;
import org.traccar.web.client.controller.DeviceController;
import org.traccar.web.client.controller.LoginController;
@@ -7,6 +9,7 @@ import org.traccar.web.client.controller.MapController;
import org.traccar.web.client.database.DatabaseService;
import org.traccar.web.client.database.DatabaseServiceAsync;
import org.traccar.web.client.i18n.ApplicationConstants;
+import org.traccar.web.shared.model.Device;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
@@ -54,6 +57,7 @@ public class Traccar implements EntryPoint, LoginController.LoginHandler {
private void createLayout() {
mapController = new MapController();
deviceController = new DeviceController();
+ deviceController.setHandler(deviceHandler);
archiveController = new ArchiveController();
Canvas mainPanel = mapController.getView();
@@ -89,4 +93,18 @@ public class Traccar implements EntryPoint, LoginController.LoginHandler {
mainLayout.draw();
}
+ DeviceController.DeviceHandler deviceHandler = new DeviceController.DeviceHandler() {
+
+ @Override
+ public void onChanged(List<Device> devices) {
+ mapController.update();
+ }
+
+ @Override
+ public void onSelected(Device device) {
+ mapController.select(device);
+ }
+
+ };
+
}
diff --git a/src/main/java/org/traccar/web/client/controller/DeviceController.java b/src/main/java/org/traccar/web/client/controller/DeviceController.java
index 6bf73b0..0c42e8a 100644
--- a/src/main/java/org/traccar/web/client/controller/DeviceController.java
+++ b/src/main/java/org/traccar/web/client/controller/DeviceController.java
@@ -15,7 +15,8 @@ import com.smartgwt.client.widgets.events.ClickHandler;
public class DeviceController implements PanelController, DevicePanel.DeviceHandler, DeviceDialog.SaveHandler {
public interface DeviceHandler {
- public void onChanged();
+ public void onChanged(List<Device> devices);
+ public void onSelected(Device device);
}
private DeviceHandler deviceHandler;
@@ -65,6 +66,13 @@ public class DeviceController implements PanelController, DevicePanel.DeviceHand
}
@Override
+ public void onSelected(Device device) {
+ if (deviceHandler != null) {
+ deviceHandler.onSelected(device);
+ }
+ }
+
+ @Override
public void onSave(Device device) {
Traccar.getDatabaseService().storeDevice(device, saveCallback);
}
@@ -87,7 +95,7 @@ public class DeviceController implements PanelController, DevicePanel.DeviceHand
public void onSuccess(List<Device> result) {
devicePanel.updateDevices(result);
if (deviceHandler != null) {
- deviceHandler.onChanged();
+ deviceHandler.onChanged(result);
}
}
};
diff --git a/src/main/java/org/traccar/web/client/controller/MapController.java b/src/main/java/org/traccar/web/client/controller/MapController.java
index 6493883..8932050 100644
--- a/src/main/java/org/traccar/web/client/controller/MapController.java
+++ b/src/main/java/org/traccar/web/client/controller/MapController.java
@@ -1,14 +1,57 @@
package org.traccar.web.client.controller;
+import java.util.List;
+
+import org.traccar.web.client.Traccar;
import org.traccar.web.client.view.MapPanel;
+import org.traccar.web.shared.model.Device;
+import org.traccar.web.shared.model.Position;
+import com.google.gwt.user.client.Timer;
+import com.google.gwt.user.client.rpc.AsyncCallback;
import com.smartgwt.client.widgets.Canvas;
public class MapController implements PanelController {
+ private static final int UPDATE_INTERVAL = 10000;
+
+ private final MapPanel mapPanel;
+
+ private final Timer updateTimer;
+
+ public MapController() {
+ mapPanel = new MapPanel();
+ updateTimer = new Timer() {
+ @Override
+ public void run() {
+ update();
+ }
+ };
+ update();
+ }
+
@Override
public Canvas getView() {
- return new MapPanel();
+ return mapPanel;
+ }
+
+ public void select(Device device) {
+ mapPanel.select(device, true);
+ }
+
+ public void update() {
+ updateTimer.cancel();
+ Traccar.getDatabaseService().getLatestPositions(new AsyncCallback<List<Position>>() {
+ @Override
+ public void onSuccess(List<Position> result) {
+ mapPanel.showPositions(result);
+ updateTimer.schedule(UPDATE_INTERVAL);
+ }
+ @Override
+ public void onFailure(Throwable caught) {
+ updateTimer.schedule(UPDATE_INTERVAL);
+ }
+ });
}
}
diff --git a/src/main/java/org/traccar/web/client/database/DatabaseService.java b/src/main/java/org/traccar/web/client/database/DatabaseService.java
index 646f7a6..4e68181 100644
--- a/src/main/java/org/traccar/web/client/database/DatabaseService.java
+++ b/src/main/java/org/traccar/web/client/database/DatabaseService.java
@@ -26,4 +26,6 @@ public interface DatabaseService extends RemoteService {
List<Position> getPositions(Device device, Date from, Date to);
+ List<Position> getLatestPositions();
+
}
diff --git a/src/main/java/org/traccar/web/client/database/DatabaseServiceAsync.java b/src/main/java/org/traccar/web/client/database/DatabaseServiceAsync.java
index 7a700be..809574d 100644
--- a/src/main/java/org/traccar/web/client/database/DatabaseServiceAsync.java
+++ b/src/main/java/org/traccar/web/client/database/DatabaseServiceAsync.java
@@ -24,4 +24,6 @@ public interface DatabaseServiceAsync {
void getPositions(Device device, Date from, Date to, AsyncCallback<List<Position>> callback);
+ void getLatestPositions(AsyncCallback<List<Position>> callback);
+
}
diff --git a/src/main/java/org/traccar/web/client/i18n/ApplicationConstants.java b/src/main/java/org/traccar/web/client/i18n/ApplicationConstants.java
index 2e7c006..41f3764 100644
--- a/src/main/java/org/traccar/web/client/i18n/ApplicationConstants.java
+++ b/src/main/java/org/traccar/web/client/i18n/ApplicationConstants.java
@@ -64,4 +64,13 @@ public interface ApplicationConstants extends Constants {
@DefaultStringValue("Cancel")
String cancel();
+ @DefaultStringValue("Mapnik")
+ String mapnik();
+
+ @DefaultStringValue("Markers")
+ String markers();
+
+ @DefaultStringValue("Map")
+ String map();
+
}
diff --git a/src/main/java/org/traccar/web/client/view/DevicePanel.java b/src/main/java/org/traccar/web/client/view/DevicePanel.java
index 2052c99..11a3bc3 100644
--- a/src/main/java/org/traccar/web/client/view/DevicePanel.java
+++ b/src/main/java/org/traccar/web/client/view/DevicePanel.java
@@ -34,6 +34,7 @@ public class DevicePanel extends SectionStack {
public void onAdd();
public void onEdit(Device device);
public void onRemove(Device device);
+ public void onSelected(Device device);
}
private DeviceHandler deviceHandler;
@@ -124,6 +125,13 @@ public class DevicePanel extends SectionStack {
public void onSelectionChanged(SelectionEvent event) {
removeButton.setVisible(list.anySelected());
editButton.setVisible(list.anySelected());
+ if (deviceHandler != null) {
+ if (list.anySelected()) {
+ deviceHandler.onSelected(deviceMap.get(list.getSelectedRecord().getAttributeAsLong(COLUMN_ID)));
+ } else {
+ deviceHandler.onSelected(null);
+ }
+ }
}
});
diff --git a/src/main/java/org/traccar/web/client/view/MapPanel.java b/src/main/java/org/traccar/web/client/view/MapPanel.java
index 06bf45c..4a2ea94 100644
--- a/src/main/java/org/traccar/web/client/view/MapPanel.java
+++ b/src/main/java/org/traccar/web/client/view/MapPanel.java
@@ -1,12 +1,24 @@
package org.traccar.web.client.view;
+import java.util.AbstractMap;
+import java.util.HashMap;
+import java.util.List;
+
+import org.gwtopenmaps.openlayers.client.Icon;
import org.gwtopenmaps.openlayers.client.LonLat;
import org.gwtopenmaps.openlayers.client.Map;
import org.gwtopenmaps.openlayers.client.MapOptions;
import org.gwtopenmaps.openlayers.client.MapWidget;
+import org.gwtopenmaps.openlayers.client.Marker;
+import org.gwtopenmaps.openlayers.client.Pixel;
import org.gwtopenmaps.openlayers.client.Projection;
+import org.gwtopenmaps.openlayers.client.Size;
import org.gwtopenmaps.openlayers.client.control.ScaleLine;
+import org.gwtopenmaps.openlayers.client.layer.Markers;
import org.gwtopenmaps.openlayers.client.layer.OSM;
+import org.traccar.web.client.Traccar;
+import org.traccar.web.shared.model.Device;
+import org.traccar.web.shared.model.Position;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
@@ -18,50 +30,80 @@ import com.smartgwt.client.widgets.events.ResizedHandler;
import com.smartgwt.client.widgets.layout.SectionStack;
import com.smartgwt.client.widgets.layout.SectionStackSection;
+
+class MarkerIconFactory {
+
+ private static final Size iconSize = new Size(21, 25);
+ private static final Pixel iconOffset = new Pixel(-10.5f, -25.0f);
+
+ private static final String iconUrl = "http://www.openlayers.org/api/img/";
+ private static final String iconRed = iconUrl + "marker.png";
+ private static final String iconBlue = iconUrl + "marker-blue.png";
+ private static final String iconGreen = iconUrl + "marker-green.png";
+ private static final String iconGold = iconUrl + "marker-gold.png";
+
+ public static Icon getLocationIcon() {
+ return new Icon(iconRed, iconSize, iconOffset);
+ }
+
+ public static Icon getSelectedLocationIcon() {
+ return new Icon(iconGreen, iconSize, iconOffset);
+ }
+
+ public static Icon getArchiveIcon() {
+ return new Icon(iconBlue, iconSize, iconOffset);
+ }
+
+ public static Icon getSelectedArchiveIcon() {
+ return new Icon(iconGold, iconSize, iconOffset);
+ }
+
+}
+
/**
* Map panel widget
*/
public class MapPanel extends SectionStack {
- //private final static int BORDER_SIZE = 1;
-
private MapWidget mapWidget;
+ private Map map;
private WidgetCanvas mapWrapper;
+ private Markers markerLayer;
+
+ private LonLat createPoint(double longitude, double latitude) {
+ LonLat point = new LonLat(longitude, latitude);
+ point.transform(new Projection("EPSG:4326").getProjectionCode(), map.getProjection());
+ return point;
+ }
- private MapWidget createMapWidget() {
+ private void createMapWidget() {
MapOptions defaultMapOptions = new MapOptions();
defaultMapOptions.setNumZoomLevels(16);
- MapWidget mapWidget = new MapWidget("100%", "100%", defaultMapOptions);
+ mapWidget = new MapWidget("100%", "100%", defaultMapOptions);
+ map = mapWidget.getMap();
- // Google layer
- /*GoogleV3Options layerOptions = new GoogleV3Options();
- layerOptions.setIsBaseLayer(true);
- layerOptions.setType(GoogleV3MapType.G_NORMAL_MAP);
- GoogleV3 layer = new GoogleV3("Google", layerOptions);*/
+ OSM mapLayer = OSM.Mapnik(Traccar.getConstants().mapnik());
+ mapLayer.setIsBaseLayer(true);
- // Open Street Map layer
- OSM layer = OSM.Mapnik("Mapnik");
- layer.setIsBaseLayer(true);
+ markerLayer = new Markers(Traccar.getConstants().markers());
- Map map = mapWidget.getMap();
- map.addLayer(layer);
+ map.addLayer(mapLayer);
+ map.addLayer(markerLayer);
map.addControl(new ScaleLine());
- // Default center
- LonLat lonLat = new LonLat(12.5, 41.9);
- lonLat.transform(new Projection("EPSG:4326").getProjectionCode(), map.getProjection());
- map.setCenter(lonLat, 1);
-
- return mapWidget;
+ map.setCenter(createPoint(12.5, 41.9), 1);
}
+ public SectionStackSection section;
+
public MapPanel() {
- SectionStackSection section = new SectionStackSection("Map");
+ section = new SectionStackSection(Traccar.getConstants().map());
+ section.setShowHeader(false);
section.setCanCollapse(false);
section.setExpanded(true);
- mapWidget = createMapWidget();
+ createMapWidget();
mapWrapper = new WidgetCanvas(mapWidget);
mapWrapper.setStyleName("defaultBorder");
@@ -84,7 +126,7 @@ public class MapPanel extends SectionStack {
mapWrapper.addResizedHandler(new ResizedHandler() {
@Override
public void onResized(ResizedEvent event) {
- mapWidget.getMap().updateSize();
+ map.updateSize();
}
});
@@ -92,4 +134,44 @@ public class MapPanel extends SectionStack {
setSections(section);
}
+ private AbstractMap<Device, Position> positionMap = new HashMap<Device, Position>();
+ private AbstractMap<Device, Marker> markerMap = new HashMap<Device, Marker>();
+ private Device selectedDevice;
+
+ public void showPositions(List<Position> positions) {
+ positionMap.clear();
+ markerMap.clear();
+ markerLayer.clearMarkers();
+ for (Position position : positions) {
+ positionMap.put(position.getDevice(), position);
+ Marker marker = new Marker(
+ createPoint(position.getLongitude(), position.getLatitude()), MarkerIconFactory.getLocationIcon());
+ markerMap.put(position.getDevice(), marker);
+ markerLayer.addMarker(marker);
+ }
+ if (selectedDevice != null) {
+ select(selectedDevice, false);
+ }
+ }
+
+ private void changeMarkerIcon(Marker marker, Icon icon) {
+ Marker newMarker = new Marker(marker.getLonLat(), icon);
+ markerLayer.removeMarker(marker);
+ markerLayer.addMarker(newMarker);
+ }
+
+ public void select(Device device, boolean center) {
+ if (selectedDevice != null) {
+ changeMarkerIcon(markerMap.get(selectedDevice), MarkerIconFactory.getLocationIcon());
+ }
+ if (device != null) {
+ Marker marker = markerMap.get(device);
+ if (center) {
+ map.panTo(marker.getLonLat());
+ }
+ changeMarkerIcon(marker, MarkerIconFactory.getSelectedLocationIcon());
+ }
+ selectedDevice = device;
+ }
+
}
diff --git a/src/main/java/org/traccar/web/server/database/DatabaseServiceImpl.java b/src/main/java/org/traccar/web/server/database/DatabaseServiceImpl.java
index 335cc17..d466262 100644
--- a/src/main/java/org/traccar/web/server/database/DatabaseServiceImpl.java
+++ b/src/main/java/org/traccar/web/server/database/DatabaseServiceImpl.java
@@ -131,4 +131,19 @@ public class DatabaseServiceImpl extends RemoteServiceServlet implements Databas
return positions;
}
+ @Override
+ public List<Position> getLatestPositions() {
+ User user = getUser();
+ TypedQuery<Position> query = entityManager.createQuery(
+ "SELECT x FROM Position x WHERE (x.device, x.time) IN (" +
+ "SELECT y.device, MAX(y.time) FROM Position y WHERE y.device IN :devices GROUP BY y.device)", Position.class);
+ query.setParameter("devices", user.getDevices());
+
+ List<Position> positions = new LinkedList<Position>();
+ for (Position position : query.getResultList()) {
+ positions.add(position);
+ }
+ return positions;
+ }
+
}
diff --git a/src/main/java/org/traccar/web/shared/model/Position.java b/src/main/java/org/traccar/web/shared/model/Position.java
index 5a918cf..69181df 100644
--- a/src/main/java/org/traccar/web/shared/model/Position.java
+++ b/src/main/java/org/traccar/web/shared/model/Position.java
@@ -28,10 +28,6 @@ public class Position implements Serializable {
@Index(name = "positionsIndex")
private Device device;
- public void setDevice(Device device) {
- this.device = device;
- }
-
public Device getDevice() {
return device;
}
@@ -39,14 +35,62 @@ public class Position implements Serializable {
@Index(name = "positionsIndex")
private Date time;
- public void setTime(Date time) {
- this.time = time;
- }
-
public Date getTime() {
return time;
}
- // TODO: other
+ private boolean valid;
+
+ public boolean getValid() {
+ return valid;
+ }
+
+ private double latitude;
+
+ public double getLatitude() {
+ return latitude;
+ }
+
+ private double longitude;
+
+ public double getLongitude() {
+ return longitude;
+ }
+
+ private double altitude;
+
+ public double getAltitude() {
+ return altitude;
+ }
+
+ private double speed;
+
+ public double getSpeed() {
+ return speed;
+ }
+
+ private double course;
+
+ public double getCourse() {
+ return course;
+ }
+
+ private double power;
+
+ public double getPower() {
+ return power;
+ }
+
+ private String address;
+
+ public String getAddress() {
+ return address;
+ }
+
+ private String other;
+
+ public String getOther() {
+ return other;
+ }
}