diff --git a/src/components/CoordinatesDisplay.tsx b/src/components/CoordinatesDisplay.tsx index f316284..5ac9edf 100644 --- a/src/components/CoordinatesDisplay.tsx +++ b/src/components/CoordinatesDisplay.tsx @@ -11,11 +11,13 @@ export function CoordinatesDisplay({ mapRef, externalSearchRef, externalSearchMarkerRef, + isMapInitialized, }: { flipped: boolean; mapRef: React.RefObject; externalSearchRef: React.RefObject; externalSearchMarkerRef: React.RefObject | null>; + isMapInitialized: boolean; }) { const [coordinates, setCoordinates] = useState( undefined @@ -56,12 +58,12 @@ export function CoordinatesDisplay({ }, []); useEffect(() => { - if (!mapRef.current) return; + if (!mapRef.current || !isMapInitialized) return; const currentMapRef = mapRef.current; const updateCoords = (e: MapBrowserEvent) => setCoordinates(e.coordinate); currentMapRef.on('pointermove', updateCoords); return () => currentMapRef.un('pointermove', updateCoords); - }, [mapRef]); + }, [mapRef, isMapInitialized]); const onSubmit = useCallback( (e: FormEvent) => { diff --git a/src/components/OpenLayersMap.tsx b/src/components/OpenLayersMap.tsx index 4049df5..24f5d50 100644 --- a/src/components/OpenLayersMap.tsx +++ b/src/components/OpenLayersMap.tsx @@ -94,6 +94,7 @@ export function OpenLayersMap({ const [isDrawing, setIsDrawing] = useState(false); const [isNewBoxDrawn, setIsNewBoxDrawn] = useState(false); const [flipTiles, setFlipTiles] = useState(true); + const [isMapInitialized, setIsMapInitialized] = useState(false); const [backHistoryStack, setBackHistoryStack] = useState< { id: string; flipped: boolean }[] @@ -277,6 +278,8 @@ export function OpenLayersMap({ view: new View(DEFAULT_INTERNAL_MAP_SETTINGS), }); + setIsMapInitialized(true); + /** * BEGIN * Set up overlay, markers, and events for the external searches functionality @@ -570,12 +573,17 @@ export function OpenLayersMap({ goBack={goBack} goForward={goForward} /> - + ); diff --git a/src/components/layers/GraticuleLayer.tsx b/src/components/layers/GraticuleLayer.tsx index ad3d015..8d074c2 100644 --- a/src/components/layers/GraticuleLayer.tsx +++ b/src/components/layers/GraticuleLayer.tsx @@ -1,4 +1,4 @@ -import { useCallback, useEffect } from 'react'; +import { useEffect, useRef } from 'react'; import { Graticule, Map } from 'ol'; import Stroke from 'ol/style/Stroke'; import { NUMBER_OF_FIXED_GRATICULE_DECIMALS } from '../../configs/mapSettings'; @@ -6,78 +6,77 @@ import { NUMBER_OF_FIXED_GRATICULE_DECIMALS } from '../../configs/mapSettings'; export function GraticuleLayer({ mapRef, flipped, + isMapInitialized, }: { mapRef: React.RefObject; flipped: boolean; + isMapInitialized: boolean; }) { - const handleLatLabelFormat = useCallback((lat: number) => { - if (Number.isInteger(lat) || String(lat).length < 5) { - return String(lat); - } + const gratRef = useRef(null); + + const formatLat = (lat: number) => { + if (Number.isInteger(lat) || String(lat).length < 5) return String(lat); return String(lat.toFixed(NUMBER_OF_FIXED_GRATICULE_DECIMALS)); - }, []); + }; - const handleLonLabelFormat = useCallback( - (lon: number) => { - if (Number.isInteger(lon) || String(lon).length < 5) { - return String(flipped ? lon * -1 + 180 : lon); - } - return String( - (flipped ? lon * -1 + 180 : lon).toFixed( - NUMBER_OF_FIXED_GRATICULE_DECIMALS - ) - ); - }, - [flipped] - ); + const formatLon = (lon: number) => { + const fixed = flipped ? lon * -1 + 180 : lon; + if (Number.isInteger(fixed) || String(fixed).length < 5) + return String(fixed); + return String(fixed.toFixed(NUMBER_OF_FIXED_GRATICULE_DECIMALS)); + }; useEffect(() => { - if (mapRef.current) { - mapRef.current.getAllLayers().forEach((l) => { - const id = l.getProperties().id; - if (id && id.includes('graticule-')) { - mapRef.current?.removeLayer(l); - } - }); + const map = mapRef.current; + if (!map || !isMapInitialized) return; - const graticule1 = new Graticule({ - strokeStyle: new Stroke({ - color: 'rgba(198,198,198,0.5)', - width: 2, - }), - zIndex: 1000, - showLabels: true, - lonLabelPosition: 0, - latLabelPosition: 0.999, - latLabelFormatter: handleLatLabelFormat, - lonLabelFormatter: handleLonLabelFormat, - wrapX: false, - properties: { - id: 'graticule-1', - }, - }); + // Remove old graticule layers + if (gratRef.current) { + gratRef.current.forEach((g) => map.removeLayer(g)); + gratRef.current = null; + } - const graticule2 = new Graticule({ - strokeStyle: new Stroke({ - color: 'rgba(198,198,198,0.5)', - width: 2, - }), - zIndex: 1000, - showLabels: true, - lonLabelPosition: 1, - latLabelPosition: 0.035, - latLabelFormatter: handleLatLabelFormat, - lonLabelFormatter: handleLonLabelFormat, - wrapX: false, - properties: { - id: 'graticule-2', - }, - }); + const stroke = new Stroke({ + color: 'rgba(198,198,198,0.5)', + width: 2, + }); - mapRef.current.addLayer(graticule1); - mapRef.current.addLayer(graticule2); - } - }, [mapRef, flipped, handleLatLabelFormat, handleLonLabelFormat]); + const g1 = new Graticule({ + strokeStyle: stroke, + zIndex: 1000, + showLabels: true, + lonLabelPosition: 0, + latLabelPosition: 0.999, + latLabelFormatter: formatLat, + lonLabelFormatter: formatLon, + wrapX: false, + properties: { id: 'graticule-1' }, + }); + + const g2 = new Graticule({ + strokeStyle: stroke, + zIndex: 1000, + showLabels: true, + lonLabelPosition: 1, + latLabelPosition: 0.035, + latLabelFormatter: formatLat, + lonLabelFormatter: formatLon, + wrapX: false, + properties: { id: 'graticule-2' }, + }); + + gratRef.current = [g1, g2]; + + map.addLayer(g1); + map.addLayer(g2); + + // Cleanup on unmount + return () => { + if (!map || !gratRef.current) return; + gratRef.current.forEach((g) => map.removeLayer(g)); + gratRef.current = null; + }; + }, [mapRef, flipped, isMapInitialized]); return null; }