import { LngLatBounds, LngLat, LngLatLike, LngLatBoundsLike } from 'maplibre-gl'; import type { Geometry, FeatureCollection, Feature } from 'geojson'; import invariant from 'tiny-invariant'; export function getBounds(geometry: Geometry): LngLatBoundsLike { const bbox = new LngLatBounds(); if (geometry.type === 'Point') { return [geometry.coordinates, geometry.coordinates] as [ [number, number], [number, number] ]; } else if (geometry.type === 'LineString') { for (const coordinate of geometry.coordinates) { bbox.extend(coordinate as [number, number]); } } else { invariant( geometry.type != 'GeometryCollection', 'GeometryCollection not supported' ); for (const coordinate of geometry.coordinates[0]) { bbox.extend(coordinate as [number, number]); } } return bbox; } export function findFeature( featureCollection: FeatureCollection, value: unknown, property = 'id' ): Feature | null { return ( featureCollection.features.find( (feature) => feature.properties && feature.properties[property] === value ) ?? null ); } export function filterFeatureCollection( featureCollection: FeatureCollection, source: string ): FeatureCollection { return { type: 'FeatureCollection', features: featureCollection.features.filter( (feature) => feature.properties?.source === source ) }; } export function filterFeatureCollectionByGeometryType( featureCollection: FeatureCollection, type: Geometry['type'] ): FeatureCollection { return { type: 'FeatureCollection', features: featureCollection.features.filter( (feature) => feature.geometry.type === type ) }; } export function generateId(): string { return Math.random().toString(20).substring(2, 6); } export function getCenter(geometry: Geometry, lngLat: LngLat): LngLatLike { const bbox = new LngLatBounds(); invariant( geometry.type != 'GeometryCollection', 'GeometryCollection not supported' ); switch (geometry.type) { case 'Point': return [...geometry.coordinates] as [number, number]; case 'LineString': return [lngLat.lng, lngLat.lat]; default: for (const coordinate of geometry.coordinates[0]) { bbox.extend(coordinate as [number, number]); } return bbox.getCenter(); } }