aboutsummaryrefslogtreecommitdiff
path: root/modern/src/map
diff options
context:
space:
mode:
Diffstat (limited to 'modern/src/map')
-rw-r--r--modern/src/map/AccuracyMap.js36
-rw-r--r--modern/src/map/CurrentLocationMap.js2
-rw-r--r--modern/src/map/CurrentPositionsMap.js6
-rw-r--r--modern/src/map/GeofenceEditMap.js36
-rw-r--r--modern/src/map/GeofenceMap.js56
-rw-r--r--modern/src/map/Map.js33
-rw-r--r--modern/src/map/PositionsMap.js71
-rw-r--r--modern/src/map/ReplayPathMap.js28
-rw-r--r--modern/src/map/SelectedDeviceMap.js4
-rw-r--r--modern/src/map/StatusView.js65
-rw-r--r--modern/src/map/mapStyles.js42
-rw-r--r--modern/src/map/mapUtil.js57
-rw-r--r--modern/src/map/switcher/switcher.js5
13 files changed, 240 insertions, 201 deletions
diff --git a/modern/src/map/AccuracyMap.js b/modern/src/map/AccuracyMap.js
index e81fc8f..4baa105 100644
--- a/modern/src/map/AccuracyMap.js
+++ b/modern/src/map/AccuracyMap.js
@@ -7,33 +7,31 @@ import { map } from './Map';
const AccuracyMap = () => {
const id = 'accuracy';
- const positions = useSelector(state => ({
+ const positions = useSelector((state) => ({
type: 'FeatureCollection',
- features: Object.values(state.positions.items).filter(position => position.accuracy > 0).map(position =>
- circle([position.longitude, position.latitude], position.accuracy * 0.001)
- ),
+ features: Object.values(state.positions.items).filter((position) => position.accuracy > 0).map((position) => circle([position.longitude, position.latitude], position.accuracy * 0.001)),
}));
useEffect(() => {
map.addSource(id, {
- 'type': 'geojson',
- 'data': {
+ type: 'geojson',
+ data: {
type: 'FeatureCollection',
- features: []
- }
+ features: [],
+ },
});
map.addLayer({
- 'source': id,
- 'id': id,
- 'type': 'fill',
- 'filter': [
- 'all',
- ['==', '$type', 'Polygon'],
+ source: id,
+ id,
+ type: 'fill',
+ filter: [
+ 'all',
+ ['==', '$type', 'Polygon'],
],
- 'paint': {
- 'fill-color':'#3bb2d0',
- 'fill-outline-color':'#3bb2d0',
- 'fill-opacity':0.25,
+ paint: {
+ 'fill-color': '#3bb2d0',
+ 'fill-outline-color': '#3bb2d0',
+ 'fill-opacity': 0.25,
},
});
@@ -48,6 +46,6 @@ const AccuracyMap = () => {
}, [positions]);
return null;
-}
+};
export default AccuracyMap;
diff --git a/modern/src/map/CurrentLocationMap.js b/modern/src/map/CurrentLocationMap.js
index 06aaad0..69724ce 100644
--- a/modern/src/map/CurrentLocationMap.js
+++ b/modern/src/map/CurrentLocationMap.js
@@ -16,6 +16,6 @@ const CurrentLocationMap = () => {
}, []);
return null;
-}
+};
export default CurrentLocationMap;
diff --git a/modern/src/map/CurrentPositionsMap.js b/modern/src/map/CurrentPositionsMap.js
index 0bfe4fc..9e00774 100644
--- a/modern/src/map/CurrentPositionsMap.js
+++ b/modern/src/map/CurrentPositionsMap.js
@@ -1,11 +1,11 @@
-import React, { } from 'react';
+import React, { } from 'react';
import { useSelector } from 'react-redux';
import PositionsMap from './PositionsMap';
const CurrentPositionsMap = () => {
- const positions = useSelector(state => Object.values(state.positions.items));
+ const positions = useSelector((state) => Object.values(state.positions.items));
return (<PositionsMap positions={positions} />);
-}
+};
export default CurrentPositionsMap;
diff --git a/modern/src/map/GeofenceEditMap.js b/modern/src/map/GeofenceEditMap.js
index fe84338..d639c19 100644
--- a/modern/src/map/GeofenceEditMap.js
+++ b/modern/src/map/GeofenceEditMap.js
@@ -1,13 +1,13 @@
-import '@mapbox/mapbox-gl-draw/dist/mapbox-gl-draw.css'
+import '@mapbox/mapbox-gl-draw/dist/mapbox-gl-draw.css';
import MapboxDraw from '@mapbox/mapbox-gl-draw';
import theme from '@mapbox/mapbox-gl-draw/src/lib/theme';
import { useEffect } from 'react';
+import { useDispatch, useSelector } from 'react-redux';
+import { useHistory } from 'react-router-dom';
import { map } from './Map';
import { geofenceToFeature, geometryToArea } from './mapUtil';
-import { useDispatch, useSelector } from 'react-redux';
import { geofencesActions } from '../store';
-import { useHistory } from 'react-router-dom';
const draw = new MapboxDraw({
displayControlsDefault: false,
@@ -17,15 +17,15 @@ const draw = new MapboxDraw({
},
userProperties: true,
styles: [...theme, {
- 'id': 'gl-draw-title',
- 'type': 'symbol',
- 'filter': ['all'],
- 'layout': {
+ id: 'gl-draw-title',
+ type: 'symbol',
+ filter: ['all'],
+ layout: {
'text-field': '{user_name}',
'text-font': ['Roboto Regular'],
'text-size': 12,
},
- 'paint': {
+ paint: {
'text-halo-color': 'white',
'text-halo-width': 1,
},
@@ -36,25 +36,25 @@ const GeofenceEditMap = () => {
const dispatch = useDispatch();
const history = useHistory();
- const geofences = useSelector(state => Object.values(state.geofences.items));
+ const geofences = useSelector((state) => Object.values(state.geofences.items));
const refreshGeofences = async () => {
const response = await fetch('/api/geofences');
if (response.ok) {
dispatch(geofencesActions.refresh(await response.json()));
}
- }
+ };
useEffect(() => {
refreshGeofences();
map.addControl(draw, 'top-left');
- map.on('draw.create', async event => {
+ map.on('draw.create', async (event) => {
const feature = event.features[0];
const newItem = { name: '', area: geometryToArea(feature.geometry) };
draw.delete(feature.id);
- const response = await fetch(`/api/geofences`, {
+ const response = await fetch('/api/geofences', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(newItem),
@@ -65,7 +65,7 @@ const GeofenceEditMap = () => {
}
});
- map.on('draw.delete', async event => {
+ map.on('draw.delete', async (event) => {
const feature = event.features[0];
const response = await fetch(`/api/geofences/${feature.id}`, { method: 'DELETE' });
if (response.ok) {
@@ -73,9 +73,9 @@ const GeofenceEditMap = () => {
}
});
- map.on('draw.update', async event => {
+ map.on('draw.update', async (event) => {
const feature = event.features[0];
- const item = geofences.find(i => i.id === feature.id);
+ const item = geofences.find((i) => i.id === feature.id);
if (item) {
const updatedItem = { ...item, area: geometryToArea(feature.geometry) };
const response = await fetch(`/api/geofences/${feature.id}`, {
@@ -94,12 +94,12 @@ const GeofenceEditMap = () => {
useEffect(() => {
draw.deleteAll();
- for (const geofence of geofences) {
+ geofences.forEach((geofence) => {
draw.add(geofenceToFeature(geofence));
- }
+ });
}, [geofences]);
return null;
-}
+};
export default GeofenceEditMap;
diff --git a/modern/src/map/GeofenceMap.js b/modern/src/map/GeofenceMap.js
index 8db175a..d00cbb1 100644
--- a/modern/src/map/GeofenceMap.js
+++ b/modern/src/map/GeofenceMap.js
@@ -7,49 +7,49 @@ import { geofenceToFeature } from './mapUtil';
const GeofenceMap = () => {
const id = 'geofences';
- const geofences = useSelector(state => Object.values(state.geofences.items));
+ const geofences = useSelector((state) => Object.values(state.geofences.items));
useEffect(() => {
map.addSource(id, {
- 'type': 'geojson',
- 'data': {
+ type: 'geojson',
+ data: {
type: 'FeatureCollection',
- features: []
- }
+ features: [],
+ },
});
map.addLayer({
- 'source': id,
- 'id': 'geofences-fill',
- 'type': 'fill',
- 'filter': [
- 'all',
- ['==', '$type', 'Polygon'],
+ source: id,
+ id: 'geofences-fill',
+ type: 'fill',
+ filter: [
+ 'all',
+ ['==', '$type', 'Polygon'],
],
- 'paint': {
- 'fill-color':'#3bb2d0',
- 'fill-outline-color':'#3bb2d0',
- 'fill-opacity':0.1,
+ paint: {
+ 'fill-color': '#3bb2d0',
+ 'fill-outline-color': '#3bb2d0',
+ 'fill-opacity': 0.1,
},
});
map.addLayer({
- 'source': id,
- 'id': 'geofences-line',
- 'type': 'line',
- 'paint': {
- 'line-color': '#3bb2d0',
- 'line-width': 2,
+ source: id,
+ id: 'geofences-line',
+ type: 'line',
+ paint: {
+ 'line-color': '#3bb2d0',
+ 'line-width': 2,
},
});
map.addLayer({
- 'source': id,
- 'id': 'geofences-title',
- 'type': 'symbol',
- 'layout': {
+ source: id,
+ id: 'geofences-title',
+ type: 'symbol',
+ layout: {
'text-field': '{name}',
'text-font': ['Roboto Regular'],
'text-size': 12,
},
- 'paint': {
+ paint: {
'text-halo-color': 'white',
'text-halo-width': 1,
},
@@ -66,11 +66,11 @@ const GeofenceMap = () => {
useEffect(() => {
map.getSource(id).setData({
type: 'FeatureCollection',
- features: geofences.map(geofenceToFeature)
+ features: geofences.map(geofenceToFeature),
});
}, [geofences]);
return null;
-}
+};
export default GeofenceMap;
diff --git a/modern/src/map/Map.js b/modern/src/map/Map.js
index 46c59d2..7dd1c2a 100644
--- a/modern/src/map/Map.js
+++ b/modern/src/map/Map.js
@@ -1,9 +1,11 @@
import 'maplibre-gl/dist/maplibre-gl.css';
import './switcher/switcher.css';
import maplibregl from 'maplibre-gl';
+import React, {
+ useRef, useLayoutEffect, useEffect, useState,
+} from 'react';
import { SwitcherControl } from './switcher/switcher';
-import React, { useRef, useLayoutEffect, useEffect, useState } from 'react';
-import { deviceCategories } from '../common/deviceCategories';
+import deviceCategories from '../common/deviceCategories';
import { prepareIcon, loadImage } from './mapUtil';
import { styleCarto, styleMapbox, styleOsm } from './mapStyles';
import t from '../common/localization';
@@ -22,18 +24,18 @@ export const map = new maplibregl.Map({
let ready = false;
const readyListeners = new Set();
-const addReadyListener = listener => {
+const addReadyListener = (listener) => {
readyListeners.add(listener);
listener(ready);
};
-const removeReadyListener = listener => {
+const removeReadyListener = (listener) => {
readyListeners.delete(listener);
};
-const updateReadyValue = value => {
+const updateReadyValue = (value) => {
ready = value;
- readyListeners.forEach(listener => listener(value));
+ readyListeners.forEach((listener) => listener(value));
};
const initMap = async () => {
@@ -42,13 +44,16 @@ const initMap = async () => {
map.addImage('background', await prepareIcon(background), {
pixelRatio: window.devicePixelRatio,
});
- await Promise.all(deviceCategories.map(async category => {
- for (const color of ['green', 'red', 'gray']) {
- const icon = await loadImage(`images/icon/${category}.svg`);
- map.addImage(`${category}-${color}`, prepareIcon(background, icon, palette.common[color]), {
- pixelRatio: window.devicePixelRatio,
- });
- }
+ await Promise.all(deviceCategories.map(async (category) => {
+ const results = [];
+ ['green', 'red', 'gray'].forEach((color) => {
+ results.push(loadImage(`images/icon/${category}.svg`).then((icon) => {
+ map.addImage(`${category}-${color}`, prepareIcon(background, icon, palette.common[color]), {
+ pixelRatio: window.devicePixelRatio,
+ });
+ }));
+ });
+ await Promise.all(results);
}));
updateReadyValue(true);
};
@@ -93,7 +98,7 @@ const Map = ({ children }) => {
}, [mapboxAccessToken]);
useEffect(() => {
- const listener = ready => setMapReady(ready);
+ const listener = (ready) => setMapReady(ready);
addReadyListener(listener);
return () => {
removeReadyListener(listener);
diff --git a/modern/src/map/PositionsMap.js b/modern/src/map/PositionsMap.js
index 35d6d92..2de01d2 100644
--- a/modern/src/map/PositionsMap.js
+++ b/modern/src/map/PositionsMap.js
@@ -3,9 +3,9 @@ import ReactDOM from 'react-dom';
import maplibregl from 'maplibre-gl';
import { Provider, useSelector } from 'react-redux';
+import { useHistory } from 'react-router-dom';
import { map } from './Map';
import store from '../store';
-import { useHistory } from 'react-router-dom';
import StatusView from './StatusView';
const PositionsMap = ({ positions }) => {
@@ -13,9 +13,9 @@ const PositionsMap = ({ positions }) => {
const clusters = `${id}-clusters`;
const history = useHistory();
- const devices = useSelector(state => state.devices.items);
+ const devices = useSelector((state) => state.devices.items);
- const deviceColor = device => {
+ const deviceColor = (device) => {
switch (device.status) {
case 'online':
return 'green';
@@ -33,15 +33,15 @@ const PositionsMap = ({ positions }) => {
name: device.name,
category: device.category || 'default',
color: deviceColor(device),
- }
+ };
};
const onMouseEnter = () => map.getCanvas().style.cursor = 'pointer';
const onMouseLeave = () => map.getCanvas().style.cursor = '';
- const onMarkerClick = useCallback(event => {
+ const onMarkerClick = useCallback((event) => {
const feature = event.features[0];
- let coordinates = feature.geometry.coordinates.slice();
+ const coordinates = feature.geometry.coordinates.slice();
while (Math.abs(event.lngLat.lng - coordinates[0]) > 180) {
coordinates[0] += event.lngLat.lng > coordinates[0] ? 360 : -360;
}
@@ -49,50 +49,52 @@ const PositionsMap = ({ positions }) => {
const placeholder = document.createElement('div');
ReactDOM.render(
<Provider store={store}>
- <StatusView deviceId={feature.properties.deviceId} onShowDetails={positionId => history.push(`/position/${positionId}`)} />
+ <StatusView deviceId={feature.properties.deviceId} onShowDetails={(positionId) => history.push(`/position/${positionId}`)} />
</Provider>,
- placeholder
+ placeholder,
);
new maplibregl.Popup({
offset: 25,
- anchor: 'top'
+ anchor: 'top',
})
.setDOMContent(placeholder)
.setLngLat(coordinates)
.addTo(map);
}, [history]);
- const onClusterClick = event => {
+ const onClusterClick = (event) => {
const features = map.queryRenderedFeatures(event.point, {
layers: [clusters],
});
const clusterId = features[0].properties.cluster_id;
map.getSource(id).getClusterExpansionZoom(clusterId, (error, zoom) => {
- if (!error) map.easeTo({
- center: features[0].geometry.coordinates,
- zoom: zoom,
- });
+ if (!error) {
+ map.easeTo({
+ center: features[0].geometry.coordinates,
+ zoom,
+ });
+ }
});
};
useEffect(() => {
map.addSource(id, {
- 'type': 'geojson',
- 'data': {
+ type: 'geojson',
+ data: {
type: 'FeatureCollection',
features: [],
},
- 'cluster': true,
- 'clusterMaxZoom': 14,
- 'clusterRadius': 50,
+ cluster: true,
+ clusterMaxZoom: 14,
+ clusterRadius: 50,
});
map.addLayer({
- 'id': id,
- 'type': 'symbol',
- 'source': id,
- 'filter': ['!', ['has', 'point_count']],
- 'layout': {
+ id,
+ type: 'symbol',
+ source: id,
+ filter: ['!', ['has', 'point_count']],
+ layout: {
'icon-image': '{category}-{color}',
'icon-allow-overlap': true,
'text-field': '{name}',
@@ -102,17 +104,17 @@ const PositionsMap = ({ positions }) => {
'text-font': ['Roboto Regular'],
'text-size': 12,
},
- 'paint': {
+ paint: {
'text-halo-color': 'white',
'text-halo-width': 1,
},
});
map.addLayer({
- 'id': clusters,
- 'type': 'symbol',
- 'source': id,
- 'filter': ['has', 'point_count'],
- 'layout': {
+ id: clusters,
+ type: 'symbol',
+ source: id,
+ filter: ['has', 'point_count'],
+ layout: {
'icon-image': 'background',
'text-field': '{point_count_abbreviated}',
'text-font': ['Roboto Regular'],
@@ -120,7 +122,6 @@ const PositionsMap = ({ positions }) => {
},
});
-
map.on('mouseenter', id, onMouseEnter);
map.on('mouseleave', id, onMouseLeave);
map.on('mouseenter', clusters, onMouseEnter);
@@ -129,7 +130,7 @@ const PositionsMap = ({ positions }) => {
map.on('click', clusters, onClusterClick);
return () => {
- Array.from(map.getContainer().getElementsByClassName('maplibregl-popup')).forEach(el => el.remove());
+ Array.from(map.getContainer().getElementsByClassName('maplibregl-popup')).forEach((el) => el.remove());
map.off('mouseenter', id, onMouseEnter);
map.off('mouseleave', id, onMouseLeave);
@@ -147,18 +148,18 @@ const PositionsMap = ({ positions }) => {
useEffect(() => {
map.getSource(id).setData({
type: 'FeatureCollection',
- features: positions.filter(it => devices.hasOwnProperty(it.deviceId)).map(position => ({
+ features: positions.filter((it) => devices.hasOwnProperty(it.deviceId)).map((position) => ({
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [position.longitude, position.latitude],
},
properties: createFeature(devices, position),
- }))
+ })),
});
}, [devices, positions]);
return null;
-}
+};
export default PositionsMap;
diff --git a/modern/src/map/ReplayPathMap.js b/modern/src/map/ReplayPathMap.js
index b40aa69..62b3f27 100644
--- a/modern/src/map/ReplayPathMap.js
+++ b/modern/src/map/ReplayPathMap.js
@@ -7,8 +7,8 @@ const ReplayPathMap = ({ positions }) => {
useEffect(() => {
map.addSource(id, {
- 'type': 'geojson',
- 'data': {
+ type: 'geojson',
+ data: {
type: 'Feature',
geometry: {
type: 'LineString',
@@ -17,16 +17,16 @@ const ReplayPathMap = ({ positions }) => {
},
});
map.addLayer({
- 'source': id,
- 'id': id,
- 'type': 'line',
- 'layout': {
+ source: id,
+ id,
+ type: 'line',
+ layout: {
'line-join': 'round',
'line-cap': 'round',
},
- 'paint': {
- 'line-color': '#333',
- 'line-width': 5,
+ paint: {
+ 'line-color': '#333',
+ 'line-width': 5,
},
});
@@ -37,23 +37,25 @@ const ReplayPathMap = ({ positions }) => {
}, []);
useEffect(() => {
- const coordinates = positions.map(item => [item.longitude, item.latitude]);
+ const coordinates = positions.map((item) => [item.longitude, item.latitude]);
map.getSource(id).setData({
type: 'Feature',
geometry: {
type: 'LineString',
- coordinates: coordinates,
+ coordinates,
},
});
if (coordinates.length) {
const bounds = coordinates.reduce((bounds, item) => bounds.extend(item), new maplibregl.LngLatBounds(coordinates[0], coordinates[0]));
map.fitBounds(bounds, {
- padding: { top: 50, bottom: 250, left: 25, right: 25 },
+ padding: {
+ top: 50, bottom: 250, left: 25, right: 25,
+ },
});
}
}, [positions]);
return null;
-}
+};
export default ReplayPathMap;
diff --git a/modern/src/map/SelectedDeviceMap.js b/modern/src/map/SelectedDeviceMap.js
index 655fca9..e6c5f58 100644
--- a/modern/src/map/SelectedDeviceMap.js
+++ b/modern/src/map/SelectedDeviceMap.js
@@ -4,7 +4,7 @@ import { useSelector } from 'react-redux';
import { map } from './Map';
const SelectedDeviceMap = () => {
- const mapCenter = useSelector(state => {
+ const mapCenter = useSelector((state) => {
if (state.devices.selectedId) {
const position = state.positions.items[state.devices.selectedId] || null;
if (position) {
@@ -19,6 +19,6 @@ const SelectedDeviceMap = () => {
}, [mapCenter]);
return null;
-}
+};
export default SelectedDeviceMap;
diff --git a/modern/src/map/StatusView.js b/modern/src/map/StatusView.js
index ae049af..20e5b74 100644
--- a/modern/src/map/StatusView.js
+++ b/modern/src/map/StatusView.js
@@ -1,27 +1,68 @@
-import t from '../common/localization'
import React from 'react';
import { useSelector } from 'react-redux';
+import t from '../common/localization';
import { formatPosition } from '../common/formatter';
const StatusView = ({ deviceId, onShowDetails }) => {
- const device = useSelector(state => state.devices.items[deviceId]);
- const position = useSelector(state => state.positions.items[deviceId]);
+ const device = useSelector((state) => state.devices.items[deviceId]);
+ const position = useSelector((state) => state.positions.items[deviceId]);
- const handleClick = e => {
+ const handleClick = (e) => {
e.preventDefault();
onShowDetails(position.id);
};
return (
<>
- <b>{t('deviceStatus')}:</b> {formatPosition(device.status, 'status')}<br />
- <b>{t('sharedLocation')}:</b> {formatPosition(position, 'latitude')} {formatPosition(position, 'longitude')}<br />
- <b>{t('positionSpeed')}:</b> {formatPosition(position.speed, 'speed')}<br />
- <b>{t('positionCourse')}:</b> {formatPosition(position.course, 'course')}<br />
- <b>{t('positionDistance')}:</b> {formatPosition(position.attributes.totalDistance, 'distance')}<br />
- {position.attributes.batteryLevel &&
- <><b>{t('positionBattery')}:</b> {formatPosition(position.attributes.batteryLevel, 'batteryLevel')}<br /></>
- }
+ <b>
+ {t('deviceStatus')}
+ :
+ </b>
+ {' '}
+ {formatPosition(device.status, 'status')}
+ <br />
+ <b>
+ {t('sharedLocation')}
+ :
+ </b>
+ {' '}
+ {formatPosition(position, 'latitude')}
+ {' '}
+ {formatPosition(position, 'longitude')}
+ <br />
+ <b>
+ {t('positionSpeed')}
+ :
+ </b>
+ {' '}
+ {formatPosition(position.speed, 'speed')}
+ <br />
+ <b>
+ {t('positionCourse')}
+ :
+ </b>
+ {' '}
+ {formatPosition(position.course, 'course')}
+ <br />
+ <b>
+ {t('positionDistance')}
+ :
+ </b>
+ {' '}
+ {formatPosition(position.attributes.totalDistance, 'distance')}
+ <br />
+ {position.attributes.batteryLevel
+ && (
+ <>
+ <b>
+ {t('positionBattery')}
+ :
+ </b>
+ {' '}
+ {formatPosition(position.attributes.batteryLevel, 'batteryLevel')}
+ <br />
+ </>
+ )}
<a href="/" onClick={handleClick}>{t('sharedShowDetails')}</a>
</>
);
diff --git a/modern/src/map/mapStyles.js b/modern/src/map/mapStyles.js
index 00a8666..9650ead 100644
--- a/modern/src/map/mapStyles.js
+++ b/modern/src/map/mapStyles.js
@@ -4,7 +4,7 @@ export const styleCustom = (url, attribution) => ({
osm: {
type: 'raster',
tiles: [url],
- attribution: attribution,
+ attribution,
tileSize: 256,
},
},
@@ -22,30 +22,30 @@ export const styleOsm = () => styleCustom(
);
export const styleCarto = () => ({
- 'version': 8,
- 'sources': {
+ version: 8,
+ sources: {
'raster-tiles': {
- 'type': 'raster',
- 'tiles': [
- 'https://a.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}@2x.png',
- 'https://b.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}@2x.png',
- 'https://c.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}@2x.png',
- 'https://d.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}@2x.png'
+ type: 'raster',
+ tiles: [
+ 'https://a.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}@2x.png',
+ 'https://b.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}@2x.png',
+ 'https://c.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}@2x.png',
+ 'https://d.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}@2x.png',
],
- 'tileSize': 256,
- 'attribution': '© <a target="_top" rel="noopener" href="http://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, © <a target="_top" rel="noopener" href="https://carto.com/attribution">CARTO</a>'
- }
+ tileSize: 256,
+ attribution: '© <a target="_top" rel="noopener" href="http://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, © <a target="_top" rel="noopener" href="https://carto.com/attribution">CARTO</a>',
+ },
},
- 'glyphs': 'https://cdn.traccar.com/map/fonts/{fontstack}/{range}.pbf',
- 'layers': [
+ glyphs: 'https://cdn.traccar.com/map/fonts/{fontstack}/{range}.pbf',
+ layers: [
{
- 'id': 'simple-tiles',
- 'type': 'raster',
- 'source': 'raster-tiles',
- 'minzoom': 0,
- 'maxzoom': 22,
- }
- ]
+ id: 'simple-tiles',
+ type: 'raster',
+ source: 'raster-tiles',
+ minzoom: 0,
+ maxzoom: 22,
+ },
+ ],
});
export const styleMapbox = (style) => `mapbox://styles/mapbox/${style}`;
diff --git a/modern/src/map/mapUtil.js b/modern/src/map/mapUtil.js
index 67ce345..e3c32f4 100644
--- a/modern/src/map/mapUtil.js
+++ b/modern/src/map/mapUtil.js
@@ -2,13 +2,11 @@ import { parse, stringify } from 'wellknown';
import canvasTintImage from 'canvas-tint-image';
import circle from '@turf/circle';
-export const loadImage = (url) => {
- return new Promise(imageLoaded => {
- const image = new Image();
- image.onload = () => imageLoaded(image);
- image.src = url;
- });
-};
+export const loadImage = (url) => new Promise((imageLoaded) => {
+ const image = new Image();
+ image.onload = () => imageLoaded(image);
+ image.src = url;
+});
export const prepareIcon = (background, icon, color) => {
const pixelRatio = window.devicePixelRatio;
@@ -32,44 +30,39 @@ export const prepareIcon = (background, icon, color) => {
return context.getImageData(0, 0, canvas.width, canvas.height);
};
-export const reverseCoordinates = it => {
+export const reverseCoordinates = (it) => {
if (!it) {
return it;
- } else if (Array.isArray(it)) {
+ } 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),
}
+ return it.map((it) => reverseCoordinates(it));
}
-}
+ return {
+ ...it,
+ coordinates: reverseCoordinates(it.coordinates),
+ };
+};
export const geofenceToFeature = (item) => {
if (item.area.indexOf('CIRCLE') > -1) {
- let coordinates = item.area.replace(/CIRCLE|\(|\)|,/g, " ").trim().split(/ +/);
- var options = { steps: 32, units: 'meters' };
- let polygon = circle([Number(coordinates[1]), Number(coordinates[0])], Number(coordinates[2]), options);
+ const coordinates = item.area.replace(/CIRCLE|\(|\)|,/g, ' ').trim().split(/ +/);
+ const options = { steps: 32, units: 'meters' };
+ const polygon = circle([Number(coordinates[1]), Number(coordinates[0])], Number(coordinates[2]), options);
return {
id: item.id,
type: 'Feature',
geometry: polygon.geometry,
- properties: { name: item.name }
- };
- } else {
- return {
- id: item.id,
- type: 'Feature',
- geometry: reverseCoordinates(parse(item.area)),
- properties: { name: item.name }
+ properties: { name: item.name },
};
}
-}
+ return {
+ id: item.id,
+ type: 'Feature',
+ geometry: reverseCoordinates(parse(item.area)),
+ properties: { name: item.name },
+ };
+};
-export const geometryToArea = (geometry) => {
- return stringify(reverseCoordinates(geometry));
-}
+export const geometryToArea = (geometry) => stringify(reverseCoordinates(geometry));
diff --git a/modern/src/map/switcher/switcher.js b/modern/src/map/switcher/switcher.js
index a755645..e9076aa 100644
--- a/modern/src/map/switcher/switcher.js
+++ b/modern/src/map/switcher/switcher.js
@@ -1,5 +1,4 @@
export class SwitcherControl {
-
constructor(styles, defaultStyle, beforeSwitch, afterSwitch) {
this.styles = styles;
this.defaultStyle = defaultStyle;
@@ -27,8 +26,8 @@ export class SwitcherControl {
styleElement.innerText = style.title;
styleElement.classList.add(style.title.replace(/[^a-z0-9-]/gi, '_'));
styleElement.dataset.uri = JSON.stringify(style.uri);
- styleElement.addEventListener('click', event => {
- const srcElement = event.srcElement;
+ styleElement.addEventListener('click', (event) => {
+ const { srcElement } = event;
if (srcElement.classList.contains('active')) {
return;
}