简而言之,问题是:如何使用Google Maps API 以外的其他工具在墨卡托中准确地投影一个环绕的大圆半径?
问题很长:
所以我有一个难题。我运行了一个地图应用程序,它使用 Google Maps API 将巨大的圆圈投影到墨卡托地图上——它试图显示非常大、精确的半径,例如,大约 13,000 公里。但我不想再使用 Google Maps API,因为 Google 的新定价方案太疯狂了。因此,我试图将代码转换为 Leaflet、Mapbox 或任何非 Google 的东西,没有任何东西可以正确处理这些圆圈。
以下是 Google Maps API 如何处理以非洲北部为中心、半径为 13,000 公里的测地圆:
这在直觉上看起来很奇怪,但却是正确的。波浪形图案是由环绕地球的圆圈引起的。
D3.js 可以在正交投影中正确渲染它。所以这是在 D3.js 中使用 d3.geo.circle() 在地球上渲染的同一个圆圈,旋转两次:
这使得 2D-“波浪”模式更有意义,对吧?对。我喜欢它。完全适用于我的科学传播等目的。
但是当我将代码转换为 Leaflet 时,它根本不起作用。为什么?因为 Leaflet 的 circle 类根本就不是一个大圆。相反,它似乎只是一个随着纬度有点扭曲的椭圆,但不是以真正的测地线方式。相同的圆,相同的半径,相同的原点,我们得到:
大错特错,大错特错!除了看起来完全不切实际之外,这是不正确的——澳大利亚不会在这样的圆形半径内。这对我的申请很重要!这是不行的。
好吧,我想,也许诀窍就是尝试实现我自己的大圆圈类。我采用的方法是将圆点作为距原点的距离进行迭代,但是使用这个非常有用的网站上的“目标点给定距离和距起点的方位”计算来计算距离,然后将它们投影为多边形传单。这是我得到的结果:
这看起来很糟糕,但实际上更接近准确!我们得到了波浪效应,这是正确的。像我一样,你可能会问,“这里到底发生了什么?” 所以我做了一个版本,让我可以突出每个迭代点:
你可以很清楚地看到它正确地渲染了圆,但是多边形错误地加入了它。它应该做的(人们可能会天真地认为)是将波浪形包裹在墨卡托地图投影的多个实例周围,而不是天真地将它们连接在顶部,而是将它们连接成球形。就像这个粗糙的 Photoshop 渲染一样:
然后多边形将以某种方式“关闭”,表明多边形上方的所有内容也都包含在其中。
不过,我不知道如何在 Leaflet 中实现这样的东西。或其他任何事情。考虑到缩放状态,也许我必须自己处理原始 SVG?或者其他的东西?在我进入那些危险的杂草之前,我想我会征求任何建议/想法/等。也许有一些更明显的方法。
哦,我尝试了另一件事:使用相同的 d3.geo.circle 构造函数,该构造函数在墨卡托/传单投影的正交投影中效果很好。它产生的结果或多或少与我的“天真”传单大圆实现相同:
我猜这是有希望的。但是,如果您移动原点的经度,D3.js 版本会以一种更奇怪的方式包装(D3.js 为红色,我的 Leaflet 类为青绿色):
如果 D3.js 中有某种方法可以改变它的工作方式,我不会感到惊讶,但我还没有完全进入 D3.js 的兔子洞。我希望 D3.js 能让这个“更容易”(因为它是比 Leaflet 更完整的制图工具),所以我会继续研究这个。
我还没有尝试在 Mapbox-gl 中执行此操作(我想这是“尝试”列表中的下一个)。
反正。谢谢阅读。重申这个问题:如何使用Google Maps API 以外的其他工具在墨卡托中准确地投影一个环绕的大圆半径?