Javascript D3以英里为单位缩放半径的圆

Javascript D3以英里为单位缩放半径的圆,javascript,d3.js,topojson,Javascript,D3.js,Topojson,假设现有投影/拓扑 我想做的是在半径为r的点(长,纬度)处创建一个圆,以英里为单位。我知道有一个d3.geo函数用于此,但经过一些考虑后,我认为它不会与我的特定应用程序非常兼容 因此,现在我正在寻找使用本机svg圆形解决方案,其中cx和cy是lat和long,r是以英里为单位的半径。我知道cx和cy,但我不知道如何确保r是15英里。因此,主要的问题是如何确保在像素空间中绘制时,以英里为单位缩放半径。必须有某种方法可以使用投影函数为半径设置适当的比例。但我还没有在实践中看到这一点 我还应该指出,我

假设现有投影/拓扑

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

因此,现在我正在寻找使用本机svg圆形解决方案,其中cx和cy是lat和long,r是以英里为单位的半径。我知道cx和cy,但我不知道如何确保r是15英里。因此,主要的问题是如何确保在像素空间中绘制时,以英里为单位缩放半径。必须有某种方法可以使用投影函数为半径设置适当的比例。但我还没有在实践中看到这一点


我还应该指出,我的投影是动态的,取决于用户事件,投影(包括比例)可以改变。因此,我不确定这是否会影响现有投影中圆的缩放方式,但为了安全起见,我想我会披露这一点。

为什么不使用内置圆生成器

返回一个类型为“Polygon”的新GeoJSON几何体对象,该对象近似于球体表面上的一个圆,具有当前和。任何参数都会传递给访问器

剩下的唯一任务是计算圆的半径(以度为单位)。因为地球不是一个完美的球体,这可能会成为它自身的一个挑战。但对于许多应用,近似值就足够了。仅考虑3958 mi的长度,计算可写成:

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
然后可以将其传递给圆生成器:

var circle = d3.geoCircle().radius(radiusDeg);
最后,圆生成器用于通过数据绑定将其输出传递到适当的路径生成器,同时考虑投影:

svg.append("path")
  .datum(circle)
    .attr("d", path);
看看这个,它的特点是在全球不同的位置都有半径为50英里的圆圈。与投影相结合的圆生成器将控制圆的正确大小和正确外观

D3V3 如果您仍然坚持使用D3V3,那么这个示例也可以使用。但是,您需要相应地调整:

d3.geo.circle↦ 除此之外,圆生成器的某些方法已重命名:

圆圈↦ 圆圈 圆圈↦ 圆圈 将这些调整应用于我上面的链接块,这同样适用于v3:

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


为什么不使用内置的圆生成器

返回一个类型为“Polygon”的新GeoJSON几何体对象,该对象近似于球体表面上的一个圆,具有当前和。任何参数都会传递给访问器

剩下的唯一任务是计算圆的半径(以度为单位)。因为地球不是一个完美的球体,这可能会成为它自身的一个挑战。但对于许多应用,近似值就足够了。仅考虑3958 mi的长度,计算可写成:

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
然后可以将其传递给圆生成器:

var circle = d3.geoCircle().radius(radiusDeg);
最后,圆生成器用于通过数据绑定将其输出传递到适当的路径生成器,同时考虑投影:

svg.append("path")
  .datum(circle)
    .attr("d", path);
看看这个,它的特点是在全球不同的位置都有半径为50英里的圆圈。与投影相结合的圆生成器将控制圆的正确大小和正确外观

D3V3 如果您仍然坚持使用D3V3,那么这个示例也可以使用。但是,您需要相应地调整:

d3.geo.circle↦ 除此之外,圆生成器的某些方法已重命名:

圆圈↦ 圆圈 圆圈↦ 圆圈 将这些调整应用于我上面的链接块,这同样适用于v3:

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


