| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110 |
- // index.ts
- import { clone } from "@turf/clone";
- import { distance } from "@turf/distance";
- import { degreesToRadians, lengthToDegrees } from "@turf/helpers";
- // lib/rbush-export.ts
- import lib from "rbush";
- var rbush = lib;
- // index.ts
- function clustersDbscan(points, maxDistance, options = {}) {
- if (options.mutate !== true) points = clone(points);
- const minPoints = options.minPoints || 3;
- const latDistanceInDegrees = lengthToDegrees(maxDistance, options.units);
- var tree = new rbush(points.features.length);
- var visited = points.features.map((_) => false);
- var assigned = points.features.map((_) => false);
- var isnoise = points.features.map((_) => false);
- var clusterIds = points.features.map((_) => -1);
- tree.load(
- points.features.map((point, index) => {
- var [x, y] = point.geometry.coordinates;
- return {
- minX: x,
- minY: y,
- maxX: x,
- maxY: y,
- index
- };
- })
- );
- const regionQuery = (index) => {
- const point = points.features[index];
- const [x, y] = point.geometry.coordinates;
- const minY = Math.max(y - latDistanceInDegrees, -90);
- const maxY = Math.min(y + latDistanceInDegrees, 90);
- const lonDistanceInDegrees = function() {
- if (minY < 0 && maxY > 0) {
- return latDistanceInDegrees;
- }
- if (Math.abs(minY) < Math.abs(maxY)) {
- return latDistanceInDegrees / Math.cos(degreesToRadians(maxY));
- } else {
- return latDistanceInDegrees / Math.cos(degreesToRadians(minY));
- }
- }();
- const minX = Math.max(x - lonDistanceInDegrees, -360);
- const maxX = Math.min(x + lonDistanceInDegrees, 360);
- const bbox = { minX, minY, maxX, maxY };
- return tree.search(bbox).filter(
- (neighbor) => {
- const neighborIndex = neighbor.index;
- const neighborPoint = points.features[neighborIndex];
- const distanceInKm = distance(point, neighborPoint, {
- units: "kilometers"
- });
- return distanceInKm <= maxDistance;
- }
- );
- };
- const expandCluster = (clusteredId, neighbors) => {
- for (var i = 0; i < neighbors.length; i++) {
- var neighbor = neighbors[i];
- const neighborIndex = neighbor.index;
- if (!visited[neighborIndex]) {
- visited[neighborIndex] = true;
- const nextNeighbors = regionQuery(neighborIndex);
- if (nextNeighbors.length >= minPoints) {
- neighbors.push(...nextNeighbors);
- }
- }
- if (!assigned[neighborIndex]) {
- assigned[neighborIndex] = true;
- clusterIds[neighborIndex] = clusteredId;
- }
- }
- };
- var nextClusteredId = 0;
- points.features.forEach((_, index) => {
- if (visited[index]) return;
- const neighbors = regionQuery(index);
- if (neighbors.length >= minPoints) {
- const clusteredId = nextClusteredId;
- nextClusteredId++;
- visited[index] = true;
- expandCluster(clusteredId, neighbors);
- } else {
- isnoise[index] = true;
- }
- });
- points.features.forEach((_, index) => {
- var clusterPoint = points.features[index];
- if (!clusterPoint.properties) {
- clusterPoint.properties = {};
- }
- if (clusterIds[index] >= 0) {
- clusterPoint.properties.dbscan = isnoise[index] ? "edge" : "core";
- clusterPoint.properties.cluster = clusterIds[index];
- } else {
- clusterPoint.properties.dbscan = "noise";
- }
- });
- return points;
- }
- var turf_clusters_dbscan_default = clustersDbscan;
- export {
- clustersDbscan,
- turf_clusters_dbscan_default as default
- };
- //# sourceMappingURL=index.js.map
|