diff --git a/README.md b/README.md index a4bc42a..e2320b9 100644 --- a/README.md +++ b/README.md @@ -65,6 +65,10 @@ and `offset` is the amount of points to skip (for pagination). Returns the zoom on which the cluster expands into several children (useful for "click to zoom" feature) given the cluster's `cluster_id`. +#### `getPointUnclusterZoom(point)` + +Returns the zoom on which a point appears unclustered. The point must be provided as array with `[Lng, Lat]`. + ## Options | Option | Default | Description | diff --git a/index.js b/index.js index c564396..b86c58a 100644 --- a/index.js +++ b/index.js @@ -191,6 +191,28 @@ export default class Supercluster { return expansionZoom; } + getPointUnclusterZoom(point) { + const [lng, lat] = point; + const pointX = fround(lngX(lng)); + const pointY = fround(latY(lat)); + + let expansionZoom = this.options.minZoom; + while (expansionZoom < this.options.maxZoom) { + const tree = this.trees[expansionZoom]; + + const pointIdxs = tree.within(pointX, pointY, 0); + + const unclustered = pointIdxs.some( + idx => tree.data[idx].parentId !== -1 + ); + if (unclustered) return expansionZoom; + + expansionZoom++; + } + + return expansionZoom; + } + _appendLeaves(result, clusterId, limit, offset, skipped) { const children = this.getChildren(clusterId); diff --git a/test/test.js b/test/test.js index 74671ff..5952549 100644 --- a/test/test.js +++ b/test/test.js @@ -172,3 +172,17 @@ test('makes sure unclustered point coords are not rounded', () => { assert.deepEqual(index.getTile(20, 1028744, 656754).features[0].geometry[0], [421, 281]); }); + +test('returns point uncluster zoom level', () => { + const points = [ + {type: 'Feature', geometry: {type: 'Point', coordinates: [173, 53]}}, + {type: 'Feature', geometry: {type: 'Point', coordinates: [174, 54]}} + ]; + const index = new Supercluster({maxZoom: 19}).load(points); + const cluster = index.getClusters([172, 52, 175, 55], 1)[0]; + + const clusterExpansionZoom = index.getClusterExpansionZoom(cluster.id); + const pointUnclusterZoom = index.getPointUnclusterZoom(points[0].geometry.coordinates); + + assert.deepEqual(clusterExpansionZoom, pointUnclusterZoom); +});