import maplibregl, { type GeoJSONSourceSpecification, type LayerSpecification, } from 'maplibre-gl'; export function removeLayerIfExists(map: maplibregl.Map, layerId: string | null | undefined) { if (!layerId) return; try { if (map.getLayer(layerId)) { map.removeLayer(layerId); } } catch { // ignore } } export function removeSourceIfExists(map: maplibregl.Map, sourceId: string) { try { if (map.getSource(sourceId)) { map.removeSource(sourceId); } } catch { // ignore } } const GLOBE_NATIVE_LAYER_IDS = [ 'ships-globe-halo', 'ships-globe-outline', 'ships-globe', 'ships-globe-label', 'ships-globe-hover-halo', 'ships-globe-hover-outline', 'ships-globe-hover', 'pair-lines-ml', 'fc-lines-ml', 'fleet-circles-ml-fill', 'fleet-circles-ml', 'pair-range-ml', 'deck-globe', ]; const GLOBE_NATIVE_SOURCE_IDS = [ 'ships-globe-src', 'ships-globe-hover-src', 'pair-lines-ml-src', 'fc-lines-ml-src', 'fleet-circles-ml-src', 'fleet-circles-ml-fill-src', 'pair-range-ml-src', ]; export function clearGlobeNativeLayers(map: maplibregl.Map) { for (const id of GLOBE_NATIVE_LAYER_IDS) { removeLayerIfExists(map, id); } for (const id of GLOBE_NATIVE_SOURCE_IDS) { removeSourceIfExists(map, id); } } export function ensureGeoJsonSource( map: maplibregl.Map, sourceId: string, data: GeoJSON.GeoJSON, ) { const existing = map.getSource(sourceId); if (existing) { (existing as maplibregl.GeoJSONSource).setData(data); } else { map.addSource(sourceId, { type: 'geojson', data, } satisfies GeoJSONSourceSpecification); } } export function ensureLayer( map: maplibregl.Map, spec: LayerSpecification, options?: { before?: string }, ) { if (map.getLayer(spec.id)) return; const before = options?.before && map.getLayer(options.before) ? options.before : undefined; map.addLayer(spec, before); } export function setLayerVisibility(map: maplibregl.Map, layerId: string, visible: boolean) { if (!map.getLayer(layerId)) return; try { map.setLayoutProperty(layerId, 'visibility', visible ? 'visible' : 'none'); } catch { // ignore } } export function cleanupLayers( map: maplibregl.Map, layerIds: string[], sourceIds: string[], ) { requestAnimationFrame(() => { for (const id of layerIds) { try { if (map.getLayer(id)) map.removeLayer(id); } catch { // ignore } } for (const id of sourceIds) { try { if (map.getSource(id)) map.removeSource(id); } catch { // ignore } } }); }