简体   繁体   English

带有阿尔伯斯投影的 D3.js 地图:如何旋转它?

[英]D3.js Map with Albers Projection: How to rotate it?

I'm building a map of the Philippines with d3.js and for a strange reason the map looks like rotated on the left, so that the country doesn't look how it really is.我正在使用 d3.js 构建菲律宾地图,但出于一个奇怪的原因,该地图看起来像在左侧旋转,因此该国家/地区看起来并不真实。 I've tried to modify the projection.rotate field but doesn't seems like is the correction line.我试图修改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);

    });

This is the code.这是代码。

Any help would be great!任何帮助都会很棒!

Thanks!谢谢!

Albers projections can be a bit tricky if you don't know the underlying transformations.如果您不知道潜在的转换,Albers 预测可能会有点棘手。 Unless showing the US (for which the parameters of d3.geoAlbers are defaulted to), you'll likely need to modify the parallels, rotation, and center.除非显示美国(d3.geoAlbers 的参数默认为美国),否则您可能需要修改平行度、旋转度和中心。

Standard Parallels标准平行线

This is an albers projection with its parallels set to 10 and 15 .parallels([10,15]) , as in your question, and a scale of 100 (and with rotation and center set to [0,0]):这是一个阿尔伯斯投影,其平行度设置为 10 和 15 .parallels([10,15]) ,如您的问题,比例为 100(旋转和中心设置为 [0,0]):

基本的阿尔伯斯

This shape is due to the conical nature of the projection.这种形状是由于投影的圆锥形特性。 If southern parallels are chosen, the concavity is reversed.如果选择南部平行线,则凹度将反转。 More extreme latitudes/parallels will result in a greater bend.更极端的纬度/平行将导致更大的弯曲。

The parallels selected should run through your area of interest as the area near the parallels is where distortion is minimized.选择的平行线应穿过您感兴趣的区域,因为平行线附近的区域是失真最小的区域。

Rotation回转

If we wanted to say, focus on Australia (I'll keep the parallels the same as the image above for the sake of demonstration):如果我们想说,请关注澳大利亚(为了演示,我将保持与上图相同的相似之处):

澳大利亚剪辑

We could simply use the geographic center of Australia as the center of the projection .projection.center([x,y]) and scale to an appropriate level .projection.scale(1000) :我们可以简单地使用澳大利亚的地理中心作为投影的中心.projection.center([x,y])并缩放到适当的级别.projection.scale(1000)

澳大利亚

The only change is that Australia is bigger, it is still as distorted as when it was in the corner of the map and smaller.唯一的变化是澳大利亚更大了,它仍然像在地图角落时一样扭曲并且变小了。 It was shifted up/down and left/right and then magnified with no other transformations.它向上/向下和向左/向右移动,然后在没有其他变换的情况下放大。

As your question surmises, rotation is the solution to the problem of showing areas not near the prime meridian.正如您的问题所推测的那样,旋转是显示不在本初子午线附近的区域的解决方案。

If we rotate the first map (which is the same as the second map) by 100 degrees of longitude .projection.rotate([100,0]) , we get:如果我们将第一张地图(与第二张地图相同)旋转 100 度经度.projection.rotate([100,0]) ,我们得到:

阿尔伯斯100度

The world has spun 100 degrees, and an imaginary line drawn vertically through the center of the map aligns with the meridian at -100 degrees of longitude or 100 degrees west.世界旋转了 100 度,一条垂直穿过地图中心的假想线与经线 -100 度或西经 100 度的子午线对齐。

Centering定心

If our area of interest is Central America (for which the parallels you used - and I have continued to use - will work for) then the next step is to shift the center of the map up and down along the projection's central meridian.如果我们感兴趣的区域是中美洲(您使用的平行线 - 我一直在使用 - 将适用于该地区),那么下一步是沿着投影的中央子午线上下移动地图的中心。 For Central America, this shift might be 20 degrees : .projection.center([0,20]) .对于中美洲,这种偏移可能是 20 度: .projection.center([0,20]) With an appropriate scale, let's say 1000 the result will look like:使用适当的比例,假设 1000,结果将如下所示:

最终的

Philippines菲律宾

So, for the Philippines, using your center coordinate [122.427150, 12.499176] and parallels, an ideal Albers projection might look like:因此,对于菲律宾,使用您的中心坐标 [122.427150, 12.499176] 和平行线,理想的阿尔伯斯投影可能如下所示:

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

Which for me yielded:这对我来说产生了: 最终的

Summary概括

For an Albers:对于阿尔伯斯:

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

Where a and b are parallels that intersect the area of interest, y is the central parallel, and x is the central meridian.其中ab是与感兴趣区域相交的纬线, y是中央纬线, x是中央子午线。

If using a method ( projeciton.fitSize / projection.fitExtent ) to automatically center and scale a feature, you don't need to use the center and rotate methods, but you must still set parallels and rotation first.如果使用方法( projeciton.fitSize / projection.fitExtent )来自动中心和缩放功能,您无需使用中心和旋转的方法,但仍然必须设置平行和旋转第一。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM