d3 - 我可以以某种方式组成两个投影,或投射投影吗?

时间:2016-05-05 21:13:49

标签: javascript d3.js mapping projection composition

我想创建一个在Z轴上向后倾斜的地图,就好像你正看着它平放在桌子上一样。没问题:使用Mike Bostock的custom projection方法,定义一个简单的转换,可以在向上移动时缩放,称之为一天。

除了在过程中我了解到d3默认为Albers USA投影,并且使用我的自定义投影将阿拉斯加和夏威夷放回正确的位置(我不想要。)

另外,我没有意识到波多黎各没有参加Albers USA投影,所以我实际上想切换到Albers USA + PR

如果我能提供帮助,我宁愿不重新制作预测,因为有一天我会找到一个同样拥有其他美国领土的阿尔伯斯。

投影是否可以合成?

1 个答案:

答案 0 :(得分:2)

在不知道您的实施细节的情况下,我有forked Mike Bostock的Block AlbersUSA + PR来展示可以做到这一点的方法。

其核心是使用Albers USA投影,其中包括波多黎各的要求。这是正常的D3 projection

var albersUsaPrProj = albersUsaPr()
    .scale(1070)
    .translate([width / 2, height / 2]);

接下来,我已经对表格实施了一个相当天真的投影,可能需要进行一些改进,但应该足以让你开始。这个使用d3.geo.transform()来创建流包装器,用于在桌面上投影地图所需的计算。包裹的stream listener只需要实现point方法,该方法将使用xy屏幕坐标调用,这些坐标是地理投影的结果。

// The scale is used for convenient calculations only.
var yScale = d3.scale.linear()
               .domain([0,height])
               .range([0.25,1]);

var desktopProj = d3.geo.transform({
  point: function(x,y) {
    this.stream.point((x - 0.5*width) * yScale(y) + (0.5*width), y);
  }
});

通过创建实现.stream()方法的对象,两个投影很容易组合成一个新的流包装器。

var combinedProj = {
  stream: function(s) {
      return albersUsaPrProj.stream(desktopProj.stream(s));
  }
};

根据projection.stream(listener)上的文件:

  

返回指定侦听器的突出流包装器。流式传输到包装器的任何几何体都会在流式传输到包装的侦听器之前进行投影。

这将首先让albersUsaPrProj处理地图的Albers USA投影,然后将生成的屏幕坐标流式传输到desktopProj

然后可以将此组合投影传递给path.projection([projection])

  

为了更好地控制流转换,可以将投影指定为实现 stream 方法的对象。 (参见示例。)stream方法将输出流作为输入,并返回投影输入几何的包装流;换句话说,它实现了projection.stream

这给我们最后的电话号码

var path = d3.geo.path()
    .projection(combinedProj);
相关问题