如何在 react-map-gl/deck.gl 视口上获得 H3 六边形?

How can I get the H3 hexagons on a react-map-gl/deck.gl viewport?

我想查询基于视口上可见的 H3 六边形的数据(以及每个视口更改的新数据)。有没有办法用 react-map-gl 和 deck.gl?

来实现这个

要获取视口内的六边形,您需要获取当前视口的边界框。如果当前视口为 {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);
}