Como criar um GeoJSON que funciona com o D3?

17

Estou simplesmente tentando converter um arquivo .shp em um formato geoJSON usando:

ogr2ogr -f geoJSON output.json input.shp

Depois de executar o comando, nada parece estar errado. Aqui está um trecho do 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 ], 
...

Mas quando tento usar o arquivo JSON no d3 (http://d3js.org/) para desenhar polígonos SVG, a saída está errada. Como os arquivos shp são exibidos corretamente no QGIS, acho que deve haver algo errado com o modo como uso ogr2ogr. O SVG que recebo não está completamente errado, mas parece haver um detalhe que não consigo encontrar. Parece que foi virado de cabeça para baixo e de alguma forma distorcido em duas partes separadas.

Aqui está o javaScript que eu usei para gerar o 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);

Alguém tem uma idéia do que deu errado aqui? Também tentei converter o arquivo shp usando o Qgis e o myGeodata (http://converter.mygeodata.eu/vector). Mas nenhum deles funciona da maneira que deveria.

Sou muito novo em todo esse material de cartografia. Então, eu ficaria muito feliz em receber alguns conselhos.

Muito obrigado!

Flavio
fonte

Respostas:

7

OK, brincar com diferentes projeções, escalas e traduções no d3 resolveu meu problema. Como a projeção padrão ao usar o d3.geo.path () é albersUsa, houve um bom motivo para tentar outras projeções. Suponho que o problema poderia ter sido resolvido mais facilmente usando a especificação EPSG correta ao converter o arquivo de formas, mas esses números obscuros excederam meu conhecimento.

Então o que fiz no final foi simplesmente usar uma projeção mercator e trazê-la para o svg-viewport com o 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);
    });

Aqui está um link para os arquivos de forma que usei e o geoJSON resultante. Para simplificar os shapefiles, que obtive do GADM , usei o mapshaper .

Eu ainda estaria interessado em uma solução menos trabalhosa e mais flexível. Então, se alguém tiver uma ideia, agradeço desde já! Mas, por enquanto, estou feliz por reconhecer os 16 Bundesländer da Alemanha!

Flavio
fonte
1
spatialreference.org é um site útil para projeções e códigos EPSG.
Dmci
5

você tentou especificar o código EPSG correto para o seu shapefile e saída GeoJSON? Por exemplo:

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

dmci
fonte
Provavelmente existe o problema. Eu não especifiquei nada Principalmente por falta de conhecimento. Mas eu encontrei uma solução alternativa para o meu problema. Vou postar em um minuto.
Flavio
3

Você está certo, para um mapa da alemanha você precisa alterar a projeção padrão conforme ela se ajusta aos dados dos EUA. Está centralizado em algum lugar do Kansas e para um mapa de tamanho 960xalgo.

Obviamente, os parâmetros corretos também dependem das dimensões do seu mapa.

Se você deseja usar a projeção d3.geo.albers (melhor para mapas de coropleth ), aqui estão meus parâmetros:

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
fonte