diff --git a/src/app/(maps)/components/FullScreenMap.tsx b/src/app/(maps)/components/FullScreenMap.tsx index 753e41f06..857ecb250 100644 --- a/src/app/(maps)/components/FullScreenMap.tsx +++ b/src/app/(maps)/components/FullScreenMap.tsx @@ -7,6 +7,7 @@ import { MapLayerMouseEvent } from 'maplibre-gl' export const FullScreenMap: React.FC = () => { const [center, setCenter] = useState<[number, number] | undefined>(undefined) const [zoom, setZoom] = useState(undefined) + const [initialAreaId, setInitialAreaId] = useState(undefined) const [isInitialized, setIsInitialized] = useState(false) const router = useRouter() @@ -17,6 +18,11 @@ export const FullScreenMap: React.FC = () => { if (isInitialized) return const { camera } = urlParams.fromUrl() + const { areaId } = urlParams.fromUrl() + + if (areaId !== null) { + setInitialAreaId(areaId) + } if (camera !== null) { setCenter([camera.center.lng, camera.center.lat]) @@ -25,17 +31,17 @@ export const FullScreenMap: React.FC = () => { return } - getVisitorLocation() - .then((visitorLocation) => { + getVisitorLocation().then( + (visitorLocation) => { if (visitorLocation !== null && visitorLocation !== undefined) { setCenter([visitorLocation.longitude, visitorLocation.latitude]) setIsInitialized(true) } - }) - .catch(() => { - console.log('Unable to determine user\'s location') - setIsInitialized(true) - }) + } + ).catch(() => { + console.log('Unable to determine user\'s location') + setIsInitialized(true) + }) }, [urlParams, isInitialized]) const handleCameraMovement = useCallback( @@ -57,12 +63,12 @@ export const FullScreenMap: React.FC = () => { const { camera } = urlParams.fromUrl() const url = urlParams.toUrl({ camera: camera ?? null, areaId }) router.replace(url, { scroll: false }) - }, - [urlParams, router] + }, [urlParams, router] ) return ( void children?: React.ReactNode handleOnClick?: (e: MapLayerMouseEvent) => void + initialAreaId?: string } /** * Global map */ export const GlobalMap: React.FC = ({ - showFullscreenControl = true, initialCenter, initialZoom, initialViewState, onCameraMovement, children, handleOnClick + showFullscreenControl = true, initialCenter, initialZoom, initialViewState, onCameraMovement, children, handleOnClick, initialAreaId }) => { const [clickInfo, setClickInfo] = useState(null) const [hoverInfo, setHoverInfo] = useState(null) const [mapInstance, setMapInstance] = useState(null) const [cursor, setCursor] = useState('default') const [mapStyle, setMapStyle] = useState(MAP_STYLES.light.style) + const [isSourceLoaded, setIsSourceLoaded] = useState(false) const [dataLayersDisplayState, setDataLayersDisplayState] = useState({ areaBoundaries: false, organizations: false, @@ -166,6 +168,39 @@ export const GlobalMap: React.FC = ({ setMapStyle(style.style) } + const findAreaById = useCallback((map: maplibregl.Map, areaId: string) => { + const features = map.querySourceFeatures('crags', { + sourceLayer: 'crags', + filter: ['==', ['get', 'id'], areaId] + }) + return features[0] // return first feature because it could be duplicated by the tileset + }, []) + + useEffect(() => { + if (mapInstance == null) return + + if (!isSourceLoaded) { + mapInstance.on('sourcedata', (e) => { + if (e.sourceId === 'crags' && e.isSourceLoaded) { + setIsSourceLoaded(true) + } + }) + } + + if (isSourceLoaded && initialAreaId !== undefined) { + const feature = findAreaById(mapInstance, initialAreaId) + if (feature != null) { + setClickInfo(prev => { + setActiveFeatureVisual(prev, { selected: false, hover: false }) + + const activeFeature = tileToFeature('crag-name-labels', { x: 0, y: 0 }, feature.geometry, feature.properties as TileProps, mapInstance) + setActiveFeatureVisual(activeFeature, { selected: true, hover: false }) + return activeFeature + }) + } + } + }, [mapInstance, isSourceLoaded, initialAreaId, findAreaById]) + return (