index.js 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696
  1. /**
  2. * @module helpers
  3. */
  4. /**
  5. * Earth Radius used with the Harvesine formula and approximates using a spherical (non-ellipsoid) Earth.
  6. *
  7. * @memberof helpers
  8. * @type {number}
  9. */
  10. export var earthRadius = 6371008.8;
  11. /**
  12. * Unit of measurement factors using a spherical (non-ellipsoid) earth radius.
  13. *
  14. * @memberof helpers
  15. * @type {Object}
  16. */
  17. export var factors = {
  18. centimeters: earthRadius * 100,
  19. centimetres: earthRadius * 100,
  20. degrees: earthRadius / 111325,
  21. feet: earthRadius * 3.28084,
  22. inches: earthRadius * 39.37,
  23. kilometers: earthRadius / 1000,
  24. kilometres: earthRadius / 1000,
  25. meters: earthRadius,
  26. metres: earthRadius,
  27. miles: earthRadius / 1609.344,
  28. millimeters: earthRadius * 1000,
  29. millimetres: earthRadius * 1000,
  30. nauticalmiles: earthRadius / 1852,
  31. radians: 1,
  32. yards: earthRadius * 1.0936,
  33. };
  34. /**
  35. * Units of measurement factors based on 1 meter.
  36. *
  37. * @memberof helpers
  38. * @type {Object}
  39. */
  40. export var unitsFactors = {
  41. centimeters: 100,
  42. centimetres: 100,
  43. degrees: 1 / 111325,
  44. feet: 3.28084,
  45. inches: 39.37,
  46. kilometers: 1 / 1000,
  47. kilometres: 1 / 1000,
  48. meters: 1,
  49. metres: 1,
  50. miles: 1 / 1609.344,
  51. millimeters: 1000,
  52. millimetres: 1000,
  53. nauticalmiles: 1 / 1852,
  54. radians: 1 / earthRadius,
  55. yards: 1.0936133,
  56. };
  57. /**
  58. * Area of measurement factors based on 1 square meter.
  59. *
  60. * @memberof helpers
  61. * @type {Object}
  62. */
  63. export var areaFactors = {
  64. acres: 0.000247105,
  65. centimeters: 10000,
  66. centimetres: 10000,
  67. feet: 10.763910417,
  68. hectares: 0.0001,
  69. inches: 1550.003100006,
  70. kilometers: 0.000001,
  71. kilometres: 0.000001,
  72. meters: 1,
  73. metres: 1,
  74. miles: 3.86e-7,
  75. millimeters: 1000000,
  76. millimetres: 1000000,
  77. yards: 1.195990046,
  78. };
  79. /**
  80. * Wraps a GeoJSON {@link Geometry} in a GeoJSON {@link Feature}.
  81. *
  82. * @name feature
  83. * @param {Geometry} geometry input geometry
  84. * @param {Object} [properties={}] an Object of key-value pairs to add as properties
  85. * @param {Object} [options={}] Optional Parameters
  86. * @param {Array<number>} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature
  87. * @param {string|number} [options.id] Identifier associated with the Feature
  88. * @returns {Feature} a GeoJSON Feature
  89. * @example
  90. * var geometry = {
  91. * "type": "Point",
  92. * "coordinates": [110, 50]
  93. * };
  94. *
  95. * var feature = turf.feature(geometry);
  96. *
  97. * //=feature
  98. */
  99. export function feature(geom, properties, options) {
  100. if (options === void 0) { options = {}; }
  101. var feat = { type: "Feature" };
  102. if (options.id === 0 || options.id) {
  103. feat.id = options.id;
  104. }
  105. if (options.bbox) {
  106. feat.bbox = options.bbox;
  107. }
  108. feat.properties = properties || {};
  109. feat.geometry = geom;
  110. return feat;
  111. }
  112. /**
  113. * Creates a GeoJSON {@link Geometry} from a Geometry string type & coordinates.
  114. * For GeometryCollection type use `helpers.geometryCollection`
  115. *
  116. * @name geometry
  117. * @param {string} type Geometry Type
  118. * @param {Array<any>} coordinates Coordinates
  119. * @param {Object} [options={}] Optional Parameters
  120. * @returns {Geometry} a GeoJSON Geometry
  121. * @example
  122. * var type = "Point";
  123. * var coordinates = [110, 50];
  124. * var geometry = turf.geometry(type, coordinates);
  125. * // => geometry
  126. */
  127. export function geometry(type, coordinates, _options) {
  128. if (_options === void 0) { _options = {}; }
  129. switch (type) {
  130. case "Point":
  131. return point(coordinates).geometry;
  132. case "LineString":
  133. return lineString(coordinates).geometry;
  134. case "Polygon":
  135. return polygon(coordinates).geometry;
  136. case "MultiPoint":
  137. return multiPoint(coordinates).geometry;
  138. case "MultiLineString":
  139. return multiLineString(coordinates).geometry;
  140. case "MultiPolygon":
  141. return multiPolygon(coordinates).geometry;
  142. default:
  143. throw new Error(type + " is invalid");
  144. }
  145. }
  146. /**
  147. * Creates a {@link Point} {@link Feature} from a Position.
  148. *
  149. * @name point
  150. * @param {Array<number>} coordinates longitude, latitude position (each in decimal degrees)
  151. * @param {Object} [properties={}] an Object of key-value pairs to add as properties
  152. * @param {Object} [options={}] Optional Parameters
  153. * @param {Array<number>} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature
  154. * @param {string|number} [options.id] Identifier associated with the Feature
  155. * @returns {Feature<Point>} a Point feature
  156. * @example
  157. * var point = turf.point([-75.343, 39.984]);
  158. *
  159. * //=point
  160. */
  161. export function point(coordinates, properties, options) {
  162. if (options === void 0) { options = {}; }
  163. if (!coordinates) {
  164. throw new Error("coordinates is required");
  165. }
  166. if (!Array.isArray(coordinates)) {
  167. throw new Error("coordinates must be an Array");
  168. }
  169. if (coordinates.length < 2) {
  170. throw new Error("coordinates must be at least 2 numbers long");
  171. }
  172. if (!isNumber(coordinates[0]) || !isNumber(coordinates[1])) {
  173. throw new Error("coordinates must contain numbers");
  174. }
  175. var geom = {
  176. type: "Point",
  177. coordinates: coordinates,
  178. };
  179. return feature(geom, properties, options);
  180. }
  181. /**
  182. * Creates a {@link Point} {@link FeatureCollection} from an Array of Point coordinates.
  183. *
  184. * @name points
  185. * @param {Array<Array<number>>} coordinates an array of Points
  186. * @param {Object} [properties={}] Translate these properties to each Feature
  187. * @param {Object} [options={}] Optional Parameters
  188. * @param {Array<number>} [options.bbox] Bounding Box Array [west, south, east, north]
  189. * associated with the FeatureCollection
  190. * @param {string|number} [options.id] Identifier associated with the FeatureCollection
  191. * @returns {FeatureCollection<Point>} Point Feature
  192. * @example
  193. * var points = turf.points([
  194. * [-75, 39],
  195. * [-80, 45],
  196. * [-78, 50]
  197. * ]);
  198. *
  199. * //=points
  200. */
  201. export function points(coordinates, properties, options) {
  202. if (options === void 0) { options = {}; }
  203. return featureCollection(coordinates.map(function (coords) {
  204. return point(coords, properties);
  205. }), options);
  206. }
  207. /**
  208. * Creates a {@link Polygon} {@link Feature} from an Array of LinearRings.
  209. *
  210. * @name polygon
  211. * @param {Array<Array<Array<number>>>} coordinates an array of LinearRings
  212. * @param {Object} [properties={}] an Object of key-value pairs to add as properties
  213. * @param {Object} [options={}] Optional Parameters
  214. * @param {Array<number>} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature
  215. * @param {string|number} [options.id] Identifier associated with the Feature
  216. * @returns {Feature<Polygon>} Polygon Feature
  217. * @example
  218. * var polygon = turf.polygon([[[-5, 52], [-4, 56], [-2, 51], [-7, 54], [-5, 52]]], { name: 'poly1' });
  219. *
  220. * //=polygon
  221. */
  222. export function polygon(coordinates, properties, options) {
  223. if (options === void 0) { options = {}; }
  224. for (var _i = 0, coordinates_1 = coordinates; _i < coordinates_1.length; _i++) {
  225. var ring = coordinates_1[_i];
  226. if (ring.length < 4) {
  227. throw new Error("Each LinearRing of a Polygon must have 4 or more Positions.");
  228. }
  229. for (var j = 0; j < ring[ring.length - 1].length; j++) {
  230. // Check if first point of Polygon contains two numbers
  231. if (ring[ring.length - 1][j] !== ring[0][j]) {
  232. throw new Error("First and last Position are not equivalent.");
  233. }
  234. }
  235. }
  236. var geom = {
  237. type: "Polygon",
  238. coordinates: coordinates,
  239. };
  240. return feature(geom, properties, options);
  241. }
  242. /**
  243. * Creates a {@link Polygon} {@link FeatureCollection} from an Array of Polygon coordinates.
  244. *
  245. * @name polygons
  246. * @param {Array<Array<Array<Array<number>>>>} coordinates an array of Polygon coordinates
  247. * @param {Object} [properties={}] an Object of key-value pairs to add as properties
  248. * @param {Object} [options={}] Optional Parameters
  249. * @param {Array<number>} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature
  250. * @param {string|number} [options.id] Identifier associated with the FeatureCollection
  251. * @returns {FeatureCollection<Polygon>} Polygon FeatureCollection
  252. * @example
  253. * var polygons = turf.polygons([
  254. * [[[-5, 52], [-4, 56], [-2, 51], [-7, 54], [-5, 52]]],
  255. * [[[-15, 42], [-14, 46], [-12, 41], [-17, 44], [-15, 42]]],
  256. * ]);
  257. *
  258. * //=polygons
  259. */
  260. export function polygons(coordinates, properties, options) {
  261. if (options === void 0) { options = {}; }
  262. return featureCollection(coordinates.map(function (coords) {
  263. return polygon(coords, properties);
  264. }), options);
  265. }
  266. /**
  267. * Creates a {@link LineString} {@link Feature} from an Array of Positions.
  268. *
  269. * @name lineString
  270. * @param {Array<Array<number>>} coordinates an array of Positions
  271. * @param {Object} [properties={}] an Object of key-value pairs to add as properties
  272. * @param {Object} [options={}] Optional Parameters
  273. * @param {Array<number>} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature
  274. * @param {string|number} [options.id] Identifier associated with the Feature
  275. * @returns {Feature<LineString>} LineString Feature
  276. * @example
  277. * var linestring1 = turf.lineString([[-24, 63], [-23, 60], [-25, 65], [-20, 69]], {name: 'line 1'});
  278. * var linestring2 = turf.lineString([[-14, 43], [-13, 40], [-15, 45], [-10, 49]], {name: 'line 2'});
  279. *
  280. * //=linestring1
  281. * //=linestring2
  282. */
  283. export function lineString(coordinates, properties, options) {
  284. if (options === void 0) { options = {}; }
  285. if (coordinates.length < 2) {
  286. throw new Error("coordinates must be an array of two or more positions");
  287. }
  288. var geom = {
  289. type: "LineString",
  290. coordinates: coordinates,
  291. };
  292. return feature(geom, properties, options);
  293. }
  294. /**
  295. * Creates a {@link LineString} {@link FeatureCollection} from an Array of LineString coordinates.
  296. *
  297. * @name lineStrings
  298. * @param {Array<Array<Array<number>>>} coordinates an array of LinearRings
  299. * @param {Object} [properties={}] an Object of key-value pairs to add as properties
  300. * @param {Object} [options={}] Optional Parameters
  301. * @param {Array<number>} [options.bbox] Bounding Box Array [west, south, east, north]
  302. * associated with the FeatureCollection
  303. * @param {string|number} [options.id] Identifier associated with the FeatureCollection
  304. * @returns {FeatureCollection<LineString>} LineString FeatureCollection
  305. * @example
  306. * var linestrings = turf.lineStrings([
  307. * [[-24, 63], [-23, 60], [-25, 65], [-20, 69]],
  308. * [[-14, 43], [-13, 40], [-15, 45], [-10, 49]]
  309. * ]);
  310. *
  311. * //=linestrings
  312. */
  313. export function lineStrings(coordinates, properties, options) {
  314. if (options === void 0) { options = {}; }
  315. return featureCollection(coordinates.map(function (coords) {
  316. return lineString(coords, properties);
  317. }), options);
  318. }
  319. /**
  320. * Takes one or more {@link Feature|Features} and creates a {@link FeatureCollection}.
  321. *
  322. * @name featureCollection
  323. * @param {Feature[]} features input features
  324. * @param {Object} [options={}] Optional Parameters
  325. * @param {Array<number>} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature
  326. * @param {string|number} [options.id] Identifier associated with the Feature
  327. * @returns {FeatureCollection} FeatureCollection of Features
  328. * @example
  329. * var locationA = turf.point([-75.343, 39.984], {name: 'Location A'});
  330. * var locationB = turf.point([-75.833, 39.284], {name: 'Location B'});
  331. * var locationC = turf.point([-75.534, 39.123], {name: 'Location C'});
  332. *
  333. * var collection = turf.featureCollection([
  334. * locationA,
  335. * locationB,
  336. * locationC
  337. * ]);
  338. *
  339. * //=collection
  340. */
  341. export function featureCollection(features, options) {
  342. if (options === void 0) { options = {}; }
  343. var fc = { type: "FeatureCollection" };
  344. if (options.id) {
  345. fc.id = options.id;
  346. }
  347. if (options.bbox) {
  348. fc.bbox = options.bbox;
  349. }
  350. fc.features = features;
  351. return fc;
  352. }
  353. /**
  354. * Creates a {@link Feature<MultiLineString>} based on a
  355. * coordinate array. Properties can be added optionally.
  356. *
  357. * @name multiLineString
  358. * @param {Array<Array<Array<number>>>} coordinates an array of LineStrings
  359. * @param {Object} [properties={}] an Object of key-value pairs to add as properties
  360. * @param {Object} [options={}] Optional Parameters
  361. * @param {Array<number>} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature
  362. * @param {string|number} [options.id] Identifier associated with the Feature
  363. * @returns {Feature<MultiLineString>} a MultiLineString feature
  364. * @throws {Error} if no coordinates are passed
  365. * @example
  366. * var multiLine = turf.multiLineString([[[0,0],[10,10]]]);
  367. *
  368. * //=multiLine
  369. */
  370. export function multiLineString(coordinates, properties, options) {
  371. if (options === void 0) { options = {}; }
  372. var geom = {
  373. type: "MultiLineString",
  374. coordinates: coordinates,
  375. };
  376. return feature(geom, properties, options);
  377. }
  378. /**
  379. * Creates a {@link Feature<MultiPoint>} based on a
  380. * coordinate array. Properties can be added optionally.
  381. *
  382. * @name multiPoint
  383. * @param {Array<Array<number>>} coordinates an array of Positions
  384. * @param {Object} [properties={}] an Object of key-value pairs to add as properties
  385. * @param {Object} [options={}] Optional Parameters
  386. * @param {Array<number>} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature
  387. * @param {string|number} [options.id] Identifier associated with the Feature
  388. * @returns {Feature<MultiPoint>} a MultiPoint feature
  389. * @throws {Error} if no coordinates are passed
  390. * @example
  391. * var multiPt = turf.multiPoint([[0,0],[10,10]]);
  392. *
  393. * //=multiPt
  394. */
  395. export function multiPoint(coordinates, properties, options) {
  396. if (options === void 0) { options = {}; }
  397. var geom = {
  398. type: "MultiPoint",
  399. coordinates: coordinates,
  400. };
  401. return feature(geom, properties, options);
  402. }
  403. /**
  404. * Creates a {@link Feature<MultiPolygon>} based on a
  405. * coordinate array. Properties can be added optionally.
  406. *
  407. * @name multiPolygon
  408. * @param {Array<Array<Array<Array<number>>>>} coordinates an array of Polygons
  409. * @param {Object} [properties={}] an Object of key-value pairs to add as properties
  410. * @param {Object} [options={}] Optional Parameters
  411. * @param {Array<number>} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature
  412. * @param {string|number} [options.id] Identifier associated with the Feature
  413. * @returns {Feature<MultiPolygon>} a multipolygon feature
  414. * @throws {Error} if no coordinates are passed
  415. * @example
  416. * var multiPoly = turf.multiPolygon([[[[0,0],[0,10],[10,10],[10,0],[0,0]]]]);
  417. *
  418. * //=multiPoly
  419. *
  420. */
  421. export function multiPolygon(coordinates, properties, options) {
  422. if (options === void 0) { options = {}; }
  423. var geom = {
  424. type: "MultiPolygon",
  425. coordinates: coordinates,
  426. };
  427. return feature(geom, properties, options);
  428. }
  429. /**
  430. * Creates a {@link Feature<GeometryCollection>} based on a
  431. * coordinate array. Properties can be added optionally.
  432. *
  433. * @name geometryCollection
  434. * @param {Array<Geometry>} geometries an array of GeoJSON Geometries
  435. * @param {Object} [properties={}] an Object of key-value pairs to add as properties
  436. * @param {Object} [options={}] Optional Parameters
  437. * @param {Array<number>} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature
  438. * @param {string|number} [options.id] Identifier associated with the Feature
  439. * @returns {Feature<GeometryCollection>} a GeoJSON GeometryCollection Feature
  440. * @example
  441. * var pt = turf.geometry("Point", [100, 0]);
  442. * var line = turf.geometry("LineString", [[101, 0], [102, 1]]);
  443. * var collection = turf.geometryCollection([pt, line]);
  444. *
  445. * // => collection
  446. */
  447. export function geometryCollection(geometries, properties, options) {
  448. if (options === void 0) { options = {}; }
  449. var geom = {
  450. type: "GeometryCollection",
  451. geometries: geometries,
  452. };
  453. return feature(geom, properties, options);
  454. }
  455. /**
  456. * Round number to precision
  457. *
  458. * @param {number} num Number
  459. * @param {number} [precision=0] Precision
  460. * @returns {number} rounded number
  461. * @example
  462. * turf.round(120.4321)
  463. * //=120
  464. *
  465. * turf.round(120.4321, 2)
  466. * //=120.43
  467. */
  468. export function round(num, precision) {
  469. if (precision === void 0) { precision = 0; }
  470. if (precision && !(precision >= 0)) {
  471. throw new Error("precision must be a positive number");
  472. }
  473. var multiplier = Math.pow(10, precision || 0);
  474. return Math.round(num * multiplier) / multiplier;
  475. }
  476. /**
  477. * Convert a distance measurement (assuming a spherical Earth) from radians to a more friendly unit.
  478. * Valid units: miles, nauticalmiles, inches, yards, meters, metres, kilometers, centimeters, feet
  479. *
  480. * @name radiansToLength
  481. * @param {number} radians in radians across the sphere
  482. * @param {string} [units="kilometers"] can be degrees, radians, miles, inches, yards, metres,
  483. * meters, kilometres, kilometers.
  484. * @returns {number} distance
  485. */
  486. export function radiansToLength(radians, units) {
  487. if (units === void 0) { units = "kilometers"; }
  488. var factor = factors[units];
  489. if (!factor) {
  490. throw new Error(units + " units is invalid");
  491. }
  492. return radians * factor;
  493. }
  494. /**
  495. * Convert a distance measurement (assuming a spherical Earth) from a real-world unit into radians
  496. * Valid units: miles, nauticalmiles, inches, yards, meters, metres, kilometers, centimeters, feet
  497. *
  498. * @name lengthToRadians
  499. * @param {number} distance in real units
  500. * @param {string} [units="kilometers"] can be degrees, radians, miles, inches, yards, metres,
  501. * meters, kilometres, kilometers.
  502. * @returns {number} radians
  503. */
  504. export function lengthToRadians(distance, units) {
  505. if (units === void 0) { units = "kilometers"; }
  506. var factor = factors[units];
  507. if (!factor) {
  508. throw new Error(units + " units is invalid");
  509. }
  510. return distance / factor;
  511. }
  512. /**
  513. * Convert a distance measurement (assuming a spherical Earth) from a real-world unit into degrees
  514. * Valid units: miles, nauticalmiles, inches, yards, meters, metres, centimeters, kilometres, feet
  515. *
  516. * @name lengthToDegrees
  517. * @param {number} distance in real units
  518. * @param {string} [units="kilometers"] can be degrees, radians, miles, inches, yards, metres,
  519. * meters, kilometres, kilometers.
  520. * @returns {number} degrees
  521. */
  522. export function lengthToDegrees(distance, units) {
  523. return radiansToDegrees(lengthToRadians(distance, units));
  524. }
  525. /**
  526. * Converts any bearing angle from the north line direction (positive clockwise)
  527. * and returns an angle between 0-360 degrees (positive clockwise), 0 being the north line
  528. *
  529. * @name bearingToAzimuth
  530. * @param {number} bearing angle, between -180 and +180 degrees
  531. * @returns {number} angle between 0 and 360 degrees
  532. */
  533. export function bearingToAzimuth(bearing) {
  534. var angle = bearing % 360;
  535. if (angle < 0) {
  536. angle += 360;
  537. }
  538. return angle;
  539. }
  540. /**
  541. * Converts an angle in radians to degrees
  542. *
  543. * @name radiansToDegrees
  544. * @param {number} radians angle in radians
  545. * @returns {number} degrees between 0 and 360 degrees
  546. */
  547. export function radiansToDegrees(radians) {
  548. var degrees = radians % (2 * Math.PI);
  549. return (degrees * 180) / Math.PI;
  550. }
  551. /**
  552. * Converts an angle in degrees to radians
  553. *
  554. * @name degreesToRadians
  555. * @param {number} degrees angle between 0 and 360 degrees
  556. * @returns {number} angle in radians
  557. */
  558. export function degreesToRadians(degrees) {
  559. var radians = degrees % 360;
  560. return (radians * Math.PI) / 180;
  561. }
  562. /**
  563. * Converts a length to the requested unit.
  564. * Valid units: miles, nauticalmiles, inches, yards, meters, metres, kilometers, centimeters, feet
  565. *
  566. * @param {number} length to be converted
  567. * @param {Units} [originalUnit="kilometers"] of the length
  568. * @param {Units} [finalUnit="kilometers"] returned unit
  569. * @returns {number} the converted length
  570. */
  571. export function convertLength(length, originalUnit, finalUnit) {
  572. if (originalUnit === void 0) { originalUnit = "kilometers"; }
  573. if (finalUnit === void 0) { finalUnit = "kilometers"; }
  574. if (!(length >= 0)) {
  575. throw new Error("length must be a positive number");
  576. }
  577. return radiansToLength(lengthToRadians(length, originalUnit), finalUnit);
  578. }
  579. /**
  580. * Converts a area to the requested unit.
  581. * Valid units: kilometers, kilometres, meters, metres, centimetres, millimeters, acres, miles, yards, feet, inches, hectares
  582. * @param {number} area to be converted
  583. * @param {Units} [originalUnit="meters"] of the distance
  584. * @param {Units} [finalUnit="kilometers"] returned unit
  585. * @returns {number} the converted area
  586. */
  587. export function convertArea(area, originalUnit, finalUnit) {
  588. if (originalUnit === void 0) { originalUnit = "meters"; }
  589. if (finalUnit === void 0) { finalUnit = "kilometers"; }
  590. if (!(area >= 0)) {
  591. throw new Error("area must be a positive number");
  592. }
  593. var startFactor = areaFactors[originalUnit];
  594. if (!startFactor) {
  595. throw new Error("invalid original units");
  596. }
  597. var finalFactor = areaFactors[finalUnit];
  598. if (!finalFactor) {
  599. throw new Error("invalid final units");
  600. }
  601. return (area / startFactor) * finalFactor;
  602. }
  603. /**
  604. * isNumber
  605. *
  606. * @param {*} num Number to validate
  607. * @returns {boolean} true/false
  608. * @example
  609. * turf.isNumber(123)
  610. * //=true
  611. * turf.isNumber('foo')
  612. * //=false
  613. */
  614. export function isNumber(num) {
  615. return !isNaN(num) && num !== null && !Array.isArray(num);
  616. }
  617. /**
  618. * isObject
  619. *
  620. * @param {*} input variable to validate
  621. * @returns {boolean} true/false
  622. * @example
  623. * turf.isObject({elevation: 10})
  624. * //=true
  625. * turf.isObject('foo')
  626. * //=false
  627. */
  628. export function isObject(input) {
  629. return !!input && input.constructor === Object;
  630. }
  631. /**
  632. * Validate BBox
  633. *
  634. * @private
  635. * @param {Array<number>} bbox BBox to validate
  636. * @returns {void}
  637. * @throws Error if BBox is not valid
  638. * @example
  639. * validateBBox([-180, -40, 110, 50])
  640. * //=OK
  641. * validateBBox([-180, -40])
  642. * //=Error
  643. * validateBBox('Foo')
  644. * //=Error
  645. * validateBBox(5)
  646. * //=Error
  647. * validateBBox(null)
  648. * //=Error
  649. * validateBBox(undefined)
  650. * //=Error
  651. */
  652. export function validateBBox(bbox) {
  653. if (!bbox) {
  654. throw new Error("bbox is required");
  655. }
  656. if (!Array.isArray(bbox)) {
  657. throw new Error("bbox must be an Array");
  658. }
  659. if (bbox.length !== 4 && bbox.length !== 6) {
  660. throw new Error("bbox must be an Array of 4 or 6 numbers");
  661. }
  662. bbox.forEach(function (num) {
  663. if (!isNumber(num)) {
  664. throw new Error("bbox must only contain numbers");
  665. }
  666. });
  667. }
  668. /**
  669. * Validate Id
  670. *
  671. * @private
  672. * @param {string|number} id Id to validate
  673. * @returns {void}
  674. * @throws Error if Id is not valid
  675. * @example
  676. * validateId([-180, -40, 110, 50])
  677. * //=Error
  678. * validateId([-180, -40])
  679. * //=Error
  680. * validateId('Foo')
  681. * //=OK
  682. * validateId(5)
  683. * //=OK
  684. * validateId(null)
  685. * //=Error
  686. * validateId(undefined)
  687. * //=Error
  688. */
  689. export function validateId(id) {
  690. if (!id) {
  691. throw new Error("id is required");
  692. }
  693. if (["string", "number"].indexOf(typeof id) === -1) {
  694. throw new Error("id must be a number or a string");
  695. }
  696. }