I am plotting thousands of data points on a map, and at any point I want to fetch the data points falling in a particular map bounding box. For example, attached below is the complete view of the available data points,
If I zoom in a bit, i will have fewer points and I want to fetch the data associated with those points.
How I am approaching this is fetching the bounding box of the map, and then checking the coordinates of each point if they belong in that bounding box. Sample code is below,
JavaScript
x
15
15
1
const data = [
2
{lat: 33.93911, lng: 67.709953},
3
{lat: -11.2027, lng: 17.8739},
4
{lat: -33.8688, lng: 151.2093},
5
{lat: -42.8821, lng: 147.3272},
6
{lat: 26.0275, lng: 50.55}
7
]
8
const boundingBox = window.map.getMapBounds();
9
const result = [];
10
for(let i = 0; i < data.length; i++) {
11
if(/* point lies within bounding box */) {
12
result.push(point);
13
}
14
}
15
How can I optimise it or is there a better solution? Thanks a lot.
Advertisement
Answer
You can try using bbox-polygon
and boolean-intersects
from turf
:
- Use
onViewStateChange
from deck instance within adebounce
function so it won’t be executed too often - Create a polygon from the deck
viewState
using@turf/bbox-polygon
- Pass it to
@turf/boolean-intersects
with the whole features usingfilter
JS method
JavaScript
1
32
32
1
import { WebMercatorViewport } from '@deck.gl/core';
2
import bboxPolygon from '@turf/bbox-polygon';
3
import intersects from '@turf/boolean-intersects';
4
5
function debounce(fn, ms) {
6
let timer;
7
return (args) => {
8
clearTimeout(timer);
9
timer = setTimeout(() => {
10
timer = null;
11
fn.apply(this, args);
12
}, ms);
13
};
14
}
15
16
function getViewport(viewState) {
17
const bounds = new WebMercatorViewport(viewState).getBounds()
18
return bboxPolygon(bounds)
19
}
20
21
function getViewportFeatures({ viewState }) {
22
const viewport = getViewport(viewState)
23
const viewportFeatures = features.filter((f) => intersects(f, viewport))
24
console.log(viewportFeatures) // Your target
25
}
26
27
<DeckGL
28
29
onViewStateChange={debounce(getViewportFeatures, 500)}
30
/>
31
32
Advanced: if your data is really big, you can use Web Workers