Arash Howaida
Arash Howaida

Reputation: 2617

Topojson adding external properties without any apparent mapping context

The goal is to add external properties to a topojson. I have succeeded in converting shapefiles from http://www.diva-gis.org/gdata for various countries into json files. I have also succeeded in down-sampling these files to a more front-end friendly file-size. Like this:

shp2json CHN_adm0.shp --out CHN_adm0.json
geo2topo CHN_adm0.json > china.json
shp2json CHN_adm1.shp --out CHN_adm1.json
geo2topo CHN_adm1.json > china.json
toposimplify -s 1e-9 -f < china.json > china-topo.json
toposimplify -s 1e-9 -f < china1.json > china1-topo.json

Then I merged the country level polygons with the provincial level polygons. And perhaps this is where I might append external properties if this is correct, but as you will see I may have an additional hurdle:

geo2topo regions=CHN_adm1.json country=CHN_adm0.json > china-regions-topo.json
toposimplify -s 1e-9 -f < china-regions-topo.json > china-regions.json

What I am unsure with at this juncture is how one appends properties to data from diva-gis. Here is an example slice of the dict/object and relevant keys of what my china-regions.json ended up like (note: I'm using python to explore the json file, but I'm not really going to use python for anything else in question):

len(json['objects']['regions']['geometries'])
>> 31 ## 31 provinces in China

json_data['objects']['regions'].keys()

>> dict_keys(['type', 'bbox', 'geometries']) ## seems like there is nothing to map to, like an id or province name

Question

How do I add external properties to topojsons that I have converted from shapefiles from diva-gis? It appears there is nothing to map to. I can't even tell which province is which after exploring the data; it's just a list of arcs -- which plot on a map well enough, but there is nothing intuitive for a human to discern which province is which.

Further Clarifications:

Upvotes: 1

Views: 353

Answers (1)

Andrew Reid
Andrew Reid

Reputation: 38181

Your close to finding an identifier - they are typically grand children of each geometry:

topojson.objects.regions[n].geometry.properties.property // where property is a column in the original shapefile.

With shp2json you can't use --geometry or --ignore-properties or you'll ignore the dbf file. The dbf file holds the properties of each feature

These properties are the columns of the attribute table of the shapefile. If you have nothing here, you have not included the dbf file that holds this data as part of the conversion process.

With just javascript I might get a list of properties of each geometry with:

    // Get the geometries:
    var regions = data.objects.regions.geometries;

    // List of properties present (in first element anyways):
    console.log(Object.keys(regions[0].properties));

And to add new properties, using javascript and d3's map method, I might use:

    // Create a map to look up regions:
    var map = d3.map(regions, function(d) { return d.properties.NAME_1; });

    // Get by Name_1:
    console.log(map.get("ExampleName"));        

    // New data to join to topojson:
    var dataToAttach = [
        { region: "A", capital: "X" },
        { region: "B", capital: "Y" },
        { region: "C", capital: "Z"}  //...
    ]

    // Add new property:
    dataToAttach.forEach(function(d) {
      map.get(d.region).capital = d.capital;
    })

The most common issue here is that the identifiers won't match exactly or at all with the tabular data you want to join to it, this will often require tinkering.

Here's an implementation of the above (in the client though), using and adding data to a topojson create from diva gis data.

Upvotes: 0

Related Questions