D3.Geo在平移/缩放上的表现

时间:2013-06-13 17:42:02

标签: d3.js gis topojson

去年,我使用Mapnik library(服务器端,位图/平铺)在网络地图上进行了几次实验。现在我试图使用d3.js的载体,客户端方法复制相同的实验。

我有一张地图(~680个形状),其中zoom很慢而pan缓慢(迈克博斯托克的this example效果很好)。我怀疑问题出在zoommove回调中,selectAll("path").attr("d", path)需要太长时间。

function zoommove() {
    projection.translate(d3.event.translate).scale(d3.event.scale);
    mapa.selectAll("path").attr("d", path);
    console.log('zoommove fired...');
}

问题

  1. 我在这里做错了吗?
  2. 我可以做些什么才能优化表现?
  3. 地图就是这个(jsfiddle here):

    Municipalities from São Paulo State, Brazil

    数据源采用topojson格式。它被简化了,可能已经太多了,因为有些形状没有关闭:

    enter image description here

    [UPDATE]

    看起来即使在没有简化标志的情况下运行topojson时也会出现打开几何的问题,我还在调查。我很感激这里的任何线索,文档不是很详细。

3 个答案:

答案 0 :(得分:11)

(我不太清楚这里发生了什么,这可能是完全错误的)。

mapa.selectAll("path").attr("d", path);

从头开始重绘地图。这适用于50个州,但开始变得相当缓慢,600多个形状。如果你把路径留在原地并且只是改变了整个svg,你可能会有更好的运气:

function zoommove() {
  svg.attr("transform",
      "translate("+d3.event.translate+")"
      + " scale("+d3.event.scale+")");
}

我曾经用它创建一个美国county level map(约500个形状),可以平滑地缩放和平移。

答案 1 :(得分:2)

在这里回答我自己的问题,如果你觉得这很有帮助,那么请提升亚当的答案,值得信赖。

对我有用的是什么:

var bg = svg.append('g')
    .call(zoom);

var map = bg.append("g")
    .attr("transform", "translate(0,0) scale(1)");

...

function zoommove() {
    var t1 = projection.translate(),
        t2 = d3.event.translate,
        t = [t2[0]-t1[0], t2[1]-t1[1]];

    map.attr("transform", 
        "translate("+t+") " +
        "scale("+(d3.event.scale/s)+")"
    );
    console.log(map.attr("transform"));
}

一些提示:

  • 如果projection.translate()不是[0,0],则必须将其考虑在内,否则在您第一次尝试平移/缩放时会出现大的凹凸(仅限第一次)。
  • 如果projection.scale()不是1,则必须将其考虑在内。
  • .call(zoom)必须位于地图父元素中,否则平移/缩放会变得颠簸。

答案 2 :(得分:1)

我遇到过类似的问题,并且重新缩放不适合我的解决方案,因为我不希望svg元素本身被缩放。我做的是优化它,使得可见区域之外的元素不会重新计算。这意味着当所有元素都在视图中时,性能仍然很差,但是当你放大它时会更好。

ode样本:

clippedArea.selectAll("circle")
    .style("visibility", d => pointInDomain(d, domain) ? "visible" : "hidden")
    .filter(d => pointInDomain(d, domain))
  .attr("cx", d => xz(d.x));

JSFiddle