半径按英里数缩放的D3 Topojson圆 [英] D3 Topojson Circle with Radius Scaled in Miles

查看:106
本文介绍了半径按英里数缩放的D3 Topojson圆的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

(假设现有的projection/topojson)

(assuming existing projection/topojson)

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

What I'm trying to do is create a circle at a point ([long,lat]) of radius (r) in miles. I know there is a d3.geo function for this, but after some consideration I don't think it will be very compatible with my particular application.

所以现在我正在寻找使用本机svg circle解决方案,其中cx和cy是经度和纬度,而r是以英里为单位的半径.我知道cx和cy,但是我不知道如何确保r等于15英里.因此,最主要的是如何确保在像素空间中绘制半径时以英里为单位缩放半径.必须以某种方式使用projection函数为半径设置适当的比例.但是我在实践中还没有看到.

So now I'm looking for using a native svg circle solution, where cx and cy are the lat and long, and r is the radius in miles. I know the cx and cy, but I don't know how to make sure the r is say 15 miles. So the main thing is how to make sure the radius is scaled in miles when drawn in pixel space. There must be someway to use the projection function to set the appropriate scale for the radius. But I haven't seen this in practice.

我还要指出,我的投影是动态的,取决于用户事件,投影(包括比例)可以更改.因此,我不确定这是否会影响现有投影范围内圆圈的缩放比例,但我想我会公开这一点,以确保安全.

Also I should point out that my projection is dynamic, depending on user events the projection (including scale) can change. So I'm not sure if that will have bearing on how circles are scaled within the context of an existing projection, but I thought I would disclose that to be on the safe side.

推荐答案

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

Why not use the built-in circle generator d3.geoCircle()?

使用"中心半径

Returns a new GeoJSON geometry object of type "Polygon" approximating a circle on the surface of a sphere, with the current center, radius and precision. Any arguments are passed to the accessors.

剩下的唯一任务是计算以度为单位的圆的半径.因为地球不是一个完美的球体,所以这可能对自身构成挑战.但是对于许多应用而言,近似值就足够了.仅考虑 3,958 mi 平均半径,计算可以写为:

The only task left to you is to calculate the radius of the circle in degrees. Because earth is not a perfect sphere this can become quite challenge of its own. But for many applications an approximation will suffice. Taking just the mean radius of 3,958 mi into account, the calculations can be written as:

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

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

This can then be passed to the circle generator:

var circle = d3.geoCircle().radius(radiusDeg);

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

Finally, the circle generator is used to pass its output via data binding to an appropriate path generator taking into account the projection:

svg.append("path")
  .datum(circle)
    .attr("d", path);

看看这个,它在各个位置的半径均为50英里在全球范围内.与投影结合使用的圆发生器将控制圆的正确尺寸和正确外观.

Have a look at this Block which features circles of 50 miles radius each at various positions around the globe. The circle generator in combination with the projection will take control of the correct sizing and the correct appearance of the circle.

如果您仍然坚持使用D3 v3,则该示例同样适用.但是,您需要相应地调整名称:

If you are still stuck to D3 v3 the example works as well. However, you need to adjust the names accordingly:

  • d3.geo.circle ↦ d3.geoCircle

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

In addition to that, some of the circle generator's methods have been renamed:

  • circle.origin()circle.center()
  • circle.angle()circle.radius()

将这些调整应用于我上面链接的代码块,这同样适用于v3: v3代码块.

Applying those adjustments to my above linked Block, this works for v3 just as well: v3 Block.

当涉及具有严重失真的异常投影时,此方法将发挥其优势.只需将块"中的投影更改为 d3.geoGnomonic() 即可轻松看到.以下来自更新的 Block 的屏幕截图仍显示了与上述相同的半径为50英里的圆圈每个:

This approach gets to play to its strengths when it comes to unusual projections having severe distortions. Just by changing the projection in the Block to d3.geoGnomonic() this becomes easily visible. The following screenshot from the updated Block still shows the same circles as above having a radius of 50 miles each:

这篇关于半径按英里数缩放的D3 Topojson圆的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