Вопрос, вкратце: Как точно спроецировать большой радиус окружности в Mercator, используя что-то другое , чем Google Maps API?
Вопрос, в длинне:
Итак, у меня есть загадка. Я запускаю картографическое приложение, которое использует API Карт Google для проецирования огромных кругов на карту Меркатора - это попытка показать очень большие, точные радиусы, скажем, порядка 13 000 км. Но я больше не хочу использовать API Карт Google, потому что новая схема ценообразования Google безумна. Поэтому я пытаюсь преобразовать код в Leaflet, или Mapbox, или что-нибудь, не принадлежащее Google , и ничто не может правильно обработать эти круги.
Вот как Google Maps API обрабатывает геодезический круг с радиусом 13 000 км, центрированный к северу от Африки:
![Google Maps API great circle](https://i.stack.imgur.com/H4xNT.png)
Это выглядит интуитивно странно , но правильно . Волнообразный рисунок вызван окружением Земли.
D3.js может правильно отобразить это в ортографической проекции . Итак, вот тот же круг, созданный в D3.js с d3.geo.circle () на глобусе, в двух поворотах:
![D3.js great circle on orthographic v1](https://i.stack.imgur.com/oZqWM.png)
![D3.js great circle on orthographic v2](https://i.stack.imgur.com/9Rwrg.png)
Что делает 2D- "волнистый" рисунок более понятным, верно? Правильно. Я люблю это. Полностью работает для моих целей научного общения и все такое.
Но когда я конвертирую свой код в Leaflet, он совсем не работает. Зачем? Потому что класс кружка Листовки совсем не велик. Вместо этого кажется, что это просто эллипс, который немного искажен широтой, но не по-геодезически. Тот же круг, тот же радиус, та же точка начала, и мы получаем это:
![Leaflet's attempt at a 13000 km circle](https://i.stack.imgur.com/2V3mR.png)
Так неправильно, так неправильно! Помимо того, что выглядеть совершенно нереально, это просто неправильно - Австралия будет не находиться внутри такого радиуса круга. Это важно для моего заявления! Это не может сделать.
Ладно, подумал я, может быть, хитрость заключается в том, чтобы просто попытаться реализовать свой собственный класс большого круга. Подход, который я выбрал, состоял в том, чтобы выполнить итерации по точкам окружности как расстояниям от исходной точки, но рассчитать расстояния, используя расчеты «Заданное расстояние с учетом расстояния и начальная точка» из этого очень полезного веб-сайта , а затем спроектировать их как многоугольник в Leaflet. Вот что я получаю в результате:
Это выглядит плохо, но на самом деле гораздо ближе к точности! Мы получаем волновой эффект, и это правильно. Как и я, вы можете спросить: «Что здесь на самом деле происходит?» Поэтому я сделал версию, которая позволила мне выделить каждую итерацию:
![Attempted Great Circle implementation in Leaflet with points](https://i.stack.imgur.com/sIpo3.png)
И вы можете ясно видеть, что круг правильно отрисован, но полигон неправильно соединяется с ним. То, что должно делать (можно наивно подумать), оборачивает эту волновую фигуру вокруг множества экземпляров проекции карты Меркатора, не наивно соединяя их сверху, а соединяя их сферически. Как этот грубый перевод Photoshop:
![Photoshopped version of Leaflet](https://i.stack.imgur.com/pSMmg.png)
И тогда многоугольник «закроется» таким образом, чтобы это указывало на то, что все, что находится над многоугольником, также было заключено в нем.
Я понятия не имею, как реализовать что-то подобное в Leaflet. Или что-нибудь еще по этому вопросу. Может быть, мне нужно как-то обработать необработанный SVG самостоятельно, учитывая состояние масштабирования? Или что-то? Прежде чем я уйду в эти коварные сорняки, я подумал, что буду просить любые предложения / идеи / и т.д. Может быть, есть более очевидный подход.
О, и я попробовал еще одну вещь: использовать тот же конструктор d3.geo.circle, который так хорошо работал в ортографической проекции для проекции Меркатора / Листовки. Он дает более или менее те же результаты, что и моя «наивная» реализация Leaflet Great Circle:
![D3.js Great Circle in Mercator](https://i.stack.imgur.com/hBS1Y.png)
Что перспективно, я думаю.Однако, если вы переместите долготу исходной точки, версия D3.js будет выглядеть более странно (D3.js - красный, мой класс Leaflet - бирюзовый):
![D3.js vs Leaflet at different Longitude](https://i.stack.imgur.com/vCbcK.png)
Я бы не удивился, если бы в D3.js был какой-то способ изменить, как это работает, но я не дошел до кроличьей норы D3.js.Я надеялся, что D3.js сделает это «проще» (поскольку он является более полноформатным картографическим инструментом, чем Leaflet), поэтому я буду продолжать в этом разбираться.
Я еще не пытался сделать это в Mapbox-gl (я думаю, это будет следующим в списке "попыток").
В любом случае.Спасибо за прочтение.Повторим вопрос: Как точно спроецировать большой радиус окружности в Меркаторе, используя что-то другое , чем Google Maps API?