index.js 3.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. "use strict";
  2. var __importDefault = (this && this.__importDefault) || function (mod) {
  3. return (mod && mod.__esModule) ? mod : { "default": mod };
  4. };
  5. Object.defineProperty(exports, "__esModule", { value: true });
  6. var distance_1 = __importDefault(require("@turf/distance"));
  7. var helpers_1 = require("@turf/helpers");
  8. var meta_1 = require("@turf/meta");
  9. var tin_1 = __importDefault(require("@turf/tin"));
  10. var turf_dissolve_1 = __importDefault(require("./lib/turf-dissolve"));
  11. /**
  12. * Takes a set of {@link Point|points} and returns a concave hull Polygon or MultiPolygon.
  13. * Internally, this uses [turf-tin](https://github.com/Turfjs/turf-tin) to generate geometries.
  14. *
  15. * @name concave
  16. * @param {FeatureCollection<Point>} points input points
  17. * @param {Object} [options={}] Optional parameters
  18. * @param {number} [options.maxEdge=Infinity] the length (in 'units') of an edge necessary for part of the
  19. * hull to become concave.
  20. * @param {string} [options.units='kilometers'] can be degrees, radians, miles, or kilometers
  21. * @returns {Feature<(Polygon|MultiPolygon)>|null} a concave hull (null value is returned if unable to compute hull)
  22. * @example
  23. * var points = turf.featureCollection([
  24. * turf.point([-63.601226, 44.642643]),
  25. * turf.point([-63.591442, 44.651436]),
  26. * turf.point([-63.580799, 44.648749]),
  27. * turf.point([-63.573589, 44.641788]),
  28. * turf.point([-63.587665, 44.64533]),
  29. * turf.point([-63.595218, 44.64765])
  30. * ]);
  31. * var options = {units: 'miles', maxEdge: 1};
  32. *
  33. * var hull = turf.concave(points, options);
  34. *
  35. * //addToMap
  36. * var addToMap = [points, hull]
  37. */
  38. function concave(points, options) {
  39. if (options === void 0) { options = {}; }
  40. var maxEdge = options.maxEdge || Infinity;
  41. var cleaned = removeDuplicates(points);
  42. var tinPolys = tin_1.default(cleaned);
  43. // calculate length of all edges and area of all triangles
  44. // and remove triangles that fail the max length test
  45. tinPolys.features = tinPolys.features.filter(function (triangle) {
  46. var pt1 = triangle.geometry.coordinates[0][0];
  47. var pt2 = triangle.geometry.coordinates[0][1];
  48. var pt3 = triangle.geometry.coordinates[0][2];
  49. var dist1 = distance_1.default(pt1, pt2, options);
  50. var dist2 = distance_1.default(pt2, pt3, options);
  51. var dist3 = distance_1.default(pt1, pt3, options);
  52. return dist1 <= maxEdge && dist2 <= maxEdge && dist3 <= maxEdge;
  53. });
  54. if (tinPolys.features.length < 1) {
  55. return null;
  56. }
  57. // merge the adjacent triangles
  58. var dissolved = turf_dissolve_1.default(tinPolys);
  59. // geojson-dissolve always returns a MultiPolygon
  60. if (dissolved.coordinates.length === 1) {
  61. dissolved.coordinates = dissolved.coordinates[0];
  62. dissolved.type = "Polygon";
  63. }
  64. return helpers_1.feature(dissolved);
  65. }
  66. /**
  67. * Removes duplicated points in a collection returning a new collection
  68. *
  69. * @private
  70. * @param {FeatureCollection<Point>} points to be cleaned
  71. * @returns {FeatureCollection<Point>} cleaned set of points
  72. */
  73. function removeDuplicates(points) {
  74. var cleaned = [];
  75. var existing = {};
  76. meta_1.featureEach(points, function (pt) {
  77. if (!pt.geometry) {
  78. return;
  79. }
  80. var key = pt.geometry.coordinates.join("-");
  81. if (!Object.prototype.hasOwnProperty.call(existing, key)) {
  82. cleaned.push(pt);
  83. existing[key] = true;
  84. }
  85. });
  86. return helpers_1.featureCollection(cleaned);
  87. }
  88. exports.default = concave;