import { Map } from 'ol' import React, { useEffect } from 'react' import { PathDetailsStoreState } from '@/stores/PathDetailsStore' import { Coordinate } from '@/stores/QueryStore' import { FeatureCollection } from 'geojson' import VectorLayer from 'ol/layer/Vector' import VectorSource from 'ol/source/Vector' import { Stroke, Style } from 'ol/style' import { GeoJSON } from 'ol/format' import { fromLonLat } from 'ol/proj' const highlightedPathSegmentLayerKey = 'highlightedPathSegmentLayer' /** * This layer highlights path segments that are above the elevation threshold set by the horizontal line in the * path details diagram. */ export default function usePathDetailsLayer(map: Map, pathDetails: PathDetailsStoreState) { useEffect(() => { removePathSegmentsLayer(map) addPathSegmentsLayer(map, pathDetails) return () => { removePathSegmentsLayer(map) } }, [map, pathDetails]) return } function removePathSegmentsLayer(map: Map) { map.getLayers() .getArray() .filter(l => l.get(highlightedPathSegmentLayerKey)) .forEach(l => map.removeLayer(l)) } function addPathSegmentsLayer(map: Map, pathDetails: PathDetailsStoreState) { const highlightedPathSegmentsLayer = new VectorLayer({ source: new VectorSource({ features: new GeoJSON().readFeatures( createHighlightedPathSegments(pathDetails.pathDetailsHighlightedSegments) ), }), style: () => new Style({ stroke: new Stroke({ // todo color: 'red', width: 4, lineCap: 'round', lineJoin: 'round', }), }), }) highlightedPathSegmentsLayer.set(highlightedPathSegmentLayerKey, true) highlightedPathSegmentsLayer.setZIndex(3) map.addLayer(highlightedPathSegmentsLayer) } function createHighlightedPathSegments(segments: Coordinate[][]) { const featureCollection: FeatureCollection = { type: 'FeatureCollection', features: [ { type: 'Feature', geometry: { type: 'MultiLineString', coordinates: segments.map(s => s.map(c => fromLonLat([c.lng, c.lat]))), }, properties: {}, }, ], } return featureCollection }