aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnton Tananaev <anton@traccar.org>2022-08-17 07:03:25 -0700
committerAnton Tananaev <anton@traccar.org>2022-08-17 07:03:25 -0700
commit6ec5eaf47904fbec5ac7ecd1939291e3aab60530 (patch)
tree599a59cdcbce26207090662f97ad4e8073a26c09
parent13eaaebb02814e539648c3bc545c3e3d07f204c3 (diff)
downloadtrackermap-web-6ec5eaf47904fbec5ac7ecd1939291e3aab60530.tar.gz
trackermap-web-6ec5eaf47904fbec5ac7ecd1939291e3aab60530.tar.bz2
trackermap-web-6ec5eaf47904fbec5ac7ecd1939291e3aab60530.zip
Geofences on most maps
-rw-r--r--modern/src/main/MainPage.js5
-rw-r--r--modern/src/map/MapGeofence.js92
-rw-r--r--modern/src/map/main/MapGeofence.js86
-rw-r--r--modern/src/other/EventPage.js2
-rw-r--r--modern/src/other/ReplayPage.js2
-rw-r--r--modern/src/reports/RouteReportPage.js2
-rw-r--r--modern/src/reports/StopReportPage.js2
-rw-r--r--modern/src/reports/TripReportPage.js2
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} />