Предварительно упростить топожсон из командной строки

Насколько я понимаю, topojson.presimplify(JSON) в D3 добавляет Z координату к каждой точке во входной форме топоса в зависимости от ее значимости, что затем позволяет использовать ее для динамического упрощения, как в http://bl.ocks.org/mbostock/6245977

Этот метод topojson.presimplify() выполняется довольно долго на сложных картах, особенно в Firefox, из-за чего браузер перестает отвечать на запросы в течение нескольких секунд.

Можно ли его запечь прямо в файл topojson через командную строку, как это делается с проекциями:

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

person BartoNaz    schedule 09.06.2014    source источник


Ответы (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.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); 
    }
}
person BartoNaz    schedule 11.06.2014