aboutsummaryrefslogtreecommitdiff
path: root/src/map/MapMarkers.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/map/MapMarkers.js')
-rw-r--r--src/map/MapMarkers.js89
1 files changed, 89 insertions, 0 deletions
diff --git a/src/map/MapMarkers.js b/src/map/MapMarkers.js
new file mode 100644
index 00000000..8fbe92b6
--- /dev/null
+++ b/src/map/MapMarkers.js
@@ -0,0 +1,89 @@
+import { useId, useEffect } from 'react';
+import { useTheme } from '@mui/styles';
+import { useMediaQuery } from '@mui/material';
+import { map } from './core/MapView';
+import { useAttributePreference } from '../common/util/preferences';
+import { findFonts } from './core/mapUtil';
+
+const MapMarkers = ({ markers, showTitles }) => {
+ const id = useId();
+
+ const theme = useTheme();
+ const desktop = useMediaQuery(theme.breakpoints.up('md'));
+ const iconScale = useAttributePreference('iconScale', desktop ? 0.75 : 1);
+
+ useEffect(() => {
+ map.addSource(id, {
+ type: 'geojson',
+ data: {
+ type: 'FeatureCollection',
+ features: [],
+ },
+ });
+
+ if (showTitles) {
+ map.addLayer({
+ id,
+ type: 'symbol',
+ source: id,
+ filter: ['!has', 'point_count'],
+ layout: {
+ 'icon-image': '{image}',
+ 'icon-size': iconScale,
+ 'icon-allow-overlap': true,
+ 'text-field': '{title}',
+ 'text-allow-overlap': true,
+ 'text-anchor': 'bottom',
+ 'text-offset': [0, -2 * iconScale],
+ 'text-font': findFonts(map),
+ 'text-size': 12,
+ },
+ paint: {
+ 'text-halo-color': 'white',
+ 'text-halo-width': 1,
+ },
+ });
+ } else {
+ map.addLayer({
+ id,
+ type: 'symbol',
+ source: id,
+ layout: {
+ 'icon-image': '{image}',
+ 'icon-size': iconScale,
+ 'icon-allow-overlap': true,
+ },
+ });
+ }
+
+ return () => {
+ if (map.getLayer(id)) {
+ map.removeLayer(id);
+ }
+ if (map.getSource(id)) {
+ map.removeSource(id);
+ }
+ };
+ }, [showTitles]);
+
+ useEffect(() => {
+ map.getSource(id)?.setData({
+ type: 'FeatureCollection',
+ features: markers.map(({ latitude, longitude, image, title }) => ({
+ type: 'Feature',
+ geometry: {
+ type: 'Point',
+ coordinates: [longitude, latitude],
+ },
+ properties: {
+ image: image || 'default-neutral',
+ title: title || '',
+ },
+ })),
+ });
+ }, [showTitles, markers]);
+
+ return null;
+};
+
+export default MapMarkers;