aboutsummaryrefslogtreecommitdiff
path: root/modern
diff options
context:
space:
mode:
authorAnton Tananaev <anton.tananaev@gmail.com>2020-10-25 15:59:38 -0700
committerAnton Tananaev <anton.tananaev@gmail.com>2020-10-25 15:59:38 -0700
commit5df4c5743d7b501529d4e3823fe02184ef0259fe (patch)
tree646bb68e91595035aa589c120f81880f2f18987b /modern
parent2184bb6a9e98327f7d756b5977ae5315268f37b3 (diff)
downloadtrackermap-web-5df4c5743d7b501529d4e3823fe02184ef0259fe.tar.gz
trackermap-web-5df4c5743d7b501529d4e3823fe02184ef0259fe.tar.bz2
trackermap-web-5df4c5743d7b501529d4e3823fe02184ef0259fe.zip
Initial geofence implementation
Diffstat (limited to 'modern')
-rw-r--r--modern/package.json3
-rw-r--r--modern/src/map/GeofenceMap.js59
-rw-r--r--modern/src/map/mapUtil.js17
3 files changed, 78 insertions, 1 deletions
diff --git a/modern/package.json b/modern/package.json
index afba6a59..bd1dd33e 100644
--- a/modern/package.json
+++ b/modern/package.json
@@ -20,7 +20,8 @@
"react-router-dom": "^5.2.0",
"react-scripts": "^3.4.3",
"redux": "^4.0.5",
- "typeface-roboto": "0.0.75"
+ "typeface-roboto": "0.0.75",
+ "wellknown": "^0.5.0"
},
"scripts": {
"start": "craco start",
diff --git a/modern/src/map/GeofenceMap.js b/modern/src/map/GeofenceMap.js
new file mode 100644
index 00000000..965efaa5
--- /dev/null
+++ b/modern/src/map/GeofenceMap.js
@@ -0,0 +1,59 @@
+import wellknown from 'wellknown';
+import { useEffect, useState } from 'react';
+
+import { map } from './Map';
+import { useEffectAsync } from '../reactHelper';
+import { reverseCoordinates } from './mapUtil';
+
+const GeofenceMap = () => {
+ const id = 'geofences';
+
+ const [geofences, setGeofences] = useState([]);
+
+ useEffectAsync(async () => {
+ const response = await fetch('/api/geofences');
+ if (response.ok) {
+ setGeofences(await response.json());
+ }
+ }, []);
+
+ useEffect(() => {
+ map.addSource(id, {
+ 'type': 'geojson',
+ 'data': {
+ type: 'FeatureCollection',
+ features: []
+ }
+ });
+ map.addLayer({
+ 'id': id,
+ 'type': 'fill',
+ 'source': id,
+ 'layout': {},
+ 'paint': {
+ 'fill-color': '#088',
+ 'fill-opacity': 0.8
+ }
+ });
+
+ return () => {
+ map.removeLayer(id);
+ map.removeSource(id);
+ };
+ }, []);
+
+ useEffect(() => {
+ map.getSource(id).setData({
+ type: 'FeatureCollection',
+ features: geofences.map(item => [item.name, reverseCoordinates(wellknown(item.area))]).filter(([, geometry]) => !!geometry).map(([name, geometry]) => ({
+ type: 'Feature',
+ geometry: geometry,
+ properties: { name },
+ })),
+ });
+ }, [geofences]);
+
+ return null;
+}
+
+export default GeofenceMap;
diff --git a/modern/src/map/mapUtil.js b/modern/src/map/mapUtil.js
index 614234b5..71d7b3c9 100644
--- a/modern/src/map/mapUtil.js
+++ b/modern/src/map/mapUtil.js
@@ -50,3 +50,20 @@ export const calculateBounds = features => {
return null;
}
}
+
+export const reverseCoordinates = it => {
+ if (!it) {
+ return it;
+ } else if (Array.isArray(it)) {
+ if (it.length === 2 && !Number.isNaN(it[0]) && !Number.isNaN(it[1])) {
+ return [it[1], it[0]];
+ } else {
+ return it.map(it => reverseCoordinates(it));
+ }
+ } else {
+ return {
+ ...it,
+ coordinates: reverseCoordinates(it.coordinates),
+ }
+ }
+}