From 5100c457ad2f1faf1cffa8503c6baaf3a26c5d89 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 10 Jan 2013 23:42:16 +1300 Subject: Archive panel and some map features --- src/org/traccar/web/client/view/ArchiveView.java | 21 +++- .../web/client/view/MapPositionRenderer.java | 114 +++++++++++++++++++ src/org/traccar/web/client/view/MapView.java | 125 +++++++++------------ .../traccar/web/client/view/MarkerIconFactory.java | 32 ++++++ 4 files changed, 220 insertions(+), 72 deletions(-) create mode 100644 src/org/traccar/web/client/view/MapPositionRenderer.java create mode 100644 src/org/traccar/web/client/view/MarkerIconFactory.java (limited to 'src/org/traccar/web/client/view') diff --git a/src/org/traccar/web/client/view/ArchiveView.java b/src/org/traccar/web/client/view/ArchiveView.java index f61ffcc..5d74f37 100644 --- a/src/org/traccar/web/client/view/ArchiveView.java +++ b/src/org/traccar/web/client/view/ArchiveView.java @@ -28,8 +28,9 @@ import com.sencha.gxt.widget.core.client.form.TimeField; import com.sencha.gxt.widget.core.client.grid.ColumnConfig; import com.sencha.gxt.widget.core.client.grid.ColumnModel; import com.sencha.gxt.widget.core.client.grid.Grid; +import com.sencha.gxt.widget.core.client.selection.SelectionChangedEvent; -public class ArchiveView { +public class ArchiveView implements SelectionChangedEvent.SelectionChangedHandler { private static ArchiveViewUiBinder uiBinder = GWT.create(ArchiveViewUiBinder.class); @@ -107,6 +108,7 @@ public class ArchiveView { uiBinder.createAndBindUi(this); + grid.getSelectionModel().addSelectionChangedHandler(this); grid.getSelectionModel().setSelectionMode(SelectionMode.SINGLE); // Initialize with current time @@ -117,6 +119,15 @@ public class ArchiveView { toTime.setValue(now); } + @Override + public void onSelectionChanged(SelectionChangedEvent event) { + if (event.getSelection().isEmpty()) { + archiveHandler.onSelected(null); + } else { + archiveHandler.onSelected(event.getSelection().get(0)); + } + } + @SuppressWarnings("deprecation") private static Date getCombineDate(DateField dateField, TimeField timeField) { Date result = null; @@ -147,7 +158,13 @@ public class ArchiveView { @Override public void onAnything() { - deviceCombo.setValue(deviceStore.findModel(deviceCombo.getValue())); + Device oldDevice = deviceCombo.getValue(); + if (oldDevice != null) { + Device newDevice = deviceStore.findModel(oldDevice); + if (newDevice != null) { + deviceCombo.setValue(newDevice); + } + } } }; diff --git a/src/org/traccar/web/client/view/MapPositionRenderer.java b/src/org/traccar/web/client/view/MapPositionRenderer.java new file mode 100644 index 0000000..5a756c7 --- /dev/null +++ b/src/org/traccar/web/client/view/MapPositionRenderer.java @@ -0,0 +1,114 @@ +package org.traccar.web.client.view; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.gwtopenmaps.openlayers.client.Icon; +import org.gwtopenmaps.openlayers.client.Marker; +import org.gwtopenmaps.openlayers.client.feature.VectorFeature; +import org.gwtopenmaps.openlayers.client.geometry.LineString; +import org.gwtopenmaps.openlayers.client.geometry.Point; +import org.gwtopenmaps.openlayers.client.layer.Markers; +import org.gwtopenmaps.openlayers.client.layer.Vector; +import org.traccar.web.shared.model.Device; +import org.traccar.web.shared.model.Position; + + +public class MapPositionRenderer { + + private final MapView mapView; + private final Vector vectorLayer; + private final Markers markerLayer; + private final MarkerIconFactory.IconType iconType; + + public MapPositionRenderer(MapView mapView, MarkerIconFactory.IconType iconType) { + this.mapView = mapView; + vectorLayer = mapView.getVectorLayer(); + markerLayer = mapView.getMarkerLayer(); + this.iconType = iconType; + } + + /* + * TODO: a lot of mess here + * 1. changeMarkerIcon doesn't save new marker + * 2. if device selected save device instead of position + * 3. find way to change marker icon + * 4. shorter cleaner methods + * ... maybe something else + */ + + private void changeMarkerIcon(Marker marker, Icon icon) { + Marker newMarker = new Marker(marker.getLonLat(), icon); + markerLayer.removeMarker(marker); + markerLayer.addMarker(newMarker); + } + + private Map markerMap = new HashMap(); // Position.id -> Marker + private Map deviceMap = new HashMap(); // Device.id -> Position.id + + private Long selectedPositionId; + + public void showPositions(List positions) { + for (Marker marker : markerMap.values()) { + markerLayer.removeMarker(marker); + } + markerMap.clear(); + deviceMap.clear(); + + for (Position position : positions) { + Marker marker = new Marker( + mapView.createLonLat(position.getLongitude(), position.getLatitude()), + MarkerIconFactory.getIcon(iconType, false)); + markerMap.put(position.getId(), marker); + deviceMap.put(position.getDevice().getId(), position.getId()); + markerLayer.addMarker(marker); + } + + if (selectedPositionId != null) { + selectPosition(null, selectedPositionId, false); + } + } + + public void showTrack(List positions) { + vectorLayer.destroyFeatures(); + + if (!positions.isEmpty()) { + Point[] linePoints = new Point[positions.size()]; + + int i = 0; + for (Position position : positions) { + linePoints[i++] = mapView.createPoint(position.getLongitude(), position.getLatitude()); + } + + LineString lineString = new LineString(linePoints); + vectorLayer.addFeature(new VectorFeature(lineString)); + //mapView.getMap().zoomToExtent(lineString.getBounds()); + } + } + + public void selectPosition(Position position, boolean center) { + selectPosition(selectedPositionId, position.getId(), center); + } + + public void selectDevice(Device device, boolean center) { + Long positionId = (device != null) ? deviceMap.get(device.getId()) : null; + selectPosition(selectedPositionId, positionId, center); + } + + private void selectPosition(Long oldPositionId, Long newPositionId, boolean center) { + if (oldPositionId != null && markerMap.containsKey(oldPositionId)) { + changeMarkerIcon(markerMap.get(oldPositionId), MarkerIconFactory.getIcon(iconType, false)); + selectedPositionId = null; + } + if (newPositionId != null && markerMap.containsKey(newPositionId)) { + Marker marker = markerMap.get(newPositionId); + changeMarkerIcon(marker, MarkerIconFactory.getIcon(iconType, true)); + if (center) { + mapView.getMap().panTo(marker.getLonLat()); + } + selectedPositionId = newPositionId; + } + } + +} diff --git a/src/org/traccar/web/client/view/MapView.java b/src/org/traccar/web/client/view/MapView.java index af38c44..a7d1dad 100644 --- a/src/org/traccar/web/client/view/MapView.java +++ b/src/org/traccar/web/client/view/MapView.java @@ -1,21 +1,19 @@ 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.geometry.Point; import org.gwtopenmaps.openlayers.client.layer.Markers; +import org.gwtopenmaps.openlayers.client.layer.MarkersOptions; import org.gwtopenmaps.openlayers.client.layer.OSM; +import org.gwtopenmaps.openlayers.client.layer.Vector; +import org.gwtopenmaps.openlayers.client.layer.VectorOptions; import org.traccar.web.shared.model.Device; import org.traccar.web.shared.model.Position; @@ -25,34 +23,7 @@ import com.google.gwt.event.logical.shared.ResizeHandler; import com.google.gwt.user.client.Command; import com.sencha.gxt.widget.core.client.ContentPanel; -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); - } - -} public class MapView { @@ -64,11 +35,30 @@ public class MapView { private MapWidget mapWidget; private Map map; + private Vector vectorLayer; 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()); + public Map getMap() { + return map; + } + + public Vector getVectorLayer() { + return vectorLayer; + } + + public Markers getMarkerLayer() { + return markerLayer; + } + + public LonLat createLonLat(double longitude, double latitude) { + LonLat lonLat = new LonLat(longitude, latitude); + lonLat.transform(new Projection("EPSG:4326").getProjectionCode(), map.getProjection()); + return lonLat; + } + + public Point createPoint(double x, double y) { + Point point = new Point(x, y); + point.transform(new Projection("EPSG:4326"), new Projection(map.getProjection())); return point; } @@ -78,6 +68,8 @@ public class MapView { MapOptions defaultMapOptions = new MapOptions(); defaultMapOptions.setNumZoomLevels(16); + defaultMapOptions.setProjection("EPSG:4326"); + defaultMapOptions.setDisplayProjection(new Projection("EPSG:4326")); mapWidget = new MapWidget("100%", "100%", defaultMapOptions); map = mapWidget.getMap(); @@ -85,12 +77,19 @@ public class MapView { OSM mapLayer = OSM.Mapnik("Mapnik"); mapLayer.setIsBaseLayer(true); - markerLayer = new Markers("Markers"); + VectorOptions vectorOptions = new VectorOptions(); + vectorOptions.setProjection("EPSG:4326"); + vectorLayer = new Vector("Vector", vectorOptions); + + MarkersOptions markersOptions = new MarkersOptions(); + markersOptions.setProjection("EPSG:4326"); + markerLayer = new Markers("Markers", markersOptions); map.addLayer(mapLayer); + map.addLayer(vectorLayer); map.addLayer(markerLayer); map.addControl(new ScaleLine()); - map.setCenter(createPoint(30, 60), 1); + map.setCenter(createLonLat(12.5, 41.9), 1); contentPanel.add(mapWidget); @@ -106,44 +105,30 @@ public class MapView { }); } }); + + latestPositionRenderer = new MapPositionRenderer(this, MarkerIconFactory.IconType.iconLatest); + archivePositionRenderer = new MapPositionRenderer(this, MarkerIconFactory.IconType.iconArchive); + } + + private final MapPositionRenderer latestPositionRenderer; + + private final MapPositionRenderer archivePositionRenderer; + + public void showLatestPositions(List positions) { + latestPositionRenderer.showPositions(positions); } - private AbstractMap markerMap = new HashMap(); - private Device selectedDevice; - - public void showPositions(List positions) { - markerMap.clear(); - markerLayer.clearMarkers(); - for (Position position : positions) { - Marker marker = new Marker( - createPoint(position.getLongitude(), position.getLatitude()), MarkerIconFactory.getLocationIcon()); - markerMap.put(position.getDevice().getId(), marker); - markerLayer.addMarker(marker); - } - if (selectedDevice != null) { - select(selectedDevice, false); - } + public void showArchivePositions(List positions) { + archivePositionRenderer.showTrack(positions); + archivePositionRenderer.showPositions(positions); } - private void changeMarkerIcon(Marker marker, Icon icon) { - Marker newMarker = new Marker(marker.getLonLat(), icon); - markerLayer.removeMarker(marker); - markerLayer.addMarker(newMarker); + public void selectDevice(Device device) { + latestPositionRenderer.selectDevice(device, true); } - public void select(Device device, boolean center) { - if (selectedDevice != null) { - changeMarkerIcon(markerMap.get(selectedDevice.getId()), MarkerIconFactory.getLocationIcon()); - selectedDevice = null; - } - if (device != null && markerMap.containsKey(device.getId())) { - Marker marker = markerMap.get(device.getId()); - if (center) { - map.panTo(marker.getLonLat()); - } - changeMarkerIcon(marker, MarkerIconFactory.getSelectedLocationIcon()); - selectedDevice = device; - } + public void selectArchivePosition(Position position) { + archivePositionRenderer.selectPosition(position, true); } } diff --git a/src/org/traccar/web/client/view/MarkerIconFactory.java b/src/org/traccar/web/client/view/MarkerIconFactory.java new file mode 100644 index 0000000..484a6a4 --- /dev/null +++ b/src/org/traccar/web/client/view/MarkerIconFactory.java @@ -0,0 +1,32 @@ +package org.traccar.web.client.view; + +import org.gwtopenmaps.openlayers.client.Icon; +import org.gwtopenmaps.openlayers.client.Pixel; +import org.gwtopenmaps.openlayers.client.Size; + +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 enum IconType { + iconLatest, + iconArchive + }; + + public static Icon getIcon(IconType type, boolean selected) { + if (type == IconType.iconLatest) { + return new Icon(selected ? iconGreen : iconRed, iconSize, iconOffset); + } else if (type == IconType.iconArchive) { + return new Icon(selected ? iconGold : iconBlue, iconSize, iconOffset); + } + return null; + } + +} -- cgit v1.2.3