带有 Albers 投影的 D3.js 地图:如何旋转它?

IT技术 javascript d3.js topojson map-projections
2021-03-06 03:12:07

我正在用 d3.js 构建菲律宾的地图,但出于一个奇怪的原因,地图看起来像在左侧旋转,因此该国家/地区看起来并不真实。我试图修改projection.rotate 字段,但似乎不是修正线。

    var width = 1060,
    height = 860;

    var svg = d3.select("body").append("svg")
        .attr("width", width)
        .attr("height", height)
        .style("overflow", "auto");

    d3.json("ph.json", function(error, ph) {
      if (error) return console.error(error);

      var subunits = topojson.feature(ph, ph.objects.ph_subunits);

      var projection = d3.geo.albers();
      projection.rotate([-4 ,0]);
      projection.scale(3000);
      projection.center([122.427150, 12.499176]);
      projection.parallels([10, 15])
      projection.translate([width / 2, height / 2]);

      var path = d3.geo.path()
           .projection(projection)
           .pointRadius(2);
      svg.append("path")
        .datum(subunits)
        .attr("d", path);

    });

这是代码。

任何帮助都会很棒!

谢谢!

1个回答

如果您不知道潜在的转换,Albers 预测可能会有点棘手。除非显示美国(d3.geoAlbers 的参数默认为美国),否则您可能需要修改平行度、旋转度和中心。

标准平行线

这是一个阿尔伯斯投影,其平行度设置为 10 和 15 .parallels([10,15]),如您的问题所示,比例为 100(旋转和中心设置为 [0,0]):

基本的阿尔伯斯

这种形状是由于投影的圆锥形特性。如果选择南部平行线,则凹度将反转。更极端的纬度/平行将导致更大的弯曲。

选择的平行线应穿过您感兴趣的区域,因为平行线附近的区域是失真最小的区域。

回转

如果我们想说,请关注澳大利亚(为了演示,我将保持与上图相同的相似之处):

澳大利亚剪辑

我们可以简单地使用澳大利亚的地理中心作为投影的中心.projection.center([x,y])并缩放到适当的水平.projection.scale(1000)

澳大利亚

唯一的变化是澳大利亚变大了,它仍然像在地图角落时一样扭曲,而且变小了。它向上/向下和向左/向右移动,然后在没有其他变换的情况下放大。

正如您的问题所推测的那样,旋转是显示不在本初子午线附近的区域的解决方案。

如果我们将第一张地图(与第二张地图相同)旋转 100 度经度.projection.rotate([100,0]),我们得到:

阿尔伯斯100度

世界旋转了 100 度,一条垂直穿过地图中心的假想线与经度 -100 度或西经 100 度的子午线对齐。

定心

如果我们感兴趣的区域是中美洲(您使用的平行线 - 我一直在使用 - 将适用于该地区),那么下一步是沿着投影的中央子午线上下移动地图的中心。对于中美洲,这种转变可能是 20 度:.projection.center([0,20])使用适当的比例,假设 1000,结果将如下所示:

最后

菲律宾

因此,对于菲律宾,使用您的中心坐标 [122.427150, 12.499176] 和平行线,理想的 Albers 投影可能如下所示:

        projection.rotate([-122.427150,0])
              .center([0,12.499176])
              .scale(1200)
              .parallels([10,15]);

这对我来说产生了: 最后

概括

对于阿尔伯斯:

projection.parellels([a,b])
  .rotate([-x,0])
  .center([0,y])
  .translate([w/2,h/2])

其中ab是相交的感兴趣区域的相似之处,y是中央并行,并x为中央子午线。

如果使用方法 ( projeciton.fitSize/ projection.fitExtent) 自动居中和缩放要素,则不需要使用居中和旋转方法,但仍必须先设置平行度和旋转度。