aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnton Tananaev <anton@traccar.org>2022-10-28 17:53:24 -0700
committerAnton Tananaev <anton@traccar.org>2022-10-28 17:53:24 -0700
commit06c98c0b8216bbba5bf971cb92138741df03f1c4 (patch)
tree431c7e29649ed3824a26c01615904fa9cce81375
parent080164d310c9f789b400e9909c12423bf31ef79c (diff)
downloadtrackermap-web-06c98c0b8216bbba5bf971cb92138741df03f1c4.tar.gz
trackermap-web-06c98c0b8216bbba5bf971cb92138741df03f1c4.tar.bz2
trackermap-web-06c98c0b8216bbba5bf971cb92138741df03f1c4.zip
Improve live routes (fix #1017)
-rw-r--r--modern/src/main/MainMap.js5
-rw-r--r--modern/src/map/MapRoutePath.js2
-rw-r--r--modern/src/map/main/MapLiveRoutes.js118
-rw-r--r--modern/src/store/session.js2
4 files changed, 62 insertions, 65 deletions
diff --git a/modern/src/main/MainMap.js b/modern/src/main/MainMap.js
index 07bb3c42..273a7787 100644
--- a/modern/src/main/MainMap.js
+++ b/modern/src/main/MainMap.js
@@ -18,7 +18,6 @@ import MapGeocoder from '../map/geocoder/MapGeocoder';
import MapScale from '../map/MapScale';
import MapNotification from '../map/notification/MapNotification';
import useFeatures from '../common/util/useFeatures';
-import { useAttributePreference } from '../common/util/preferences';
const MainMap = ({ filteredPositions, selectedPosition, onEventsClick }) => {
const theme = useTheme();
@@ -30,8 +29,6 @@ const MainMap = ({ filteredPositions, selectedPosition, onEventsClick }) => {
const features = useFeatures();
- const mapLiveRoutes = useAttributePreference('mapLiveRoutes', 'none');
-
const onMarkerClick = useCallback((_, deviceId) => {
dispatch(devicesActions.select(deviceId));
}, [dispatch]);
@@ -42,7 +39,7 @@ const MainMap = ({ filteredPositions, selectedPosition, onEventsClick }) => {
<MapOverlay />
<MapGeofence />
<MapAccuracy positions={filteredPositions} />
- {mapLiveRoutes !== 'none' && <MapLiveRoutes />}
+ <MapLiveRoutes />
<MapPositions
positions={filteredPositions}
onClick={onMarkerClick}
diff --git a/modern/src/map/MapRoutePath.js b/modern/src/map/MapRoutePath.js
index 22f8d335..0eb48bdc 100644
--- a/modern/src/map/MapRoutePath.js
+++ b/modern/src/map/MapRoutePath.js
@@ -69,7 +69,7 @@ const MapRoutePath = ({ positions }) => {
color: reportColor,
},
});
- }, [positions, reportColor]);
+ }, [theme, positions, reportColor]);
return null;
};
diff --git a/modern/src/map/main/MapLiveRoutes.js b/modern/src/map/main/MapLiveRoutes.js
index 55a04606..397d8c52 100644
--- a/modern/src/map/main/MapLiveRoutes.js
+++ b/modern/src/map/main/MapLiveRoutes.js
@@ -1,8 +1,7 @@
-import { useId, useEffect, useState } from 'react';
+import { useId, useEffect } from 'react';
import { useSelector } from 'react-redux';
import { useTheme } from '@mui/styles';
import { map } from '../core/MapView';
-import { usePrevious } from '../../reactHelper';
import { useAttributePreference } from '../../common/util/preferences';
const MapLiveRoutes = () => {
@@ -10,74 +9,73 @@ const MapLiveRoutes = () => {
const theme = useTheme();
- const liveRouteLength = useAttributePreference('web.liveRouteLength', 10);
+ const type = useAttributePreference('mapLiveRoutes', 'none');
+ const devices = useSelector((state) => state.devices.items);
const selectedDeviceId = useSelector((state) => state.devices.selectedId);
- const currentDeviceId = usePrevious(selectedDeviceId);
- const position = useSelector((state) => state.session.positions[selectedDeviceId]);
-
- const [route, setRoute] = useState([]);
+ const history = useSelector((state) => state.session.history);
useEffect(() => {
- map.addSource(id, {
- type: 'geojson',
- data: {
- type: 'Feature',
- geometry: {
- type: 'LineString',
- coordinates: [],
+ if (type !== 'none') {
+ map.addSource(id, {
+ type: 'geojson',
+ data: {
+ type: 'Feature',
+ geometry: {
+ type: 'LineString',
+ coordinates: [],
+ },
},
- },
- });
- map.addLayer({
- source: id,
- id,
- type: 'line',
- layout: {
- 'line-join': 'round',
- 'line-cap': 'round',
- },
- paint: {
- 'line-color': theme.palette.colors.geometry,
- 'line-width': 2,
- },
- });
-
- return () => {
- if (map.getLayer(id)) {
- map.removeLayer(id);
- }
- if (map.getSource(id)) {
- map.removeSource(id);
- }
- };
- }, []);
+ });
+ map.addLayer({
+ source: id,
+ id,
+ type: 'line',
+ layout: {
+ 'line-join': 'round',
+ 'line-cap': 'round',
+ },
+ paint: {
+ 'line-color': ['get', 'color'],
+ 'line-width': 2,
+ },
+ });
- useEffect(() => {
- if (selectedDeviceId !== currentDeviceId) {
- if (!selectedDeviceId) {
- setRoute([]);
- } else if (position) {
- setRoute([position]);
- }
- } else if (position) {
- const last = route.at(-1);
- if (!last || (last.latitude !== position.latitude && last.longitude !== position.longitude)) {
- setRoute([...route.slice(1 - liveRouteLength), position]);
- }
+ return () => {
+ if (map.getLayer(id)) {
+ map.removeLayer(id);
+ }
+ if (map.getSource(id)) {
+ map.removeSource(id);
+ }
+ };
}
- }, [selectedDeviceId, currentDeviceId, position, route]);
+ return () => {};
+ }, [type]);
useEffect(() => {
- map.getSource(id).setData({
- type: 'Feature',
- geometry: {
- type: 'LineString',
- coordinates: route.map((item) => [item.longitude, item.latitude]),
- },
- });
- }, [route]);
+ if (type !== 'none') {
+ const deviceIds = Object.values(devices)
+ .map((device) => device.id)
+ .filter((id) => (type === 'selected' ? id === selectedDeviceId : true))
+ .filter((id) => history.hasOwnProperty(id));
+
+ map.getSource(id).setData({
+ type: 'FeatureCollection',
+ features: deviceIds.map((deviceId) => ({
+ type: 'Feature',
+ geometry: {
+ type: 'LineString',
+ coordinates: history[deviceId],
+ },
+ properties: {
+ color: devices[deviceId].attributes['web.reportColor'] || theme.palette.colors.geometry,
+ },
+ })),
+ });
+ }
+ }, [theme, type, devices, selectedDeviceId, history]);
return null;
};
diff --git a/modern/src/store/session.js b/modern/src/store/session.js
index 121b47f5..1d8b2a22 100644
--- a/modern/src/store/session.js
+++ b/modern/src/store/session.js
@@ -30,6 +30,8 @@ const { reducer, actions } = createSlice({
if (!last || (last[0] !== position.longitude && last[1] !== position.latitude)) {
state.history[position.deviceId] = [...route.slice(1 - liveRoutesLimit), [position.longitude, position.latitude]];
}
+ } else {
+ state.history = {};
}
});
},