@allmaps/stdlib
Version:
Allmaps Standard Library
273 lines (272 loc) • 10.9 kB
JavaScript
import { conformLineString, conformRing, conformPolygon, conformMultiLineString, conformMultiPolygon, geometryToSvgGeometry } from './geometry.js';
// Assert
function isGeojsonPointCoordinates(input) {
return (Array.isArray(input) &&
input.length >= 2 &&
input.every((item) => typeof item === 'number'));
}
export function isGeojsonLineStringCoordinates(input) {
return Array.isArray(input) && input.every(isGeojsonPointCoordinates);
}
export function isGeojsonRingCoordinates(input) {
return Array.isArray(input) && input.every(isGeojsonPointCoordinates);
}
export function isGeojsonPolygonCoordinates(input) {
return Array.isArray(input) && input.every(isGeojsonRingCoordinates);
}
export function isGeojsonMultiPointCoordinates(input) {
return Array.isArray(input) && input.every(isGeojsonPointCoordinates);
}
export function isGeojsonMultiLineStringCoordinates(input) {
return Array.isArray(input) && input.every(isGeojsonLineStringCoordinates);
}
export function isGeojsonMultiPolygonCoordinates(input) {
return Array.isArray(input) && input.every(isGeojsonPolygonCoordinates);
}
export function isGeojsonPoint(input) {
return (typeof input === 'object' &&
input !== null &&
'type' in input &&
input.type === 'Point' &&
'coordinates' in input &&
isGeojsonPointCoordinates(input.coordinates));
}
export function isGeojsonLineString(input) {
return (typeof input === 'object' &&
input !== null &&
'type' in input &&
input.type === 'LineString' &&
'coordinates' in input &&
isGeojsonLineStringCoordinates(input.coordinates));
}
export function isGeojsonPolygon(input) {
return (typeof input === 'object' &&
input !== null &&
'type' in input &&
input.type === 'Polygon' &&
'coordinates' in input &&
Array.isArray(input.coordinates) &&
isGeojsonPolygonCoordinates(input.coordinates));
}
export function isGeojsonMultiPoint(input) {
return (typeof input === 'object' &&
input !== null &&
'type' in input &&
input.type === 'MultiPoint' &&
'coordinates' in input &&
isGeojsonMultiPointCoordinates(input.coordinates));
}
export function isGeojsonMultiLineString(input) {
return (typeof input === 'object' &&
input !== null &&
'type' in input &&
input.type === 'MultiLineString' &&
'coordinates' in input &&
isGeojsonMultiLineStringCoordinates(input.coordinates));
}
export function isGeojsonMultiPolygon(input) {
return (typeof input === 'object' &&
input !== null &&
'type' in input &&
input.type === 'MultiPolygon' &&
'coordinates' in input &&
Array.isArray(input.coordinates) &&
isGeojsonMultiPolygonCoordinates(input.coordinates));
}
export function isGeojsonGeometry(obj) {
const isObject = typeof obj === 'object' && obj !== null;
const hasStringType = isObject && 'type' in obj && typeof obj.type === 'string';
const isValidType = hasStringType &&
(obj.type === 'Point' ||
obj.type === 'LineString' ||
obj.type === 'Polygon' ||
obj.type === 'MultiPoint' ||
obj.type === 'MultiLineString' ||
obj.type === 'MultiPolygon');
const hasCoordinatesArray = isObject && 'coordinates' in obj && Array.isArray(obj.coordinates);
return isValidType && hasCoordinatesArray;
}
export function isGeojsonMultiGeometry(obj) {
const isObject = typeof obj === 'object' && obj !== null;
const hasStringType = isObject && 'type' in obj && typeof obj.type === 'string';
const isValidType = hasStringType &&
(obj.type === 'MultiPoint' ||
obj.type === 'MultiLineString' ||
obj.type === 'MultiPolygon');
const hasCoordinatesArray = isObject && 'coordinates' in obj && Array.isArray(obj.coordinates);
return isValidType && hasCoordinatesArray;
}
// Convert to Geometry
// Note: GeoJSON points can have more then two coordiantes
function geojsonPointCoordinatesToPoint(geojsonPointCoordinates) {
return geojsonPointCoordinates.slice(0, 2);
}
export function geojsonPointToPoint(geojsonPoint) {
return geojsonPointCoordinatesToPoint(geojsonPoint.coordinates);
}
export function geojsonLineStringToLineString(geojsonLineString) {
return conformLineString(geojsonLineString.coordinates.map(geojsonPointCoordinatesToPoint));
}
export function geojsonPolygonToRing(geojsonPolygon, close = false) {
const outerRing = conformRing(geojsonPolygon.coordinates[0].map(geojsonPointCoordinatesToPoint));
return close ? [...outerRing, outerRing[0]] : outerRing;
}
export function geojsonPolygonToPolygon(geojsonPolygon, close = false) {
const polygon = conformPolygon(geojsonPolygon.coordinates.map((ring) => ring.map(geojsonPointCoordinatesToPoint)));
return close ? polygon.map((ring) => [...ring, ring[0]]) : polygon;
}
export function geojsonMultiPointToMultiPoint(geojsonMultiPoint) {
return geojsonMultiPoint.coordinates.map(geojsonPointCoordinatesToPoint);
}
export function geojsonMultiLineStringToMultiLineString(geojsonMultiLineString) {
return conformMultiLineString(geojsonMultiLineString.coordinates.map((l) => l.map(geojsonPointCoordinatesToPoint)));
}
export function geojsonMultiPolygonToMultiPolygon(geojsonMultiPolygon, close = false) {
const multipolygon = conformMultiPolygon(geojsonMultiPolygon.coordinates.map((p) => p.map((l) => l.map(geojsonPointCoordinatesToPoint))));
return close
? multipolygon.map((polygon) => polygon.map((ring) => [...ring, ring[0]]))
: multipolygon;
}
/**
* Converts a GeoJSON Geometry to a Geometry
* @param geojsonGeometry - GeoJSON Geometry
* @returns Geometry
*/
export function geojsonGeometryToGeometry(geojsonGeometry) {
if (isGeojsonPoint(geojsonGeometry)) {
return geojsonPointToPoint(geojsonGeometry);
}
else if (isGeojsonLineString(geojsonGeometry)) {
return geojsonLineStringToLineString(geojsonGeometry);
}
else if (isGeojsonPolygon(geojsonGeometry)) {
return geojsonPolygonToPolygon(geojsonGeometry);
}
else if (isGeojsonMultiPoint(geojsonGeometry)) {
return geojsonMultiPointToMultiPoint(geojsonGeometry);
}
else if (isGeojsonMultiLineString(geojsonGeometry)) {
return geojsonMultiLineStringToMultiLineString(geojsonGeometry);
}
else if (isGeojsonMultiPolygon(geojsonGeometry)) {
return geojsonMultiPolygonToMultiPolygon(geojsonGeometry);
}
else {
throw new Error('Geometry type not supported');
}
}
// Convert to SVG
export function geojsonGeometryToSvgGeometry(geojsonGeometry) {
return geometryToSvgGeometry(geojsonGeometryToGeometry(geojsonGeometry));
}
// Wrap Geometry in Feature
export function geojsonGeometryToGeojsonFeature(geojsonGeometry, properties) {
return {
type: 'Feature',
properties: properties ? properties : {},
geometry: geojsonGeometry
};
}
export function geojsonFeaturesToGeojsonFeatureCollection(geojsonFeatures) {
if (!Array.isArray(geojsonFeatures)) {
geojsonFeatures = [geojsonFeatures];
}
return {
type: 'FeatureCollection',
features: geojsonFeatures
};
}
export function geojsonGeometriesToGeojsonFeatureCollection(geojsonGeometries, properties) {
return {
type: 'FeatureCollection',
features: geojsonGeometries.map((geometry, i) => properties
? geojsonGeometryToGeojsonFeature(geometry, properties[i])
: geojsonGeometryToGeojsonFeature(geometry))
};
}
export function geojsonFeatureToGeojsonGeometry(geojsonFeature) {
return geojsonFeature.geometry;
}
export function geojsonFeatureCollectionToGeojsonGeometries(geojsonFeatureCollection) {
return geojsonFeatureCollection.features.map(geojsonFeatureToGeojsonGeometry);
}
// Expand
export function expandGeojsonMultiPointToGeojsonPoints(geojsonMultiPoint) {
return geojsonMultiPoint.coordinates.map((point) => {
return {
type: 'Point',
coordinates: point
};
});
}
export function expandGeojsonMultiLineStringToGeojsonLineStrings(geojsonMultiLineString) {
return geojsonMultiLineString.coordinates.map((lineString) => {
return {
type: 'LineString',
coordinates: lineString
};
});
}
export function expandGeojsonMultiPolygonToGeojsonPolygons(geojsonMultiPolygon) {
return geojsonMultiPolygon.coordinates.map((polygon) => {
return {
type: 'Polygon',
coordinates: polygon
};
});
}
export function expandGeojsonMultiGeometryToGeojsonGeometries(geojsonMultiGeometry) {
if (isGeojsonMultiPoint(geojsonMultiGeometry)) {
return expandGeojsonMultiPointToGeojsonPoints(geojsonMultiGeometry);
}
else if (isGeojsonMultiLineString(geojsonMultiGeometry)) {
return expandGeojsonMultiLineStringToGeojsonLineStrings(geojsonMultiGeometry);
}
else if (isGeojsonMultiPolygon(geojsonMultiGeometry)) {
return expandGeojsonMultiPolygonToGeojsonPolygons(geojsonMultiGeometry);
}
else {
throw new Error('Geometry type not supported');
}
}
// Contract
export function contractGeojsonPointsToGeojsonMultiPoint(geojsonPoints) {
return {
type: 'MultiPoint',
coordinates: geojsonPoints.map((geojsonPoint) => geojsonPoint.coordinates)
};
}
export function contractGeojsonLineStringsToGeojsonMultiLineString(geojsonLineStrings) {
return {
type: 'MultiLineString',
coordinates: geojsonLineStrings.map((geojsonLineString) => geojsonLineString.coordinates)
};
}
export function contractGeojsonPolygonsToGeojsonMultiPolygon(geojsonPolygons) {
return {
type: 'MultiPolygon',
coordinates: geojsonPolygons.map((geojsonPolygon) => geojsonPolygon.coordinates)
};
}
export function contractGeojsonGeometriesToGeojsonMultiGeometry(geojsonGeometries) {
if (geojsonGeometries.every(isGeojsonPoint)) {
return contractGeojsonPointsToGeojsonMultiPoint(geojsonGeometries);
}
else if (geojsonGeometries.every(isGeojsonLineString)) {
return contractGeojsonLineStringsToGeojsonMultiLineString(geojsonGeometries);
}
else if (geojsonGeometries.every(isGeojsonPolygon)) {
return contractGeojsonPolygonsToGeojsonMultiPolygon(geojsonGeometries);
}
else {
throw new Error('Geometry type not supported');
}
}
export function mergeGeojsonFeaturesCollections(geojsonFeatureCollections) {
return {
type: 'FeatureCollection',
features: geojsonFeatureCollections
.map((geojsonFeatureCollection) => geojsonFeatureCollection.features)
.flat(1)
};
}