James Beard e5afd5c38b
Upgrade typescript, prettier, et al to continue to modernise build environment (#2519)
* Simplify nx config (no point separately caching es and js builds - they both need to be done for any code changes). Fix some no-op type definitions i.e. X extends any, and enforce templated property types as having to extend GeoJsonProperties throughout.

* Upgrade typescript. Had to update topojson-* type defs to avoid the P = GeoJsonProperties problem in geojson-rbush. Also fix a couple of floating point precision related issues that eslint now apparently catches!

* Retire tslint.

* Upgrade eslint and prettier. Add minimal prettier config (defaults have changed) to avoid widespread, minor formatting changes (trailing commas mostly).
2023-10-24 21:51:43 +11:00

843 lines
24 KiB
TypeScript

import {
BBox,
Feature,
FeatureCollection,
Geometry,
GeometryCollection,
GeometryObject,
LineString,
MultiLineString,
MultiPoint,
MultiPolygon,
Point,
Polygon,
Position,
GeoJsonProperties,
} from "geojson";
import { Id } from "./lib/geojson";
export * from "./lib/geojson";
// TurfJS Combined Types
export type Coord = Feature<Point> | Point | Position;
// TurfJS String Types
export type Units =
| "meters"
| "metres"
| "millimeters"
| "millimetres"
| "centimeters"
| "centimetres"
| "kilometers"
| "kilometres"
| "miles"
| "nauticalmiles"
| "inches"
| "yards"
| "feet"
| "radians"
| "degrees";
export type AreaUnits =
| Exclude<Units, "radians" | "degrees">
| "acres"
| "hectares";
export type Grid = "point" | "square" | "hex" | "triangle";
export type Corners = "sw" | "se" | "nw" | "ne" | "center" | "centroid";
export type Lines = LineString | MultiLineString | Polygon | MultiPolygon;
export type AllGeoJSON =
| Feature
| FeatureCollection
| Geometry
| GeometryCollection;
/**
* @module helpers
*/
/**
* Earth Radius used with the Harvesine formula and approximates using a spherical (non-ellipsoid) Earth.
*
* @memberof helpers
* @type {number}
*/
export const earthRadius = 6371008.8;
/**
* Unit of measurement factors using a spherical (non-ellipsoid) earth radius.
*
* Keys are the name of the unit, values are the number of that unit in a single radian
*
* @memberof helpers
* @type {Object}
*/
export const factors: Record<Units, number> = {
centimeters: earthRadius * 100,
centimetres: earthRadius * 100,
degrees: 360 / (2 * Math.PI),
feet: earthRadius * 3.28084,
inches: earthRadius * 39.37,
kilometers: earthRadius / 1000,
kilometres: earthRadius / 1000,
meters: earthRadius,
metres: earthRadius,
miles: earthRadius / 1609.344,
millimeters: earthRadius * 1000,
millimetres: earthRadius * 1000,
nauticalmiles: earthRadius / 1852,
radians: 1,
yards: earthRadius * 1.0936,
};
/**
* Area of measurement factors based on 1 square meter.
*
* @memberof helpers
* @type {Object}
*/
export const areaFactors: Record<AreaUnits, number> = {
acres: 0.000247105,
centimeters: 10000,
centimetres: 10000,
feet: 10.763910417,
hectares: 0.0001,
inches: 1550.003100006,
kilometers: 0.000001,
kilometres: 0.000001,
meters: 1,
metres: 1,
miles: 3.86e-7,
nauticalmiles: 2.9155334959812285e-7,
millimeters: 1000000,
millimetres: 1000000,
yards: 1.195990046,
};
/**
* Wraps a GeoJSON {@link Geometry} in a GeoJSON {@link Feature}.
*
* @name feature
* @param {Geometry} geometry input geometry
* @param {Object} [properties={}] an Object of key-value pairs to add as properties
* @param {Object} [options={}] Optional Parameters
* @param {Array<number>} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature
* @param {string|number} [options.id] Identifier associated with the Feature
* @returns {Feature} a GeoJSON Feature
* @example
* var geometry = {
* "type": "Point",
* "coordinates": [110, 50]
* };
*
* var feature = turf.feature(geometry);
*
* //=feature
*/
export function feature<
G extends GeometryObject = Geometry,
P extends GeoJsonProperties = GeoJsonProperties,
>(
geom: G | null,
properties?: P,
options: { bbox?: BBox; id?: Id } = {}
): Feature<G, P> {
const feat: any = { type: "Feature" };
if (options.id === 0 || options.id) {
feat.id = options.id;
}
if (options.bbox) {
feat.bbox = options.bbox;
}
feat.properties = properties || {};
feat.geometry = geom;
return feat;
}
/**
* Creates a GeoJSON {@link Geometry} from a Geometry string type & coordinates.
* For GeometryCollection type use `helpers.geometryCollection`
*
* @name geometry
* @param {string} type Geometry Type
* @param {Array<any>} coordinates Coordinates
* @param {Object} [options={}] Optional Parameters
* @returns {Geometry} a GeoJSON Geometry
* @example
* var type = "Point";
* var coordinates = [110, 50];
* var geometry = turf.geometry(type, coordinates);
* // => geometry
*/
export function geometry(
type:
| "Point"
| "LineString"
| "Polygon"
| "MultiPoint"
| "MultiLineString"
| "MultiPolygon",
coordinates: any[],
_options: Record<string, never> = {}
) {
switch (type) {
case "Point":
return point(coordinates).geometry;
case "LineString":
return lineString(coordinates).geometry;
case "Polygon":
return polygon(coordinates).geometry;
case "MultiPoint":
return multiPoint(coordinates).geometry;
case "MultiLineString":
return multiLineString(coordinates).geometry;
case "MultiPolygon":
return multiPolygon(coordinates).geometry;
default:
throw new Error(type + " is invalid");
}
}
/**
* Creates a {@link Point} {@link Feature} from a Position.
*
* @name point
* @param {Array<number>} coordinates longitude, latitude position (each in decimal degrees)
* @param {Object} [properties={}] an Object of key-value pairs to add as properties
* @param {Object} [options={}] Optional Parameters
* @param {Array<number>} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature
* @param {string|number} [options.id] Identifier associated with the Feature
* @returns {Feature<Point>} a Point feature
* @example
* var point = turf.point([-75.343, 39.984]);
*
* //=point
*/
export function point<P extends GeoJsonProperties = GeoJsonProperties>(
coordinates: Position,
properties?: P,
options: { bbox?: BBox; id?: Id } = {}
): Feature<Point, P> {
if (!coordinates) {
throw new Error("coordinates is required");
}
if (!Array.isArray(coordinates)) {
throw new Error("coordinates must be an Array");
}
if (coordinates.length < 2) {
throw new Error("coordinates must be at least 2 numbers long");
}
if (!isNumber(coordinates[0]) || !isNumber(coordinates[1])) {
throw new Error("coordinates must contain numbers");
}
const geom: Point = {
type: "Point",
coordinates,
};
return feature(geom, properties, options);
}
/**
* Creates a {@link Point} {@link FeatureCollection} from an Array of Point coordinates.
*
* @name points
* @param {Array<Array<number>>} coordinates an array of Points
* @param {Object} [properties={}] Translate these properties to each Feature
* @param {Object} [options={}] Optional Parameters
* @param {Array<number>} [options.bbox] Bounding Box Array [west, south, east, north]
* associated with the FeatureCollection
* @param {string|number} [options.id] Identifier associated with the FeatureCollection
* @returns {FeatureCollection<Point>} Point Feature
* @example
* var points = turf.points([
* [-75, 39],
* [-80, 45],
* [-78, 50]
* ]);
*
* //=points
*/
export function points<P extends GeoJsonProperties = GeoJsonProperties>(
coordinates: Position[],
properties?: P,
options: { bbox?: BBox; id?: Id } = {}
): FeatureCollection<Point, P> {
return featureCollection(
coordinates.map((coords) => {
return point(coords, properties);
}),
options
);
}
/**
* Creates a {@link Polygon} {@link Feature} from an Array of LinearRings.
*
* @name polygon
* @param {Array<Array<Array<number>>>} coordinates an array of LinearRings
* @param {Object} [properties={}] an Object of key-value pairs to add as properties
* @param {Object} [options={}] Optional Parameters
* @param {Array<number>} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature
* @param {string|number} [options.id] Identifier associated with the Feature
* @returns {Feature<Polygon>} Polygon Feature
* @example
* var polygon = turf.polygon([[[-5, 52], [-4, 56], [-2, 51], [-7, 54], [-5, 52]]], { name: 'poly1' });
*
* //=polygon
*/
export function polygon<P extends GeoJsonProperties = GeoJsonProperties>(
coordinates: Position[][],
properties?: P,
options: { bbox?: BBox; id?: Id } = {}
): Feature<Polygon, P> {
for (const ring of coordinates) {
if (ring.length < 4) {
throw new Error(
"Each LinearRing of a Polygon must have 4 or more Positions."
);
}
if (ring[ring.length - 1].length !== ring[0].length) {
throw new Error("First and last Position are not equivalent.");
}
for (let j = 0; j < ring[ring.length - 1].length; j++) {
// Check if first point of Polygon contains two numbers
if (ring[ring.length - 1][j] !== ring[0][j]) {
throw new Error("First and last Position are not equivalent.");
}
}
}
const geom: Polygon = {
type: "Polygon",
coordinates,
};
return feature(geom, properties, options);
}
/**
* Creates a {@link Polygon} {@link FeatureCollection} from an Array of Polygon coordinates.
*
* @name polygons
* @param {Array<Array<Array<Array<number>>>>} coordinates an array of Polygon coordinates
* @param {Object} [properties={}] an Object of key-value pairs to add as properties
* @param {Object} [options={}] Optional Parameters
* @param {Array<number>} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature
* @param {string|number} [options.id] Identifier associated with the FeatureCollection
* @returns {FeatureCollection<Polygon>} Polygon FeatureCollection
* @example
* var polygons = turf.polygons([
* [[[-5, 52], [-4, 56], [-2, 51], [-7, 54], [-5, 52]]],
* [[[-15, 42], [-14, 46], [-12, 41], [-17, 44], [-15, 42]]],
* ]);
*
* //=polygons
*/
export function polygons<P extends GeoJsonProperties = GeoJsonProperties>(
coordinates: Position[][][],
properties?: P,
options: { bbox?: BBox; id?: Id } = {}
): FeatureCollection<Polygon, P> {
return featureCollection(
coordinates.map((coords) => {
return polygon(coords, properties);
}),
options
);
}
/**
* Creates a {@link LineString} {@link Feature} from an Array of Positions.
*
* @name lineString
* @param {Array<Array<number>>} coordinates an array of Positions
* @param {Object} [properties={}] an Object of key-value pairs to add as properties
* @param {Object} [options={}] Optional Parameters
* @param {Array<number>} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature
* @param {string|number} [options.id] Identifier associated with the Feature
* @returns {Feature<LineString>} LineString Feature
* @example
* var linestring1 = turf.lineString([[-24, 63], [-23, 60], [-25, 65], [-20, 69]], {name: 'line 1'});
* var linestring2 = turf.lineString([[-14, 43], [-13, 40], [-15, 45], [-10, 49]], {name: 'line 2'});
*
* //=linestring1
* //=linestring2
*/
export function lineString<P extends GeoJsonProperties = GeoJsonProperties>(
coordinates: Position[],
properties?: P,
options: { bbox?: BBox; id?: Id } = {}
): Feature<LineString, P> {
if (coordinates.length < 2) {
throw new Error("coordinates must be an array of two or more positions");
}
const geom: LineString = {
type: "LineString",
coordinates,
};
return feature(geom, properties, options);
}
/**
* Creates a {@link LineString} {@link FeatureCollection} from an Array of LineString coordinates.
*
* @name lineStrings
* @param {Array<Array<Array<number>>>} coordinates an array of LinearRings
* @param {Object} [properties={}] an Object of key-value pairs to add as properties
* @param {Object} [options={}] Optional Parameters
* @param {Array<number>} [options.bbox] Bounding Box Array [west, south, east, north]
* associated with the FeatureCollection
* @param {string|number} [options.id] Identifier associated with the FeatureCollection
* @returns {FeatureCollection<LineString>} LineString FeatureCollection
* @example
* var linestrings = turf.lineStrings([
* [[-24, 63], [-23, 60], [-25, 65], [-20, 69]],
* [[-14, 43], [-13, 40], [-15, 45], [-10, 49]]
* ]);
*
* //=linestrings
*/
export function lineStrings<P extends GeoJsonProperties = GeoJsonProperties>(
coordinates: Position[][],
properties?: P,
options: { bbox?: BBox; id?: Id } = {}
): FeatureCollection<LineString, P> {
return featureCollection(
coordinates.map((coords) => {
return lineString(coords, properties);
}),
options
);
}
/**
* Takes one or more {@link Feature|Features} and creates a {@link FeatureCollection}.
*
* @name featureCollection
* @param {Feature[]} features input features
* @param {Object} [options={}] Optional Parameters
* @param {Array<number>} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature
* @param {string|number} [options.id] Identifier associated with the Feature
* @returns {FeatureCollection} FeatureCollection of Features
* @example
* var locationA = turf.point([-75.343, 39.984], {name: 'Location A'});
* var locationB = turf.point([-75.833, 39.284], {name: 'Location B'});
* var locationC = turf.point([-75.534, 39.123], {name: 'Location C'});
*
* var collection = turf.featureCollection([
* locationA,
* locationB,
* locationC
* ]);
*
* //=collection
*/
export function featureCollection<
G extends GeometryObject = Geometry,
P extends GeoJsonProperties = GeoJsonProperties,
>(
features: Array<Feature<G, P>>,
options: { bbox?: BBox; id?: Id } = {}
): FeatureCollection<G, P> {
const fc: any = { type: "FeatureCollection" };
if (options.id) {
fc.id = options.id;
}
if (options.bbox) {
fc.bbox = options.bbox;
}
fc.features = features;
return fc;
}
/**
* Creates a {@link Feature<MultiLineString>} based on a
* coordinate array. Properties can be added optionally.
*
* @name multiLineString
* @param {Array<Array<Array<number>>>} coordinates an array of LineStrings
* @param {Object} [properties={}] an Object of key-value pairs to add as properties
* @param {Object} [options={}] Optional Parameters
* @param {Array<number>} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature
* @param {string|number} [options.id] Identifier associated with the Feature
* @returns {Feature<MultiLineString>} a MultiLineString feature
* @throws {Error} if no coordinates are passed
* @example
* var multiLine = turf.multiLineString([[[0,0],[10,10]]]);
*
* //=multiLine
*/
export function multiLineString<
P extends GeoJsonProperties = GeoJsonProperties,
>(
coordinates: Position[][],
properties?: P,
options: { bbox?: BBox; id?: Id } = {}
): Feature<MultiLineString, P> {
const geom: MultiLineString = {
type: "MultiLineString",
coordinates,
};
return feature(geom, properties, options);
}
/**
* Creates a {@link Feature<MultiPoint>} based on a
* coordinate array. Properties can be added optionally.
*
* @name multiPoint
* @param {Array<Array<number>>} coordinates an array of Positions
* @param {Object} [properties={}] an Object of key-value pairs to add as properties
* @param {Object} [options={}] Optional Parameters
* @param {Array<number>} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature
* @param {string|number} [options.id] Identifier associated with the Feature
* @returns {Feature<MultiPoint>} a MultiPoint feature
* @throws {Error} if no coordinates are passed
* @example
* var multiPt = turf.multiPoint([[0,0],[10,10]]);
*
* //=multiPt
*/
export function multiPoint<P extends GeoJsonProperties = GeoJsonProperties>(
coordinates: Position[],
properties?: P,
options: { bbox?: BBox; id?: Id } = {}
): Feature<MultiPoint, P> {
const geom: MultiPoint = {
type: "MultiPoint",
coordinates,
};
return feature(geom, properties, options);
}
/**
* Creates a {@link Feature<MultiPolygon>} based on a
* coordinate array. Properties can be added optionally.
*
* @name multiPolygon
* @param {Array<Array<Array<Array<number>>>>} coordinates an array of Polygons
* @param {Object} [properties={}] an Object of key-value pairs to add as properties
* @param {Object} [options={}] Optional Parameters
* @param {Array<number>} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature
* @param {string|number} [options.id] Identifier associated with the Feature
* @returns {Feature<MultiPolygon>} a multipolygon feature
* @throws {Error} if no coordinates are passed
* @example
* var multiPoly = turf.multiPolygon([[[[0,0],[0,10],[10,10],[10,0],[0,0]]]]);
*
* //=multiPoly
*
*/
export function multiPolygon<P extends GeoJsonProperties = GeoJsonProperties>(
coordinates: Position[][][],
properties?: P,
options: { bbox?: BBox; id?: Id } = {}
): Feature<MultiPolygon, P> {
const geom: MultiPolygon = {
type: "MultiPolygon",
coordinates,
};
return feature(geom, properties, options);
}
/**
* Creates a {@link Feature<GeometryCollection>} based on a
* coordinate array. Properties can be added optionally.
*
* @name geometryCollection
* @param {Array<Geometry>} geometries an array of GeoJSON Geometries
* @param {Object} [properties={}] an Object of key-value pairs to add as properties
* @param {Object} [options={}] Optional Parameters
* @param {Array<number>} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature
* @param {string|number} [options.id] Identifier associated with the Feature
* @returns {Feature<GeometryCollection>} a GeoJSON GeometryCollection Feature
* @example
* var pt = turf.geometry("Point", [100, 0]);
* var line = turf.geometry("LineString", [[101, 0], [102, 1]]);
* var collection = turf.geometryCollection([pt, line]);
*
* // => collection
*/
export function geometryCollection<
P extends GeoJsonProperties = GeoJsonProperties,
>(
geometries: Array<
Point | LineString | Polygon | MultiPoint | MultiLineString | MultiPolygon
>,
properties?: P,
options: { bbox?: BBox; id?: Id } = {}
): Feature<GeometryCollection, P> {
const geom: GeometryCollection = {
type: "GeometryCollection",
geometries,
};
return feature(geom, properties, options);
}
/**
* Round number to precision
*
* @param {number} num Number
* @param {number} [precision=0] Precision
* @returns {number} rounded number
* @example
* turf.round(120.4321)
* //=120
*
* turf.round(120.4321, 2)
* //=120.43
*/
export function round(num: number, precision = 0): number {
if (precision && !(precision >= 0)) {
throw new Error("precision must be a positive number");
}
const multiplier = Math.pow(10, precision || 0);
return Math.round(num * multiplier) / multiplier;
}
/**
* Convert a distance measurement (assuming a spherical Earth) from radians to a more friendly unit.
* Valid units: miles, nauticalmiles, inches, yards, meters, metres, kilometers, centimeters, feet
*
* @name radiansToLength
* @param {number} radians in radians across the sphere
* @param {string} [units="kilometers"] can be degrees, radians, miles, inches, yards, metres,
* meters, kilometres, kilometers.
* @returns {number} distance
*/
export function radiansToLength(
radians: number,
units: Units = "kilometers"
): number {
const factor = factors[units];
if (!factor) {
throw new Error(units + " units is invalid");
}
return radians * factor;
}
/**
* Convert a distance measurement (assuming a spherical Earth) from a real-world unit into radians
* Valid units: miles, nauticalmiles, inches, yards, meters, metres, kilometers, centimeters, feet
*
* @name lengthToRadians
* @param {number} distance in real units
* @param {string} [units="kilometers"] can be degrees, radians, miles, inches, yards, metres,
* meters, kilometres, kilometers.
* @returns {number} radians
*/
export function lengthToRadians(
distance: number,
units: Units = "kilometers"
): number {
const factor = factors[units];
if (!factor) {
throw new Error(units + " units is invalid");
}
return distance / factor;
}
/**
* Convert a distance measurement (assuming a spherical Earth) from a real-world unit into degrees
* Valid units: miles, nauticalmiles, inches, yards, meters, metres, centimeters, kilometres, feet
*
* @name lengthToDegrees
* @param {number} distance in real units
* @param {string} [units="kilometers"] can be degrees, radians, miles, inches, yards, metres,
* meters, kilometres, kilometers.
* @returns {number} degrees
*/
export function lengthToDegrees(distance: number, units?: Units): number {
return radiansToDegrees(lengthToRadians(distance, units));
}
/**
* Converts any bearing angle from the north line direction (positive clockwise)
* and returns an angle between 0-360 degrees (positive clockwise), 0 being the north line
*
* @name bearingToAzimuth
* @param {number} bearing angle, between -180 and +180 degrees
* @returns {number} angle between 0 and 360 degrees
*/
export function bearingToAzimuth(bearing: number): number {
let angle = bearing % 360;
if (angle < 0) {
angle += 360;
}
return angle;
}
/**
* Converts an angle in radians to degrees
*
* @name radiansToDegrees
* @param {number} radians angle in radians
* @returns {number} degrees between 0 and 360 degrees
*/
export function radiansToDegrees(radians: number): number {
const degrees = radians % (2 * Math.PI);
return (degrees * 180) / Math.PI;
}
/**
* Converts an angle in degrees to radians
*
* @name degreesToRadians
* @param {number} degrees angle between 0 and 360 degrees
* @returns {number} angle in radians
*/
export function degreesToRadians(degrees: number): number {
const radians = degrees % 360;
return (radians * Math.PI) / 180;
}
/**
* Converts a length to the requested unit.
* Valid units: miles, nauticalmiles, inches, yards, meters, metres, kilometers, centimeters, feet
*
* @param {number} length to be converted
* @param {Units} [originalUnit="kilometers"] of the length
* @param {Units} [finalUnit="kilometers"] returned unit
* @returns {number} the converted length
*/
export function convertLength(
length: number,
originalUnit: Units = "kilometers",
finalUnit: Units = "kilometers"
): number {
if (!(length >= 0)) {
throw new Error("length must be a positive number");
}
return radiansToLength(lengthToRadians(length, originalUnit), finalUnit);
}
/**
* Converts a area to the requested unit.
* Valid units: kilometers, kilometres, meters, metres, centimetres, millimeters, acres, miles, yards, feet, inches, hectares
* @param {number} area to be converted
* @param {Units} [originalUnit="meters"] of the distance
* @param {Units} [finalUnit="kilometers"] returned unit
* @returns {number} the converted area
*/
export function convertArea(
area: number,
originalUnit: AreaUnits = "meters",
finalUnit: AreaUnits = "kilometers"
): number {
if (!(area >= 0)) {
throw new Error("area must be a positive number");
}
const startFactor = areaFactors[originalUnit];
if (!startFactor) {
throw new Error("invalid original units");
}
const finalFactor = areaFactors[finalUnit];
if (!finalFactor) {
throw new Error("invalid final units");
}
return (area / startFactor) * finalFactor;
}
/**
* isNumber
*
* @param {*} num Number to validate
* @returns {boolean} true/false
* @example
* turf.isNumber(123)
* //=true
* turf.isNumber('foo')
* //=false
*/
export function isNumber(num: any): boolean {
return !isNaN(num) && num !== null && !Array.isArray(num);
}
/**
* isObject
*
* @param {*} input variable to validate
* @returns {boolean} true/false, including false for Arrays and Functions
* @example
* turf.isObject({elevation: 10})
* //=true
* turf.isObject('foo')
* //=false
*/
export function isObject(input: any): boolean {
return input !== null && typeof input === "object" && !Array.isArray(input);
}
/**
* Validate BBox
*
* @private
* @param {Array<number>} bbox BBox to validate
* @returns {void}
* @throws {Error} if BBox is not valid
* @example
* validateBBox([-180, -40, 110, 50])
* //=OK
* validateBBox([-180, -40])
* //=Error
* validateBBox('Foo')
* //=Error
* validateBBox(5)
* //=Error
* validateBBox(null)
* //=Error
* validateBBox(undefined)
* //=Error
*/
export function validateBBox(bbox: any): void {
if (!bbox) {
throw new Error("bbox is required");
}
if (!Array.isArray(bbox)) {
throw new Error("bbox must be an Array");
}
if (bbox.length !== 4 && bbox.length !== 6) {
throw new Error("bbox must be an Array of 4 or 6 numbers");
}
bbox.forEach((num) => {
if (!isNumber(num)) {
throw new Error("bbox must only contain numbers");
}
});
}
/**
* Validate Id
*
* @private
* @param {string|number} id Id to validate
* @returns {void}
* @throws {Error} if Id is not valid
* @example
* validateId([-180, -40, 110, 50])
* //=Error
* validateId([-180, -40])
* //=Error
* validateId('Foo')
* //=OK
* validateId(5)
* //=OK
* validateId(null)
* //=Error
* validateId(undefined)
* //=Error
*/
export function validateId(id: any): void {
if (!id) {
throw new Error("id is required");
}
if (["string", "number"].indexOf(typeof id) === -1) {
throw new Error("id must be a number or a string");
}
}