Как надежно создать гексагональную сетку на карте мира - PullRequest
4 голосов
/ 22 апреля 2019

Цель

Я пытаюсь создать приложение, в котором вся карта мира разбита на большое количество шестиугольников.Эти шестиугольники, однажды сгенерированные, всегда будут покрывать одну и ту же область на карте.Затем, учитывая определенные географические координаты, шестиугольник будет отображаться на карте, если эти координаты будут находиться в пределах его границ.Эти шестиугольники должны быть очень маленькими, каждая сторона должна быть ок.50 м - это создает основную проблему.

Первая попытка

Моя первая идея состояла в том, чтобы предварительно сгенерировать гексагональную сетку, где каждый гекс будет невидим, и выяснить,координата находится в пределах границ, просто измените стиль шестиугольника.Это работает, если длина стороны шестиугольника действительно велика (сотни километров).В моем случае, однако, приложению не хватит памяти при попытке нарисовать очень маленькие шестиугольники, даже для небольшой части карты.

// Attempting to cover the whole map in small hexagons
turf.hexGrid([-179.99, -89.99, 179.99, 89.99], 0.2);

Первая попытка, но с поворотом

Моя вторая идея состояла в том, чтобы использовать mask параметр hexGrid(), чтобы я все еще генерировалшестигранная сетка с неизменными координатами шестиугольника, но будет пытаться визуализировать шестиугольники в пределах небольшой области карты (например, области, видимой на карте).Это также не представляется возможным, поскольку даже создание такой сетки (и не отображение ее на карте) оказывается слишком затратным.

// Attempting to cover the whole map in small hexagons only within a given area (mask)
turf.hexGrid([-179.99, -89.90, 178.99, 88.90], 30, {
  mask: polygon([[[20, 60], [21, 60], [22, 62], [22, 63], [20, 60]]]),
});

Это, однако, приведет к очень искаженным шестиугольникам, что приводит кя считаю, что попытка создать гекс-сетку для всего мира - это, как правило, плохая идея.

skewed hexagons when spread over large area

Оптимистичные расчеты

Моя последняя попытка состояла в том, чтобы сгенерировать один шестиугольник в верхнем левом углу карты и использовать его координаты, чтобы вычислить, сколько шестиугольников поместится между этим первым шестиугольником и любыми заданными координатами.

Эти вычисления почти работает, но из-за округления или, возможно, ошибки в том, как я вычисляю расстояния (вручную), позиционирование отключается на все большее число по мере удаления координат от первого шестиугольника.

Пример из реальной жизни Ближайший пример того, чего я хочу достичь, - это запущенная игра "Run a Empire".Шестнадцатеричная сетка там, кажется, загружается по требованию, и только вокруг области, в которой она находится. Судя по всему, эта сетка не имеет каких-либо промежутков, которые мешали бы шестиугольникам идеально соединяться.

Какдобавленная точка интереса, рисование шестиугольников на карте мира перекосит их дальше на север.Похоже, этого не происходит в вышеупомянутой игре (скриншот ниже).Означает ли это, что размеры шестиугольников жестко запрограммированы, возможно, они нарисованы на другой проекции карты, в которой перекос не происходит?

Основной вопрос

Учитывая географические координаты, такие как местоположение GPS, как можно надежно создать шестиугольную сетку, чтобы при создании другой шестиугольной сетки на основе другого набора координат эти две сетки перекрывалисьв совершенстве?Я открыт для решения любых инструментов, не обязательно Turf или Mapbox.


Run an Empire game screenshot

1 Ответ

1 голос
/ 02 мая 2019

Я предлагаю сгенерировать векторный слой со всеми шестиугольниками и загружать их динамически, выполняя гео-запрос с использованием базы геоданных. Пересечение точки, где был размещен штифт, вернет шестиугольник под ним, и если вы используете буфер, вы также можете добавить больше шестиугольников вокруг него.

Границы для WGS84: -180,0000, -90,0000, 180,0000, 90,0000 (я знаю, это очевидно) источник: https://spatialreference.org/ref/epsg/wgs-84/ Это означает, что вам нужно начать отсюда, оценить количество шестиугольников, которые вы хотите / хотите создать. Согласно https://planetcalc.com/7721/, радиус очага в метрах составляет 6378137. Предполагая, что вам нужен шестиугольник из 6 равносторонних треугольников, это означает, что для получения шестиугольника со стороной около 50 метров его ширина должна составлять 100 м (при условии, что плоские стороны ориентированы горизонтально).

Теперь мы можем сказать, что нам нужно около 63781 шестиугольников на экваторе, давайте упростим до 63800, 360/63800 = 0,00564 ... поэтому я предлагаю начать со смещения точек на экваторе 0,0055 градусов.

Следует подчеркнуть, что WGS84 является геоидом, а не сферическим (как наша планета), поэтому окончательное представление может быть немного растянуто.

ОБНОВЛЕНИЕ: Для автоматического создания сетки, похоже, что вы также можете использовать Quantum GIS благодаря Grass

https://github.com/rldhont/Quantum-GIS/blob/master/python/plugins/processing/algs/grass7/description/v.mkgrid.txt https://grass.osgeo.org/grass76/manuals/v.mkgrid.html

...