@spatial/invariant
Version:
turf invariant module
207 lines (190 loc) • 6.97 kB
JavaScript
import { isNumber } from '@spatial/helpers';
/**
* Unwrap a coordinate from a Point Feature, Geometry or a single coordinate.
*
* @name getCoord
* @param {Array<number>|Geometry<Point>|Feature<Point>} obj Object
* @returns {Array<number>} coordinates
* @example
* var pt = turf.point([10, 10]);
*
* var coord = turf.getCoord(pt);
* //= [10, 10]
*/
export function getCoord(obj) {
if (!obj) throw new Error('obj is required');
const coordinates = getCoords(obj);
// getCoord() must contain at least two numbers (Point)
if (coordinates.length > 1 && isNumber(coordinates[0]) && isNumber(coordinates[1])) {
return coordinates;
} else {
throw new Error('Coordinate is not a valid Point');
}
}
/**
* Unwrap coordinates from a Feature, Geometry Object or an Array of numbers
*
* @name getCoords
* @param {Array<number>|Geometry|Feature} obj Object
* @returns {Array<number>} coordinates
* @example
* var poly = turf.polygon([[[119.32, -8.7], [119.55, -8.69], [119.51, -8.54], [119.32, -8.7]]]);
*
* var coord = turf.getCoords(poly);
* //= [[[119.32, -8.7], [119.55, -8.69], [119.51, -8.54], [119.32, -8.7]]]
*/
export function getCoords(obj) {
if (!obj) throw new Error('obj is required');
let coordinates;
// Array of numbers
if (obj.length) {
coordinates = obj;
// Geometry Object
} else if (obj.coordinates) {
coordinates = obj.coordinates;
// Feature
} else if (obj.geometry && obj.geometry.coordinates) {
coordinates = obj.geometry.coordinates;
}
// Checks if coordinates contains a number
if (coordinates) {
containsNumber(coordinates);
return coordinates;
}
throw new Error('No valid coordinates');
}
/**
* Checks if coordinates contains a number
*
* @name containsNumber
* @param {Array<any>} coordinates GeoJSON Coordinates
* @returns {boolean} true if Array contains a number
*/
export function containsNumber(coordinates) {
if (coordinates.length > 1 && isNumber(coordinates[0]) && isNumber(coordinates[1])) {
return true;
}
if (Array.isArray(coordinates[0]) && coordinates[0].length) {
return containsNumber(coordinates[0]);
}
throw new Error('coordinates must only contain numbers');
}
/**
* Enforce expectations about types of GeoJSON objects for Turf.
*
* @name geojsonType
* @param {GeoJSON} value any GeoJSON object
* @param {string} type expected GeoJSON type
* @param {string} name name of calling function
* @throws {Error} if value is not the expected type.
*/
export function geojsonType(value, type, name) {
if (!type || !name) throw new Error('type and name required');
if (!value || value.type !== type) {
throw new Error(`Invalid input to ${ name }: must be a ${ type }, given ${ value.type}`);
}
}
/**
* Enforce expectations about types of {@link Feature} inputs for Turf.
* Internally this uses {@link geojsonType} to judge geometry types.
*
* @name featureOf
* @param {Feature} feature a feature with an expected geometry type
* @param {string} type expected GeoJSON type
* @param {string} name name of calling function
* @throws {Error} error if value is not the expected type.
*/
export function featureOf(feature, type, name) {
if (!feature) throw new Error('No feature passed');
if (!name) throw new Error('.featureOf() requires a name');
if (!feature || feature.type !== 'Feature' || !feature.geometry) {
throw new Error(`Invalid input to ${ name }, Feature with geometry required`);
}
if (!feature.geometry || feature.geometry.type !== type) {
throw new Error(`Invalid input to ${ name }: must be a ${ type }, given ${ feature.geometry.type}`);
}
}
/**
* Enforce expectations about types of {@link FeatureCollection} inputs for Turf.
* Internally this uses {@link geojsonType} to judge geometry types.
*
* @name collectionOf
* @param {FeatureCollection} featureCollection a FeatureCollection for which features will be judged
* @param {string} type expected GeoJSON type
* @param {string} name name of calling function
* @throws {Error} if value is not the expected type.
*/
export function collectionOf(featureCollection, type, name) {
if (!featureCollection) throw new Error('No featureCollection passed');
if (!name) throw new Error('.collectionOf() requires a name');
if (!featureCollection || featureCollection.type !== 'FeatureCollection') {
throw new Error(`Invalid input to ${ name }, FeatureCollection required`);
}
for (let i = 0; i < featureCollection.features.length; i++) {
const feature = featureCollection.features[i];
if (!feature || feature.type !== 'Feature' || !feature.geometry) {
throw new Error(`Invalid input to ${ name }, Feature with geometry required`);
}
if (!feature.geometry || feature.geometry.type !== type) {
throw new Error(`Invalid input to ${ name }: must be a ${ type }, given ${ feature.geometry.type}`);
}
}
}
/**
* Get Geometry from Feature or Geometry Object
*
* @param {Feature|Geometry} geojson GeoJSON Feature or Geometry Object
* @returns {Geometry|null} GeoJSON Geometry Object
* @throws {Error} if geojson is not a Feature or Geometry Object
* @example
* var point = {
* "type": "Feature",
* "properties": {},
* "geometry": {
* "type": "Point",
* "coordinates": [110, 40]
* }
* }
* var geom = turf.getGeom(point)
* //={"type": "Point", "coordinates": [110, 40]}
*/
export function getGeom(geojson) {
if (!geojson) throw new Error('geojson is required');
if (geojson.geometry !== undefined) return geojson.geometry;
if (geojson.coordinates || geojson.geometries) return geojson;
throw new Error('geojson must be a valid Feature or Geometry Object');
}
/**
* Get Geometry Type from Feature or Geometry Object
*
* @throws {Error} **DEPRECATED** in v5.0.0 in favor of getType
*/
export function getGeomType() {
throw new Error('invariant.getGeomType has been deprecated in v5.0 in favor of invariant.getType');
}
/**
* Get GeoJSON object's type, Geometry type is prioritize.
*
* @param {GeoJSON} geojson GeoJSON object
* @param {string} [name] name of the variable to display in error message
* @returns {string} GeoJSON type
* @example
* var point = {
* "type": "Feature",
* "properties": {},
* "geometry": {
* "type": "Point",
* "coordinates": [110, 40]
* }
* }
* var geom = turf.getType(point)
* //="Point"
*/
export function getType(geojson, name) {
if (!geojson) throw new Error(`${name || 'geojson' } is required`);
// GeoJSON Feature & GeometryCollection
if (geojson.geometry && geojson.geometry.type) return geojson.geometry.type;
// GeoJSON Geometry & FeatureCollection
if (geojson.type) return geojson.type;
throw new Error(`${name || 'geojson' } is invalid`);
}