D3中投影的动态简化

时间:2014-05-31 19:30:06

标签: javascript d3.js topojson

我正在使用d3.geo.mercator()投影绘制带有D3的SVG地图。

我还使用地图的缩放行为,将transform应用于保存地图所有路径的<g>对象。

在看了Mike Bostock(http://bl.ocks.org/mbostock/6252418)的动态简化示例之后,我想知道我是否可以在我的情况下应用这样的算法,在缩小时用较少的点重绘几何体?

在我看过的所有例子中,有一个simplify函数跳过可忽略不计的点并将其余部分绘制成原样,并且该函数在var path = d3.geo.path().projection(simplify)中使用。我无法像这样使用它,因为我需要将它应用于现有的projection = d3.geo.mercator().scale(*).translate([*,*])

如何在现有投影中使用动态简化?

1 个答案:

答案 0 :(得分:2)

根据您引用的示例Dynamic Simplification II

simplify函数类似于

var simplify = d3.geo.transform({
  point: function(x, y, z) {
    if (z >= area) {
        this.stream.point(x, y);
    }
  }
});

其中area是一个阈值变量,您可以预先设置或根据缩放进行dinamically修改。

然后你会在projection的{​​{1}}方法中使用

d3.geo.path()

这或多或少是你在答案中描述的情况。现在,根据Dynamic Simplification IV,投影方法也可以定义为

var path = d3.geo.path()
    .projection(simplify);

这和以前完全一样。它只是&#34;扩展&#34;默认方法。 var path = d3.geo.path() .projection({ stream: function(s) { return simplify.stream(s); } }); 始终调用投影d3.geo.path方法,因此您可以声明自己的流并将其转发到stream

现在,您说需要使用d3.geo.mercator()重新投影路径。

simplify.stream

没问题:流可链接。你可以这样做:

var mercatorProjection = d3.geo.mercator().scale(*).translate([*,*]);

以及:

var path = d3.geo.path()
    .projection({
        stream: function(s) { 
            return simplify.stream(mercatorProjection.stream(s)); 
        }
     });

唯一的区别是,如果您正在处理WGS84,像素或其他坐标系,则必须以不同方式计算阈值区域。

重要警告var path = d3.geo.path() .projection({ stream: function(s) { return mercatorProjection.stream(simplify.stream(s)); } }); 函数中的z参数不是海拔高度。它是the area of the triangle defined by each point,是一个预先计算的值,是TopoJSON甜蜜的一部分。

我担心这意味着您不能依赖此示例来简化常规geoJSON。您必须添加自己的逻辑来计算每个点的相关区域(如果您想应用Visvalingam's algorithm)或距离最近点的距离(如果您想应用{{3})算法)或实现自己的算法。

祝你好运。