Jak stworzyć GeoJSON współpracujący z D3?

17

Po prostu próbuję przekonwertować plik .shp do formatu geoJSON, używając:

ogr2ogr -f geoJSON output.json input.shp

Po wykonaniu polecenia nic nie wydaje się błędne. Oto fragment pliku 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 ], 
...

Ale kiedy próbuję użyć pliku de JSON w d3 (http://d3js.org/) do narysowania wielokątów SVG, dane wyjściowe są po prostu błędne. Ponieważ pliki shp są poprawnie wyświetlane w QGIS, myślę, że musi być coś nie tak ze sposobem, w jaki korzystam ogr2ogr. Otrzymany plik SVG nie jest całkowicie błędny, ale wydaje się, że jest jakiś szczegół, którego nie mogę znaleźć. Wygląda na to, że został odwrócony do góry nogami i w jakiś sposób zniekształcony na dwie oddzielne części.

Oto javaScript, którego użyłem do wygenerowania pliku 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);

Czy ktoś ma pojęcie, co tu poszło nie tak? Próbowałem także przekonwertować plik shp przy użyciu Qgis i myGeodata (http://converter.mygeodata.eu/vector). Ale żadne z nich nie działa tak, jak powinno.

Jestem bardzo nowy w całej tej kartografii. Byłbym bardzo szczęśliwy, gdyby uzyskać porady.

Dziękuję bardzo!

Flavio
źródło

Odpowiedzi:

7

OK, bawienie się różnymi projekcjami, skalami i tłumaczeniami w d3 rozwiązało mój problem. Ponieważ domyślną projekcją przy użyciu d3.geo.path () jest albersUsa, istniał dobry powód, aby wypróbować inne projekcje. Przypuszczam, że problem można rozwiązać łatwiej przy użyciu właściwej specyfikacji EPSG podczas konwersji pliku kształtu, ale te niejasne liczby przekraczały moją wiedzę.

Więc w końcu to, co zrobiłem, to po prostu użycie projekcji mercatora i przeniesienie jej do rzutni svg za pomocą 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);
    });

Oto link do plików kształtów, których użyłem i wynikowego geoJSON. Aby uprościć pliki kształtu , które otrzymałem z GADM , użyłem mapshaper .

Nadal byłbym zainteresowany mniej pracochłonnym i elastycznym rozwiązaniem. Więc jeśli ktoś ma pomysł, z góry dziękuję! Ale na razie cieszę się, że mogę rozpoznać 16 niemieckich krajów związkowych!

Flavio
źródło
1
spatialreference.org to przydatna strona internetowa do projekcji i kodów EPSG.
dmci
5

próbowałeś podać poprawny kod EPSG dla swojego pliku shapefile i wyjścia GeoJSON? Na przykład:

ogr2ogr -f GeoJSON -s_srs EPSG:.... -t_srs EPSG:.... output.json input.shp

dmci
źródło
Prawdopodobnie jest problem. Nie sprecyzowałem niczego Głównie z powodu braku wiedzy. Ale znalazłem obejście mojego problemu. Wyślę to za minutę.
Flavio,
3

Masz rację, w przypadku mapy Niemiec musisz zmienić domyślną projekcję, tak aby pasowała do danych z USA. Jest wyśrodkowany gdzieś w Kansas i dla mapy o rozmiarze 960 x coś.

Właściwe parametry oczywiście zależą również od wymiarów mapy.

Jeśli chcesz użyć projekcji d3.geo.albers (najlepiej dla map Coropleth ), oto moje parametry:

var w = 415;
var h = 555;

var albers = d3.geo.albers()
    .origin([11, 51])
    .parallels([49, 53])
    .translate([230, 290])
    .scale(4000);

var path = d3.geo.path().projection(albers);
ahinrichs
źródło