From 14cdab884570133d2fbdba30ebc689f109419288 Mon Sep 17 00:00:00 2001 From: Yarchik Date: Thu, 2 Jul 2026 05:49:34 +0100 Subject: [PATCH] Fix getClusters dropping points exactly on the query bbox edge Points are stored as Float32 (fround), but the getClusters range query was built from full-precision Float64 bounds. fround can round a stored coordinate slightly outside its exact value, so a point whose lng/lat equals a bbox edge fell just outside the inclusive range and was dropped. Project the query bounds through the same fround so the edge comparison is exact. Fixes #234. --- index.js | 2 +- test/test.js | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/index.js b/index.js index 4dce8d36..0d339b28 100644 --- a/index.js +++ b/index.js @@ -102,7 +102,7 @@ export default class Supercluster { } const tree = this.trees[this._limitZoom(zoom)]; - const ids = tree.range(lngX(minLng), latY(maxLat), lngX(maxLng), latY(minLat)); + const ids = tree.range(fround(lngX(minLng)), fround(latY(maxLat)), fround(lngX(maxLng)), fround(latY(minLat))); const data = tree.data; const clusters = []; for (const id of ids) { diff --git a/test/test.js b/test/test.js index 5fb05107..4f50b204 100644 --- a/test/test.js +++ b/test/test.js @@ -179,3 +179,15 @@ test('does not throw on zero items', () => { assert.deepEqual(index.getClusters([-180, -85, 180, 85], 0), []); }); }); + +test('returns points that lie exactly on the query bbox edge', () => { + const index = new Supercluster().load([ + {type: 'Feature', properties: {name: 'a'}, geometry: {type: 'Point', coordinates: [-123.211605, 43.972615]}}, + {type: 'Feature', properties: {name: 'b'}, geometry: {type: 'Point', coordinates: [-123.245515, 43.9150233333333]}}, + {type: 'Feature', properties: {name: 'c'}, geometry: {type: 'Point', coordinates: [-123.192528333333, 44.0307166666667]}}, + {type: 'Feature', properties: {name: 'd'}, geometry: {type: 'Point', coordinates: [-123.194573333333, 44.0107]}} + ]); + const bbox = [-123.245515, 43.9150233333333, -123.192528333333, 44.0307166666667]; + const names = index.getClusters(bbox, 16).map(p => p.properties.name).sort(); + assert.deepEqual(names, ['a', 'b', 'c', 'd']); +});