Как я могу получить шестиугольники H3 в окне просмотра response-map-gl / deck.gl? - PullRequest
1 голос
/ 18 июня 2019

Я хочу запросить данные, основанные на шестиугольниках H3, которые видны в окне просмотра (и новых данных при каждом изменении окна просмотра). Есть ли в любом случае, чтобы достичь этого с помощью response-map-gl и deck.gl?

1 Ответ

0 голосов
/ 19 июня 2019

Чтобы получить шестиугольники внутри окна просмотра, вам нужно получить ограничивающий прямоугольник текущего окна просмотра.Если у вас текущий видовой экран как {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);
}
...