需要考虑的几个问题:正如您所指出的,1英里是以像素为单位的可变距离,取决于用户的位置。投影函数对于以单位表示的基础贴图的距离是幼稚的。您需要以某种方式通知投影函数topojson文件中的1英里是多少。一种方法是将距离计算为环绕地球的距离的一个比例(以弧度为单位)。看这里:是的,我知道这一块,我以前在研究中见过。然而,它需要一个有点长的距离像素功能,他广告
他的数学可能不是100%正确。我希望通过提供赏金,我能够看到是否有更完善的替代方案。需要考虑的几个问题:正如您所指出的,1英里是一个以像素为单位的可变距离,取决于用户的位置。投影函数对于以单位表示的基础贴图的距离是幼稚的。您需要以某种方式通知投影函数topojson文件中的1英里是多少。一种方法是将距离计算为环绕地球的距离的一个比例(以弧度为单位)。看这里:是的,我知道这一块,我以前在研究中见过。然而,它需要一个有点长的距离像素函数,他承认他的数学可能不是100%正确。我希望通过提供赏金,我能看到是否有更精致的选择。很好的解释,它帮助我理解更大的图景。让我来讨论一下,然后再回复你。经过更多的测试,我必须坚持我在文章前几行提到的评估。使用本机svg循环将使我的生活更加轻松。然而,你的回答在这里解释得很好,所以我很乐观,并给予它的怀疑的好处。我可能无法将其用于需要svg的原始circle应用程序,但我仍然尝试使用我制作的最小块来测试您的d3.geo。我用的是D3V3。但不起作用。因此,如果你不介意多走一步,你能解决这两个问题吗?暂时把原生svg圈放在一边。一旦我进一步理解了d3.geo.circle,我将假设d3.geo.circle可以完成原生svg circles所能做的一切。不要误解我的意思,我正在准备使用这种方法,但它有点挑战性,因为管道上的东西是svg循环,我的环境需要类似的接口。例如,我需要能够动态更改半径。使用本机svg:my_circle.attr{r:my_new_radius_value}但是,当我尝试my_geo_circle.anglemy_new_radius_value时,我没有得到函数错误。有办法解决这个问题吗?添加:my_geo_circle.datumnew_circle.attrd,geo_path后,我可以动态更改半径。忍受我的学习曲线,我不是制图工具棚里最锋利的工具。不管怎么说,你的解决方案很好,非常感谢。我给你50块赏金!半径米/地球半径*90是否错误?我想你需要radiusMi/EARTH\u RADIUS*360/2*Math.PI。很好的解释,它帮助我理解更大的图景。让我来讨论一下,然后再回复你。经过更多的测试,我必须坚持我在文章前几行提到的评估。使用本机svg循环将使我的生活更加轻松。然而,你的回答在这里解释得很好,所以我很乐观,并给予它的怀疑的好处。我可能无法将其用于需要svg的原始circle应用程序,但我仍然尝试使用我制作的最小块来测试您的d3.geo。我用的是D3V3。但不起作用。因此,如果你不介意多走一步,你能解决这两个问题吗?暂时把原生svg圈放在一边。一旦我进一步理解了d3.geo.circle,我将假设d3.geo.circle可以完成原生svg circles所能做的一切。不要误解我的意思,我正在准备使用这种方法,但它有点挑战性,因为管道上的东西是svg循环,我的环境需要类似的接口。例如,我需要能够动态更改半径。使用本机svg:my_circle.attr{r:my_new_radius_value}但是,当我尝试my_geo_circle.anglemy_new_radius_value时,我没有得到函数错误。有办法解决这个问题吗?添加:my_geo_circle.datumnew_circle.attrd,geo_path后,我可以动态更改半径。忍受我的学习曲线,我不是制图工具棚里最锋利的工具。不管怎么说,你的解决方案很好,非常感谢。我给你50块赏金!半径米/地球半径*90是否错误?我想你需要半径mi/EARTH\u RADIUS*360/2*Math.PI。