aboutsummaryrefslogtreecommitdiff
path: root/src/org/traccar/web/client/view/MapPositionRenderer.java
blob: bbe932a4f49686798ec445c75595a50506b2c814 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
/*
 * Copyright 2013 Anton Tananaev (anton.tananaev@gmail.com)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
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<Long, Marker> markerMap = new HashMap<Long, Marker>(); // Position.id -> Marker
    private Map<Long, Long> deviceMap = new HashMap<Long, Long>(); // Device.id -> Position.id

    private Long selectedPositionId;

    public void showPositions(List<Position> 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<Position> 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;
        }
    }

}