Thursday, 16 March 2017

shapefile - How to create a GeoJSON that works with D3?


I'm simply trying to convert a .shp file to a geoJSON format using:


ogr2ogr -f geoJSON output.json input.shp


After executing the command nothing seems to be wrong. Here's an excerpt from the output.json


    {
"type": "FeatureCollection",

"features": [
{ "type": "Feature",
"properties": { "ID_0": 86, "ISO": "DEU", "NAME_0": "Germany", "ID_1": 1, "NAME_1": "Baden-Württemberg", "NL_NAME_1": null, "VARNAME_1": null, "TYPE_1": "Land", "ENGTYPE_1": "State" },
"geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ 8.708400940398242, 47.715581894910606 ], [ 8.713716147005524, 47.701734382960055 ],
...


But when i try to use de JSON file in d3 (http://d3js.org/) to draw SVG polygons the output is just wrong. Since the shp files are displayed correctly in QGIS I think there has to be something wrong with the way i use ogr2ogr. The SVG I get is not completely wrong but there seems to be a detail I can't find. It seems like it has been turned upside down and somehow distorted into two separated parts.


Here's the javaScript i used to generate the svg:


//dimensions
var w = 2000;
var h = 2000;

var svg = d3.select("#chart").append("svg")
.attr("width", w)
.attr("height", h);


d3.json(
"http://localhost:8888/data/data.json",
function (json) {

var path = d3.geo.path();

svg.append("g")
.attr("class", "black")
.selectAll("path")

.data(json.features)
.enter()
.append("path")
.attr("d", path);

Does anyone have an idea what went wrong here? I also tried to convert the shp-file using Qgis and myGeodata (http://converter.mygeodata.eu/vector). But neither of them work the way they should.


I'm very new to this whole cartography stuff. So I would be very happy to get some advice.


Thanks very much!



Answer



OK, playing around with different projections, scales and translations in d3 solved my problem. Since the default projection when using d3.geo.path() is albersUsa there was good reason to try some other projections. I suppose the problem could have been solved easier using the right EPSG specification when converting the shape file but these obscure numbers exceeded my knowledge.



So what I did in the end is simply using a mercator projection and bringing it into the svg-viewport with translate().


   d3.json(
"http://localhost:8888/data/data.json",
function (json) {

//dimensions
var w = 2000;
var h = 2000;

var svg = d3.select("#chart").append("svg")

.attr("width", w)
.attr("height", h);

//create geo.path object, set the projection to merator bring it to the svg-viewport
var path = d3.geo.path()
.projection(d3.geo.mercator()
.scale(20000)
.translate([0, 3800]));

//draw svg lines of the boundries

svg.append("g")
.attr("class", "black")
.selectAll("path")
.data(json.features)
.enter()
.append("path")
.attr("d", path);
});

Here's a link to the shape files i used and the resulting geoJSON. To simplify the shapefiles, which I got from GADM, I used mapshaper.



I would still be interested in a less laborious and more flexible solution. So if anyone has an Idea, thanks in advance! But for the moment I'm happy I can recognize the 16 Bundesländer of Germany!


No comments:

Post a Comment

arcpy - Changing output name when exporting data driven pages to JPG?

Is there a way to save the output JPG, changing the output file name to the page name, instead of page number? I mean changing the script fo...