From 8e786c016ef0fa36a0a6db6acb3f7e81b1714999 Mon Sep 17 00:00:00 2001 From: Zsombor Welker Date: Thu, 7 Nov 2024 22:02:12 +0100 Subject: [PATCH] debug client: dynamically update interactive layers --- .../src/components/MapView/LayerControl.tsx | 33 ++++++++++++++++--- client/src/components/MapView/MapView.tsx | 5 +-- 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/client/src/components/MapView/LayerControl.tsx b/client/src/components/MapView/LayerControl.tsx index d6be2d641d7..e79ae95e61e 100644 --- a/client/src/components/MapView/LayerControl.tsx +++ b/client/src/components/MapView/LayerControl.tsx @@ -4,6 +4,7 @@ import { IControl, Map, TypedStyleLayer } from 'maplibre-gl'; type LayerControlProps = { position: ControlPosition; + setInteractiveLayerIds: (interactiveLayerIds: string[]) => void; }; /** @@ -15,6 +16,12 @@ type LayerControlProps = { class LayerControl implements IControl { private readonly container: HTMLDivElement = document.createElement('div'); + private readonly setInteractiveLayerIds: (interactiveLayerIds: string[]) => void; + + constructor(setInteractiveLayerIds: (interactiveLayerIds: string[]) => void) { + this.setInteractiveLayerIds = setInteractiveLayerIds; + } + onAdd(map: Map) { this.container.className = 'maplibregl-ctrl maplibregl-ctrl-group layer-select'; @@ -32,10 +39,8 @@ class LayerControl implements IControl { map .getLayersOrder() .map((l) => map.getLayer(l)) - .filter((s) => s?.type !== 'raster') - // the polylines of the routing result are put in map layers called jsx-1, jsx-2... - // we don't want them to show up in the debug layer selector - .filter((s) => !s?.id.startsWith('jsx')) + .filter((layer) => !!layer) + .filter((layer) => this.layerInteractive(layer)) .reverse() .forEach((layer) => { if (layer) { @@ -62,6 +67,17 @@ class LayerControl implements IControl { return this.container; } + private updateInteractiveLayerIds(map: Map) { + const visibleInteractiveLayerIds = map + .getLayersOrder() + .map((l) => map.getLayer(l)) + .filter((layer) => !!layer) + .filter((layer) => this.layerVisible(map, layer) && this.layerInteractive(layer)) + .map((layer) => layer.id); + + this.setInteractiveLayerIds(visibleInteractiveLayerIds); + } + private buildLayerDiv(layer: TypedStyleLayer, map: Map) { const layerDiv = document.createElement('div'); layerDiv.className = 'layer'; @@ -77,6 +93,7 @@ class LayerControl implements IControl { } else { map.setLayoutProperty(layer.id, 'visibility', 'none'); } + this.updateInteractiveLayerIds(map); }; input.checked = this.layerVisible(map, layer); input.className = 'layer'; @@ -118,13 +135,19 @@ class LayerControl implements IControl { return map.getLayoutProperty(layer.id, 'visibility') !== 'none'; } + private layerInteractive(layer: { id: string; type: string }) { + // the polylines of the routing result are put in map layers called jsx-1, jsx-2... + // we don't want them to show up in the debug layer selector + return layer?.type !== 'raster' && !layer?.id.startsWith('jsx'); + } + onRemove() { this.container.parentNode?.removeChild(this.container); } } export default function DebugLayerControl(props: LayerControlProps) { - useControl(() => new LayerControl(), { + useControl(() => new LayerControl(props.setInteractiveLayerIds), { position: props.position, }); diff --git a/client/src/components/MapView/MapView.tsx b/client/src/components/MapView/MapView.tsx index 4a6080a1b45..ec008853737 100644 --- a/client/src/components/MapView/MapView.tsx +++ b/client/src/components/MapView/MapView.tsx @@ -37,6 +37,7 @@ export function MapView({ const onMapDoubleClick = useMapDoubleClick({ tripQueryVariables, setTripQueryVariables }); const [showContextPopup, setShowContextPopup] = useState(null); const [showPropsPopup, setShowPropsPopup] = useState(null); + const [interactiveLayerIds, setInteractiveLayerIds] = useState([]); const [cursor, setCursor] = useState('auto'); const onMouseEnter = useCallback(() => setCursor('pointer'), []); const onMouseLeave = useCallback(() => setCursor('auto'), []); @@ -78,7 +79,7 @@ export function MapView({ }} // it's unfortunate that you have to list these layers here. // maybe there is a way around it: https://github.com/visgl/react-map-gl/discussions/2343 - interactiveLayerIds={['regular-stop', 'area-stop', 'group-stop', 'parking-vertex', 'vertex', 'edge', 'link']} + interactiveLayerIds={interactiveLayerIds} cursor={cursor} onMouseEnter={onMouseEnter} onMouseLeave={onMouseLeave} @@ -97,7 +98,7 @@ export function MapView({ setTripQueryVariables={setTripQueryVariables} loading={loading} /> - + {tripQueryResult?.trip.tripPatterns.length && ( )}