Чтобы получить шестиугольники внутри окна просмотра, вам нужно получить ограничивающий прямоугольник текущего окна просмотра.Если у вас текущий видовой экран как {latitude, longitude, zoom, width, height}
(который, вероятно, у вас в состоянии компонента, если вы используете react-map-gl
), вы можете получить видовой экран с помощью viewport-mercator-project
:
import WebMercatorViewport from 'viewport-mercator-project';
function bboxFromViewport(viewport) {
const {width, height} = viewport;
const projection = new WebMercatorViewport(viewport);
const [west, north] = projection.unproject([0, 0]);
const [east, south] = projection.unproject([width, height]);
return {north, south, east, west};
}
Тогда выможно использовать ограничительную рамку с h3.polyfill
, чтобы получить список содержащихся шестиугольников с заданным разрешением:
const nw = [north, west];
const ne = [north, east];
const sw = [south, west];
const se = [south, east];
const hexes = h3.polyfill([nw, ne, se, sw], resolution);
В зависимости от вашего варианта использования, вы можете расширить ограничительную рамку перед вызовом polyfill
,получить дополнительные данные вне непосредственного окна просмотра.
Вы также, вероятно, хотите каким-то образом связать это с экстентом области просмотра, иначе вы можете получить миллионы шестиугольников при уменьшении масштаба.Один дешевый хак, который я использовал для этого, состоит в том, чтобы сделать очень приблизительную оценку количества получаемых шестиугольников и избегать вызова polyfill
, если он слишком высок:
// Inexact, but it doesn't matter for our purposes
const KM_PER_DEGREE_LAT = 111.2;
function estimateHexagonsInBBox(bbox, width, height, res) {
// This is an extremely rough estimate, but we're just trying
// to get a reasonable order of magnitude
const aspect = width / height;
const latKm = (bbox.north - bbox.south) * KM_PER_DEGREE_LAT;
const lonKm = latKm * aspect;
return (latKm * lonKm) / h3.hexArea(res, h3.UNITS.km2);
}