diff --git a/ui/src/components/map/stop-areas/FunctionalAreaVisualization/FunctionalAreaVisualization.tsx b/ui/src/components/map/stop-areas/FunctionalAreaVisualization/FunctionalAreaVisualization.tsx index e8e20f0d09..3e1f1622ae 100644 --- a/ui/src/components/map/stop-areas/FunctionalAreaVisualization/FunctionalAreaVisualization.tsx +++ b/ui/src/components/map/stop-areas/FunctionalAreaVisualization/FunctionalAreaVisualization.tsx @@ -4,6 +4,7 @@ import { FC, useEffect } from 'react'; import { MapInstance, useMap } from 'react-map-gl/maplibre'; import { useAppSelector } from '../../../../hooks'; import { selectSelectedStopAreaId } from '../../../../redux'; +import { isMapStyleReady } from '../../../../utils/map'; import { MapStop } from '../../types'; import { CanvasRenderer } from './CanvasRenderer'; import { pixelSize } from './constants'; @@ -24,7 +25,7 @@ function assertIsCanvasSource(source: unknown): asserts source is CanvasSource { // so we need to register the source and layer manually. function useMapSourceAndLayer(map: MapInstance | null) { useEffect(() => { - if (!map) { + if (!map || !isMapStyleReady(map)) { return noop(); } diff --git a/ui/src/utils/map/lineFromStopToInfraLink.ts b/ui/src/utils/map/lineFromStopToInfraLink.ts index 1608fa218e..9e01924d12 100644 --- a/ui/src/utils/map/lineFromStopToInfraLink.ts +++ b/ui/src/utils/map/lineFromStopToInfraLink.ts @@ -15,7 +15,11 @@ import { MapInstance } from 'react-map-gl/maplibre'; import { ReusableComponentsVehicleModeEnum } from '../../generated/graphql'; import { Point as JorePoint } from '../../types'; import { notNullish } from '../misc'; -import { createGeometryLineBetweenPoints, removeLayer } from './mapUtils'; +import { + createGeometryLineBetweenPoints, + isMapStyleReady, + removeLayer, +} from './mapUtils'; type LineAndDistance = { readonly line: LineString; @@ -117,7 +121,7 @@ export function addLineFromStopToInfraLink( map: MapInstance | undefined, geometry: Geometry, ) { - if (!map) { + if (!map || !isMapStyleReady(map)) { return; } diff --git a/ui/src/utils/map/mapUtils.ts b/ui/src/utils/map/mapUtils.ts index 746f116e6c..eb88fbcc94 100644 --- a/ui/src/utils/map/mapUtils.ts +++ b/ui/src/utils/map/mapUtils.ts @@ -17,8 +17,15 @@ const imageAssets: ReadonlyArray = [ }, ]; +/* + * Checks if the map style exists and that it has finished loading. This is needed before performing operations on the map, such as adding/manipulating layers or sources. + */ +export function isMapStyleReady(map: MapInstance) { + return !!map?.style && map.isStyleLoaded() === true; +} + export const removeLayer = (map: MapInstance, id: string) => { - if (map.getLayer(id)) { + if (isMapStyleReady(map) && map.getLayer(id)) { map.removeLayer(id); } }; @@ -68,7 +75,7 @@ export const getInteractiveLayerIds = (mapRef: RefObject) => { }; export const removeRoute = (map: MapInstance | undefined, id: string) => { - if (!map) { + if (!map || !isMapStyleReady(map)) { return; } if (map.getLayer(id)) { @@ -83,6 +90,10 @@ export const removeRoute = (map: MapInstance | undefined, id: string) => { }; export const addRoute = (map: MapInstance, id: string, geometry: Geometry) => { + if (!isMapStyleReady(map)) { + return; + } + // remove possible existing layers with same id removeRoute(map, id); map.addLayer({