半径以英里为单位的 D3 Topojson 圆

Ara*_*ida 1 javascript d3.js topojson

(假设现有投影/topojson)

我想要做的是在半径 (r) 以英里为单位的点 ([long,lat]) 处创建一个圆。我知道有一个 d3.geo 函数,但经过一些考虑,我认为它不会与我的特定应用程序非常兼容。

所以现在我正在寻找使用原生 svgcircle解决方案,其中 cx 和 cy 是纬度和经度,而 r 是以英里为单位的半径。我知道 cx 和 cy,但我不知道如何确保 r 是 15 英里。所以主要的是如何确保在像素空间中绘制半径时以英里为单位进行缩放。必须有某种方式使用该projection函数为半径设置适当的比例。但我没有在实践中看到这一点。

另外我应该指出,我的投影是动态的,取决于投影(包括比例)可以改变的用户事件。所以我不确定这是否会影响在现有投影的背景下如何缩放圆圈,但我想我会公开这一点,以确保安全。

alt*_*lus 5

为什么不使用内置的圆生成器d3.geoCircle()

返回一个新的“多边形”类型的 GeoJSON 几何对象,它近似于球体表面上的一个圆,具有当前的中心半径精度。任何参数都传递给访问器。

剩下的唯一任务是计算圆的半径(以度为单位)。因为地球不是一个完美的球体,这本身就变得非常具有挑战性。但是对于许多应用程序,近似值就足够了。以刚刚平均半径3,958英里考虑在内,计算可以写成:

var EARTH_RADIUS = 3959;                         // mean radius in miles
var radiusMi     = 5;                            // radius to be drawn in miles
var radiusDeg    = radiusMi / EARTH_RADIUS * 90; // radius in degrees for circle generator
Run Code Online (Sandbox Code Playgroud)

然后可以将其传递给圆生成器:

var circle = d3.geoCircle().radius(radiusDeg);
Run Code Online (Sandbox Code Playgroud)

最后,圆生成器用于通过数据绑定将其输出传递到适当的路径生成器,同时考虑到投影:

svg.append("path")
  .datum(circle)
    .attr("d", path);
Run Code Online (Sandbox Code Playgroud)

看看这个Block,它在全球不同的位置都有半径 50 英里的圆圈。圆生成器与投影相结合将控制圆的正确大小和正确外观。

在此处输入图片说明


D3 v3

如果您仍然坚持使用 D3 v3,该示例也能正常工作。但是,您需要相应地调整名称

除此之外,一些圆生成器的方法已重命名:

将这些调整应用于我上面链接的 Block,这也适用于 v3:v3 Block


当涉及具有严重扭曲的异常预测时,这种方法可以发挥其优势。只需将 Block 中的投影更改d3.geoGnomonic()为此即可轻松可见。更新后的Block的以下屏幕截图仍然显示与上面相同的圆圈,每个圆圈的半径为 50 英里:

在此处输入图片说明