UNPKG

@loaders.gl/gis

Version:

Helpers for GIS category data

70 lines (62 loc) 2.32 kB
import type {BinaryFeatureCollection, BinaryGeometry, Feature} from '@loaders.gl/schema'; type TransformCoordinate = (coord: number[]) => number[]; /** * Apply transformation to every coordinate of binary features * @param binaryFeatures binary features * @param transformCoordinate Function to call on each coordinate * @return Transformed binary features */ export function transformBinaryCoords( binaryFeatures: BinaryFeatureCollection, transformCoordinate: TransformCoordinate ): BinaryFeatureCollection { if (binaryFeatures.points) { transformBinaryGeometryPositions(binaryFeatures.points, transformCoordinate); } if (binaryFeatures.lines) { transformBinaryGeometryPositions(binaryFeatures.lines, transformCoordinate); } if (binaryFeatures.polygons) { transformBinaryGeometryPositions(binaryFeatures.polygons, transformCoordinate); } return binaryFeatures; } /** Transform one binary geometry */ function transformBinaryGeometryPositions(binaryGeometry: BinaryGeometry, fn: TransformCoordinate) { const {positions} = binaryGeometry; for (let i = 0; i < positions.value.length; i += positions.size) { // @ts-ignore inclusion of bigint causes problems const coord: Array<number> = Array.from(positions.value.subarray(i, i + positions.size)); const transformedCoord = fn(coord); // @ts-ignore typescript typing for .set seems to require bigint? positions.value.set(transformedCoord, i); } } /** * Apply transformation to every coordinate of GeoJSON features * * @param features Array of GeoJSON features * @param fn Function to call on each coordinate * @return Transformed GeoJSON features */ export function transformGeoJsonCoords( features: Feature[], fn: (coord: number[]) => number[] ): Feature[] { for (const feature of features) { // @ts-ignore feature.geometry.coordinates = coordMap(feature.geometry.coordinates, fn); } return features; } function coordMap(array: unknown, fn: (coord: number[]) => number[]): unknown[] { if (isCoord(array)) { return fn(array as number[]); } return (array as unknown[]).map((item) => { return coordMap(item, fn); }); } function isCoord(array: unknown) { return Array.isArray(array) && Number.isFinite(array[0]) && Number.isFinite(array[1]); }