我正在使用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([*,*])
。
如何在现有投影中使用动态简化?
答案 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})算法)或实现自己的算法。
祝你好运。