UNPKG

terriajs

Version:

Geospatial data visualization platform.

181 lines (163 loc) 4.58 kB
import { feature, featureCollection } from "@turf/helpers"; import { Feature, FeatureCollection, GeoJsonProperties, Geometry, GeometryCollection, LineString, MultiLineString, MultiPoint, MultiPolygon, Point, Polygon } from "geojson"; import { isJsonObject, isJsonString } from "./Json"; export type GeoJsonCrs = | { type: "name"; properties: { name: string; }; } | { type: "EPSG"; properties: { code: string; }; }; export type FeatureCollectionWithCrs< G extends Geometry | null = Geometry | GeometryCollection, P = GeoJsonProperties > = FeatureCollection<G, P> & { crs?: GeoJsonCrs; }; // Note: these type checks are not that rigorous, we are assuming we are getting valid GeoJson objects export function isFeatureCollection( json: any ): json is FeatureCollectionWithCrs { return ( isJsonObject(json, false) && json.type === "FeatureCollection" && Array.isArray(json.features) ); } export function isFeature(json: any): json is Feature { return ( isJsonObject(json, false) && json.type === "Feature" && !!json.geometry ); } export function isPoint(json: any): json is Feature<Point> { return ( isJsonObject(json, false) && json.type === "Feature" && isJsonObject(json.geometry, false) && json.geometry.type === "Point" ); } export function isMultiPoint(json: any): json is Feature<MultiPoint> { return ( isJsonObject(json, false) && json.type === "Feature" && isJsonObject(json.geometry, false) && json.geometry.type === "MultiPoint" ); } export function isLine(json: any): json is Feature<LineString> { return ( isJsonObject(json, false) && json.type === "Feature" && isJsonObject(json.geometry, false) && json.geometry.type === "LineString" ); } export function isMultiLineString(json: any): json is Feature<MultiLineString> { return ( isJsonObject(json, false) && json.type === "Feature" && isJsonObject(json.geometry, false) && json.geometry.type === "MultiLineString" ); } export function isPolygon(json: any): json is Feature<Polygon> { return ( isJsonObject(json, false) && json.type === "Feature" && isJsonObject(json.geometry, false) && json.geometry.type === "Polygon" ); } export function isMultiPolygon(json: any): json is Feature<MultiPolygon> { return ( isJsonObject(json, false) && json.type === "Feature" && isJsonObject(json.geometry, false) && json.geometry.type === "MultiPolygon" ); } export function isGeometryCollection( json: any ): json is Feature<GeometryCollection> { return ( isJsonObject(json, false) && json.type === "Feature" && isJsonObject(json.geometry, false) && json.geometry.type === "GeometryCollection" ); } export function isGeometries(json: any): json is Geometry { return ( isJsonObject(json, false) && isJsonString(json.type) && [ "Point", "MultiPoint", "LineString", "MultiLineString", "Polygon", "MultiPolygon" ].includes(json.type) && Array.isArray(json.coordinates) ); } /** * Returns the points in a MultiPoint as separate Point features. */ export function explodeMultiPoint(feature: Feature): Feature[] { return feature.geometry?.type === "MultiPoint" ? feature.geometry.coordinates.map((coordinates) => ({ type: "Feature", geometry: { type: "Point", coordinates } as Point, properties: feature.properties })) : []; } export function toFeatureCollection( json: any ): FeatureCollectionWithCrs | undefined { if (isFeatureCollection(json)) return json; // It's already a feature collection, do nothing if (isFeature(json)) { // Move CRS data from Feature to FeatureCollection if ("crs" in json && isJsonObject((json as any).crs)) { const crs = (json as any).crs; delete (json as any).crs; const fc = featureCollection([json]) as FeatureCollectionWithCrs; fc.crs = crs; return fc; } return featureCollection([json]) as FeatureCollectionWithCrs; } if (isGeometries(json)) return featureCollection([feature(json)]) as FeatureCollectionWithCrs; if (Array.isArray(json) && json.every((item) => isFeature(item))) { return featureCollection(json) as FeatureCollectionWithCrs; } if (Array.isArray(json) && json.every((item) => isGeometries(item))) { return featureCollection( json.map((item) => feature(item)) ) as FeatureCollectionWithCrs; } }