如何在d3 AlbersUSA投影中移动状态?

时间:2012-10-24 17:42:36

标签: javascript position d3.js

我在d3中使用标准的AlbersUSA投影。

我遇到的一件事是,由于阿拉斯加和波多黎各在连续状态绘制的“矩形”之外,我无法最大化我的缩放系数以适应较小的视口。

理想情况下,我想将波多黎各移到路易斯安那州以下,并可能与夏威夷和阿拉斯加交换位置,这将使我有更好的合作范围。

查看文档,我看到AlbersUSA复合材料是使用以下函数创建的:

function albersUsa(coordinates) {
  var lon = coordinates[0],
      lat = coordinates[1];
  return (lat > 50 ? alaska
      : lon < -140 ? hawaii
      : lat < 21 ? puertoRico
      : lower48)(coordinates);
}

如何修改此功能(或有效创建我自己的功能),以便我可以移动状态而不必担心增加GeoJSON数据本身?

1 个答案:

答案 0 :(得分:0)

(我没试过这个)

  1. d3.geo.albersUsa的代码复制到d3源代码中(代码包含在本文的底部)。

  2. 修改名称:d3.geo.myAlbersUsa = function() { ... }

  3. 查看函数albersUsa.translate。这就是3个州被转移到“人为”位置的地方。例如alaska.translate([dx - 400 * dz, dy + 170 * dz]);

  4. 调整这些数字(400和170),直到它移动到您想要的位置(从小变化开始,如+/- 10)。

  5. 对于您要将数据绘制到的任何路径,您需要将其投影指定为自定义投影:path.projection(d3.geo.myAlbersUsa())

  6. 从D3源代码中,这是您在步骤1中复制/粘贴所需的代码:

    // A composite projection for the United States, 960x500. The set of standard
    // parallels for each region comes from USGS, which is published here:
    // http://egsc.usgs.gov/isb/pubs/MapProjections/projections.html#albers
    // TODO allow the composite projection to be rescaled?
    d3.geo.albersUsa = function() {
      var lower48 = d3.geo.albers();
    
      var alaska = d3.geo.albers()
          .origin([-160, 60])
          .parallels([55, 65]);
    
      var hawaii = d3.geo.albers()
          .origin([-160, 20])
          .parallels([8, 18]);
    
      var puertoRico = d3.geo.albers()
          .origin([-60, 10])
          .parallels([8, 18]);
    
      function albersUsa(coordinates) {
        var lon = coordinates[0],
            lat = coordinates[1];
        return (lat > 50 ? alaska
            : lon < -140 ? hawaii
            : lat < 21 ? puertoRico
            : lower48)(coordinates);
      }
    
      albersUsa.scale = function(x) {
        if (!arguments.length) return lower48.scale();
        lower48.scale(x);
        alaska.scale(x * .6);
        hawaii.scale(x);
        puertoRico.scale(x * 1.5);
        return albersUsa.translate(lower48.translate());
      };
    
      albersUsa.translate = function(x) {
        if (!arguments.length) return lower48.translate();
        var dz = lower48.scale() / 1000,
            dx = x[0],
            dy = x[1];
        lower48.translate(x);
        alaska.translate([dx - 400 * dz, dy + 170 * dz]);
        hawaii.translate([dx - 190 * dz, dy + 200 * dz]);
        puertoRico.translate([dx + 580 * dz, dy + 430 * dz]);
        return albersUsa;
      };
    
      return albersUsa.scale(lower48.scale());
    };