UNPKG

@spatial/invariant

Version:
209 lines (191 loc) 7.03 kB
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] */ 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]]] */ 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 */ 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. */ 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. */ 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. */ 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]} */ 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 */ 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" */ 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`); } export { collectionOf, containsNumber, featureOf, geojsonType, getCoord, getCoords, getGeom, getGeomType, getType };