从命令行预先简化topojson

时间:2014-06-09 09:54:50

标签: javascript topojson

据我所知,D3中的topojson.presimplify(JSON)根据其重要性将Z坐标添加到输入topojson形状中的每个点,然后允许将其用于动态简化,如{{3 }}

此方法topojson.presimplify()需要很长时间才能在复杂的地图上执行,尤其是在Firefox中,这会使浏览器在几秒钟内无响应。

可以通过命令行将其直接烘焙到topojson文件中,因为它是通过投影完成的:

topojson --projection 'd3.geo.mercator().translate([0,0]).scale(1)' -o cartesian.topo.json spherical.topo.json

1 个答案:

答案 0 :(得分:1)

我找到了一个解决方法,这并不是我想要的那么简单,但仍然可以达到相同的效果。

调用topojson.presimplify(data)后,data已经保留了预先简化的几何图形,并添加了Z轴值。

然后我将其转换为JSON字符串并手动将其复制到JSON.stringify(data)的新文件

然而,这些转换为JSON字符串的Infinity值经常出现Z并且JSON.stringify方法转换为null时出现问题。此外,当Z坐标值存在时,它通常过于精确,并且写入所有小数点会占用太多空间。

出于这个原因,在将data转换为JSON字符串之前,我修剪了数字:

// Simplifying the map
topojson.presimplify(data);

// Changing Infinity values to 0, limiting decimal points
var arcs = data.arcs;
for(var i1 = arcs.length; i1--;) {
    var arc = arcs[i1];
    for(var i2 = arc.length; i2--;) {
        var v = arc[i2][2];
        if(v === Infinity) arc[i2][2] = 0;
        else {
            arc[i2][2] = M.round(v * 1e9)/1e9;
        }
    }
}

这使得Infinity值显示为0,其他值被修剪为9个小数点,这足以使动态简化工作正常。

由于此类字符串太长而无法轻松打印以复制到新的json文件,因此将其存储在浏览器的localStorage中要容易得多:

localStorage.setItem(<object name>, JSON.stringify(data))

然后在Safari或Chrome中打开开发人员控制台,在标签Resources -> Local Storage -> <Website URL>中,可以找到,复制存储的对象,然后将其粘贴到文本编辑器中。

通常它被粘贴为<key> <value>对,因此需要从粘贴的字符串的开头删除它,以便从{开始。

由于Infinity值已转换为0,因此在动态简化函数中应将其考虑在内,以便将Z = 0的点视为Z = Infinity并且总是用任何简化区域绘制:

point: function(x, y, z) { 
    if (z===0 || z >= simplificationArea) {
        this.stream.point(x, y); 
    }
}