如何在D3中使用多个多边形(对于多个结果视口)剪辑地理投影?

时间:2015-04-21 00:00:12

标签: svg d3.js geo

TL; DR:尝试渲染非连续的更全面的投影,但要素多边形跨越多个"视口"。如何避免(在视口边缘处切割多边形)?

完整版我想渲染一个非连续的更全面的投影(瓷砖用"空格"而不是传统上对齐)地理数据。如何在D3中使用它?我正在寻找的粗略布局的示例可以是found here

我认为,基于Jason Davis在jasondavies.com/maps/airocean的极其有益的工作,我已经想出如何编写投影本身。由于我不想要连续的地图表示,我只是硬编码每个面的从gnomonic到相对位置的变换,而不是对共享的tile边缘进行矩阵乘法。但是,跨越切片边界的要素当前会呈现为单个SVG路径,从而导致它们在画布上涂抹整个画面(连接它们所在的切片),如此simple layout example

我注意到Jason已经分叉了D3进行更全面的投影,添加了d3.geo.projection.clipPolygon来渲染非矩形视口。但即便如此,逻辑似乎仅限于包含整个地图的单个视口。看看clipPolygon的实现,我不确定我是否可以在任何合理的时间内调整它以处理多个多边形。

请注意,由于我不打算将其发布为网页(它是艺术项目中物理布局的基础),如果渲染时间是以下情况,我会非常高兴很长,我每个脸都有一个投影,剪辑轮廓每个只包含一个面。不幸的是,即使这一点现在看起来已经超出我的范围,如果我将单个图块的轮廓作为剪辑多边形传递,我只会渲染该图像但完全填充单一颜色(特征多边形)。

任何帮助表示赞赏! :)

"多面体"投影我使用:

d3.geo.woodcut = function(nodes, face) {
  var r = π / 1.5;

  var baseTransform = [
    Math.cos(r), Math.sin(r), 0,
    -Math.sin(r), Math.cos(r), 0
  ];

  var mesh = [], outline = [];

  for (var i = 0; i < nodes.length; ++i) {
    var node = nodes[i];   
    var ring = node.face.slice();
    ring.push(ring[0]);
    var centroid = d3.geo.centroid({type: "Polygon", coordinates: [ring]});

    // add mesh
    var edges = faceEdges(node.face);
    for (var j = 0; j < edges.length; ++j) {
      // todo: skip some sides for indented triangle
      mesh.push(edges[j].map(function(d) { return d3.geo.interpolate(d, centroid)(ε); }));
    }

    // add to outline
    if (i == 4/*true*/) {
      var tmp = node.face.slice();
      tmp.push(tmp[0]);
      for (var j = 0; j < tmp.length; ++j) {
        outline.push(tmp.map(function(d) { return d3.geo.interpolate(d, centroid)(ε); }));
      }
    }

    node.transform = baseTransform.slice();
    node.transform[2] = i * 1.5;
  }

  function forward(λ, φ) {
    var node = face(λ, φ),
        point = node.project([λ * degrees, φ * degrees]),
        t;
    if (t = node.transform) {
      return [
        t[0] * point[0] + t[1] * point[1] + t[2],
        -(t[3] * point[0] + t[4] * point[1] + t[5])
      ];
    }
    point[1] = -point[1];
    return point;
  }

  var projection = d3.geo.projection(forward)/*.clipPolygon(outline)*/;
  projection.mesh = mesh;

  return projection;
}

0 个答案:

没有答案