diff options
author | Anton Tananaev <anton@traccar.org> | 2022-08-17 07:03:25 -0700 |
---|---|---|
committer | Anton Tananaev <anton@traccar.org> | 2022-08-17 07:03:25 -0700 |
commit | 6ec5eaf47904fbec5ac7ecd1939291e3aab60530 (patch) | |
tree | 599a59cdcbce26207090662f97ad4e8073a26c09 /modern/src | |
parent | 13eaaebb02814e539648c3bc545c3e3d07f204c3 (diff) | |
download | trackermap-web-6ec5eaf47904fbec5ac7ecd1939291e3aab60530.tar.gz trackermap-web-6ec5eaf47904fbec5ac7ecd1939291e3aab60530.tar.bz2 trackermap-web-6ec5eaf47904fbec5ac7ecd1939291e3aab60530.zip |
Geofences on most maps
Diffstat (limited to 'modern/src')
-rw-r--r-- | modern/src/main/MainPage.js | 5 | ||||
-rw-r--r-- | modern/src/map/MapGeofence.js | 92 | ||||
-rw-r--r-- | modern/src/map/main/MapGeofence.js | 86 | ||||
-rw-r--r-- | modern/src/other/EventPage.js | 2 | ||||
-rw-r--r-- | modern/src/other/ReplayPage.js | 2 | ||||
-rw-r--r-- | modern/src/reports/RouteReportPage.js | 2 | ||||
-rw-r--r-- | modern/src/reports/StopReportPage.js | 2 | ||||
-rw-r--r-- | modern/src/reports/TripReportPage.js | 2 |
8 files changed, 104 insertions, 89 deletions
diff --git a/modern/src/main/MainPage.js b/modern/src/main/MainPage.js index bcd62c7d..c42b5be5 100644 --- a/modern/src/main/MainPage.js +++ b/modern/src/main/MainPage.js @@ -19,7 +19,7 @@ import DevicesList from './DevicesList'; import MapView from '../map/core/MapView'; import MapSelectedDevice from '../map/main/MapSelectedDevice'; import MapAccuracy from '../map/main/MapAccuracy'; -import MapGeofence from '../map/main/MapGeofence'; +import MapGeofence from '../map/MapGeofence'; import MapCurrentLocation from '../map/MapCurrentLocation'; import BottomMenu from '../common/components/BottomMenu'; import { useTranslation } from '../common/components/LocalizationProvider'; @@ -148,7 +148,6 @@ const MainPage = () => { const [mapOnSelect] = usePersistedState('mapOnSelect', false); - const [mapGeofences] = usePersistedState('mapGeofences', true); const [mapLiveRoutes] = usePersistedState('mapLiveRoutes', false); const selectedDeviceId = useSelector((state) => state.devices.selectedId); @@ -230,7 +229,7 @@ const MainPage = () => { <div className={classes.root}> <MapView> <MapOverlay /> - {mapGeofences && <MapGeofence />} + <MapGeofence /> <MapAccuracy positions={filteredPositions} /> {mapLiveRoutes && <MapLiveRoutes />} <MapPositions positions={filteredPositions} onClick={onClick} showStatus /> diff --git a/modern/src/map/MapGeofence.js b/modern/src/map/MapGeofence.js new file mode 100644 index 00000000..31554f11 --- /dev/null +++ b/modern/src/map/MapGeofence.js @@ -0,0 +1,92 @@ +import { useId, useEffect } from 'react'; +import { useSelector } from 'react-redux'; +import { useTheme } from '@mui/styles'; +import { map } from './core/MapView'; +import { findFonts, geofenceToFeature } from './core/mapUtil'; +import usePersistedState from '../common/util/usePersistedState'; + +const MapGeofence = () => { + const id = useId(); + + const theme = useTheme(); + + const [mapGeofences] = usePersistedState('mapGeofences', true); + + const geofences = useSelector((state) => state.geofences.items); + + useEffect(() => { + if (mapGeofences) { + map.addSource(id, { + type: 'geojson', + data: { + type: 'FeatureCollection', + features: [], + }, + }); + map.addLayer({ + source: id, + id: 'geofences-fill', + type: 'fill', + filter: [ + 'all', + ['==', '$type', 'Polygon'], + ], + paint: { + 'fill-color': ['get', 'color'], + 'fill-outline-color': ['get', 'color'], + 'fill-opacity': 0.1, + }, + }); + map.addLayer({ + source: id, + id: 'geofences-line', + type: 'line', + paint: { + 'line-color': ['get', 'color'], + 'line-width': 2, + }, + }); + map.addLayer({ + source: id, + id: 'geofences-title', + type: 'symbol', + layout: { + 'text-field': '{name}', + 'text-font': findFonts(map), + 'text-size': 12, + }, + paint: { + 'text-halo-color': 'white', + 'text-halo-width': 1, + }, + }); + + return () => { + if (map.getLayer('geofences-fill')) { + map.removeLayer('geofences-fill'); + } + if (map.getLayer('geofences-line')) { + map.removeLayer('geofences-line'); + } + if (map.getLayer('geofences-title')) { + map.removeLayer('geofences-title'); + } + if (map.getSource(id)) { + map.removeSource(id); + } + }; + } + return () => {}; + }, [mapGeofences]); + + useEffect(() => { + map.getSource(id).setData({ + type: 'FeatureCollection', + features: Object.values(geofences).map((geofence) => geofenceToFeature(theme, geofence)), + }); + }, [geofences]); + + return null; +}; + +export default MapGeofence; diff --git a/modern/src/map/main/MapGeofence.js b/modern/src/map/main/MapGeofence.js deleted file mode 100644 index 6cfe9b61..00000000 --- a/modern/src/map/main/MapGeofence.js +++ /dev/null @@ -1,86 +0,0 @@ -import { useId, useEffect } from 'react'; -import { useSelector } from 'react-redux'; -import { useTheme } from '@mui/styles'; -import { map } from '../core/MapView'; -import { findFonts, geofenceToFeature } from '../core/mapUtil'; - -const MapGeofence = () => { - const id = useId(); - - const theme = useTheme(); - - const geofences = useSelector((state) => state.geofences.items); - - useEffect(() => { - map.addSource(id, { - type: 'geojson', - data: { - type: 'FeatureCollection', - features: [], - }, - }); - map.addLayer({ - source: id, - id: 'geofences-fill', - type: 'fill', - filter: [ - 'all', - ['==', '$type', 'Polygon'], - ], - paint: { - 'fill-color': ['get', 'color'], - 'fill-outline-color': ['get', 'color'], - 'fill-opacity': 0.1, - }, - }); - map.addLayer({ - source: id, - id: 'geofences-line', - type: 'line', - paint: { - 'line-color': ['get', 'color'], - 'line-width': 2, - }, - }); - map.addLayer({ - source: id, - id: 'geofences-title', - type: 'symbol', - layout: { - 'text-field': '{name}', - 'text-font': findFonts(map), - 'text-size': 12, - }, - paint: { - 'text-halo-color': 'white', - 'text-halo-width': 1, - }, - }); - - return () => { - if (map.getLayer('geofences-fill')) { - map.removeLayer('geofences-fill'); - } - if (map.getLayer('geofences-line')) { - map.removeLayer('geofences-line'); - } - if (map.getLayer('geofences-title')) { - map.removeLayer('geofences-title'); - } - if (map.getSource(id)) { - map.removeSource(id); - } - }; - }, []); - - useEffect(() => { - map.getSource(id).setData({ - type: 'FeatureCollection', - features: Object.values(geofences).map((geofence) => geofenceToFeature(theme, geofence)), - }); - }, [geofences]); - - return null; -}; - -export default MapGeofence; diff --git a/modern/src/other/EventPage.js b/modern/src/other/EventPage.js index 7f5d32ba..7bd5be30 100644 --- a/modern/src/other/EventPage.js +++ b/modern/src/other/EventPage.js @@ -11,6 +11,7 @@ import { useTranslation } from '../common/components/LocalizationProvider'; import MapView from '../map/core/MapView'; import MapCamera from '../map/MapCamera'; import MapPositions from '../map/MapPositions'; +import MapGeofence from '../map/MapGeofence'; const useStyles = makeStyles(() => ({ root: { @@ -70,6 +71,7 @@ const EventPage = () => { </AppBar> <div className={classes.mapContainer}> <MapView> + <MapGeofence /> {position && <MapPositions positions={[position]} />} </MapView> {position && <MapCamera latitude={position.latitude} longitude={position.longitude} />} diff --git a/modern/src/other/ReplayPage.js b/modern/src/other/ReplayPage.js index 556f5a87..46f7571c 100644 --- a/modern/src/other/ReplayPage.js +++ b/modern/src/other/ReplayPage.js @@ -22,6 +22,7 @@ import ReportFilter from '../reports/components/ReportFilter'; import { useTranslation } from '../common/components/LocalizationProvider'; import { useCatch } from '../reactHelper'; import MapCamera from '../map/MapCamera'; +import MapGeofence from '../map/MapGeofence'; const useStyles = makeStyles((theme) => ({ root: { @@ -151,6 +152,7 @@ const ReplayPage = () => { return ( <div className={classes.root}> <MapView> + <MapGeofence /> <MapRoutePath positions={positions} /> {index < positions.length && ( <MapPositions positions={[positions[index]]} onClick={onClick} /> diff --git a/modern/src/reports/RouteReportPage.js b/modern/src/reports/RouteReportPage.js index bce63e31..a37ad7b1 100644 --- a/modern/src/reports/RouteReportPage.js +++ b/modern/src/reports/RouteReportPage.js @@ -20,6 +20,7 @@ import MapPositions from '../map/MapPositions'; import useReportStyles from './common/useReportStyles'; import TableShimmer from '../common/components/TableShimmer'; import MapCamera from '../map/MapCamera'; +import MapGeofence from '../map/MapGeofence'; const RouteReportPage = () => { const classes = useReportStyles(); @@ -67,6 +68,7 @@ const RouteReportPage = () => { {selectedItem && ( <div className={classes.containerMap}> <MapView> + <MapGeofence /> {[...new Set(items.map((it) => it.deviceId))].map((deviceId) => ( <MapRoutePath key={deviceId} positions={items.filter((position) => position.deviceId === deviceId)} /> ))} diff --git a/modern/src/reports/StopReportPage.js b/modern/src/reports/StopReportPage.js index 5d6e837d..36c4d124 100644 --- a/modern/src/reports/StopReportPage.js +++ b/modern/src/reports/StopReportPage.js @@ -22,6 +22,7 @@ import MapView from '../map/core/MapView'; import MapCamera from '../map/MapCamera'; import AddressValue from '../common/components/AddressValue'; import TableShimmer from '../common/components/TableShimmer'; +import MapGeofence from '../map/MapGeofence'; const columnsArray = [ ['startTime', 'reportStartTime'], @@ -98,6 +99,7 @@ const StopReportPage = () => { {selectedItem && ( <div className={classes.containerMap}> <MapView> + <MapGeofence /> <MapPositions positions={[{ deviceId: selectedItem.deviceId, latitude: selectedItem.latitude, diff --git a/modern/src/reports/TripReportPage.js b/modern/src/reports/TripReportPage.js index 7fa98a6c..63988850 100644 --- a/modern/src/reports/TripReportPage.js +++ b/modern/src/reports/TripReportPage.js @@ -22,6 +22,7 @@ import AddressValue from '../common/components/AddressValue'; import TableShimmer from '../common/components/TableShimmer'; import MapMarkers from '../map/MapMarkers'; import MapCamera from '../map/MapCamera'; +import MapGeofence from '../map/MapGeofence'; const columnsArray = [ ['startTime', 'reportStartTime'], @@ -145,6 +146,7 @@ const TripReportPage = () => { {selectedItem && ( <div className={classes.containerMap}> <MapView> + <MapGeofence /> {route && ( <> <MapRoutePath positions={route} /> |