diff options
Diffstat (limited to 'src/map/MapMarkers.js')
-rw-r--r-- | src/map/MapMarkers.js | 89 |
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; |