index.js 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  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 clone_1 = __importDefault(require("@turf/clone"));
  7. var distance_1 = __importDefault(require("@turf/distance"));
  8. var meta_1 = require("@turf/meta");
  9. var helpers_1 = require("@turf/helpers");
  10. var density_clustering_1 = __importDefault(require("density-clustering"));
  11. /**
  12. * Takes a set of {@link Point|points} and partition them into clusters according to {@link DBSCAN's|https://en.wikipedia.org/wiki/DBSCAN} data clustering algorithm.
  13. *
  14. * @name clustersDbscan
  15. * @param {FeatureCollection<Point>} points to be clustered
  16. * @param {number} maxDistance Maximum Distance between any point of the cluster to generate the clusters (kilometers only)
  17. * @param {Object} [options={}] Optional parameters
  18. * @param {string} [options.units="kilometers"] in which `maxDistance` is expressed, can be degrees, radians, miles, or kilometers
  19. * @param {boolean} [options.mutate=false] Allows GeoJSON input to be mutated
  20. * @param {number} [options.minPoints=3] Minimum number of points to generate a single cluster,
  21. * points which do not meet this requirement will be classified as an 'edge' or 'noise'.
  22. * @returns {FeatureCollection<Point>} Clustered Points with an additional two properties associated to each Feature:
  23. * - {number} cluster - the associated clusterId
  24. * - {string} dbscan - type of point it has been classified as ('core'|'edge'|'noise')
  25. * @example
  26. * // create random points with random z-values in their properties
  27. * var points = turf.randomPoint(100, {bbox: [0, 30, 20, 50]});
  28. * var maxDistance = 100;
  29. * var clustered = turf.clustersDbscan(points, maxDistance);
  30. *
  31. * //addToMap
  32. * var addToMap = [clustered];
  33. */
  34. function clustersDbscan(points, maxDistance, options) {
  35. // Input validation being handled by Typescript
  36. // collectionOf(points, 'Point', 'points must consist of a FeatureCollection of only Points');
  37. // if (maxDistance === null || maxDistance === undefined) throw new Error('maxDistance is required');
  38. // if (!(Math.sign(maxDistance) > 0)) throw new Error('maxDistance is invalid');
  39. // if (!(minPoints === undefined || minPoints === null || Math.sign(minPoints) > 0)) throw new Error('options.minPoints is invalid');
  40. if (options === void 0) { options = {}; }
  41. // Clone points to prevent any mutations
  42. if (options.mutate !== true)
  43. points = clone_1.default(points);
  44. // Defaults
  45. options.minPoints = options.minPoints || 3;
  46. // create clustered ids
  47. var dbscan = new density_clustering_1.default.DBSCAN();
  48. var clusteredIds = dbscan.run(meta_1.coordAll(points), helpers_1.convertLength(maxDistance, options.units), options.minPoints, distance_1.default);
  49. // Tag points to Clusters ID
  50. var clusterId = -1;
  51. clusteredIds.forEach(function (clusterIds) {
  52. clusterId++;
  53. // assign cluster ids to input points
  54. clusterIds.forEach(function (idx) {
  55. var clusterPoint = points.features[idx];
  56. if (!clusterPoint.properties)
  57. clusterPoint.properties = {};
  58. clusterPoint.properties.cluster = clusterId;
  59. clusterPoint.properties.dbscan = "core";
  60. });
  61. });
  62. // handle noise points, if any
  63. // edges points are tagged by DBSCAN as both 'noise' and 'cluster' as they can "reach" less than 'minPoints' number of points
  64. dbscan.noise.forEach(function (noiseId) {
  65. var noisePoint = points.features[noiseId];
  66. if (!noisePoint.properties)
  67. noisePoint.properties = {};
  68. if (noisePoint.properties.cluster)
  69. noisePoint.properties.dbscan = "edge";
  70. else
  71. noisePoint.properties.dbscan = "noise";
  72. });
  73. return points;
  74. }
  75. exports.default = clustersDbscan;