如何在运行时以编程方式向topojson文件添加属性?

时间:2017-02-15 21:36:29

标签: json d3.js geojson topojson

我试图在运行时向topojson添加其他属性。我查看了Choropleth示例,但我不认为有人操纵原始的json文件。

最好的方法是什么?

JSON:

list

合并数组看起来像这样:

{ "type":"Topology", "objects":{ "countries":{ "bbox":[ ... ], "type":"GeometryCollection", "geometries":[ { "type":"Polygon", "properties":{ "name":"Afghanistan", "count": 30 // <------- Property I want to add. }, "id":"AFG", "arcs":[ ... ] }, { "type":"MultiPolygon", "properties":{ "name":"Angola", "count": 50 // <------- Property I want to add. }, "id":"AGO", "arcs":[ ... ] } ... }

1 个答案:

答案 0 :(得分:2)

  

我查看了Choropleth示例,但我认为没有人操纵原始的json文件。

不,他没有。在您链接的示例中,Mike Bostock创建了一个地图......

var unemployment = d3.map();
unemployment.set(d.id, +d.rate);

......然后他使用那张地图:

.attr("fill", function(d) { return color(d.rate = unemployment.get(d.id)); })

正如您所看到的,这种方法不会改变topoJSON。除此之外,它更快更优雅。

但是,如果要向topoJSON添加属性,可以轻松完成。

首先,嵌套您的d3.jsond3.csv(或您用来获取数据的任何其他功能):

d3.csv("mycsv.csv", function(data) {
    d3.json("mytopojson.json", function(json) {
        //code here
    });
});

然后,使用两个嵌套的for循环来添加属性(不是更快的解决方案)。在这个演示中,我正在硬编码topoJSON并使用<pre>加载CSV,因为在Stack片段中,我无法上传真实文件。

检查它,原始topoJSON对象没有count属性,但console.log中显示的结果包含:

var topoJSON = {
    "type": "Topology",
    "objects": {
        "countries": {
            "type": "GeometryCollection",
            "geometries": [{
                "type": "Polygon",
                "properties": {
                    "name": "Afghanistan"
                },
                "id": "AFG"
            }, {
                "type": "MultiPolygon",
                "properties": {
                    "name": "Angola"
                },
                "id": "AGO",
            }]
        }
    }
};

var csv = d3.csvParse(d3.select("#csv").text());

var geometries = topoJSON.objects.countries.geometries;

for (var i = 0; i < csv.length; i++) {
    for (var j = 0; j < geometries.length; j++) {
        if (csv[i].country == geometries[j].id) {
            geometries[j].properties.count = csv[i].count;
        }
    }
}

console.log(topoJSON);
pre{
  display:none;
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<pre id="csv">country,count
AGO,50
AFG,30</pre>