2017-06-14 5 views
1

Ich baue eine Straßenkarte für eine Stadt namens Shenzhen in China. Ich habe den Datensatz von mapzen.com und konvertiere die Shape-Datei in JSON-Datei mit Topojson-Kommandozeile (topojson -o -p).d3.js - D3 Karte nicht mit China Stadtdatensatz

Hier meine JSON-Datei ist: https://raw.githubusercontent.com/MandyZou/Mandy-Web/gh-pages/ShenzhenMap/shenzhenroads.json

Hier ist mein Code:

<!DOCTYPE html> 
<head> 
<title>Shenzhen Map</title> 
<script src="https://d3js.org/d3.v4.min.js"></script> 
<script src="https://d3js.org/d3-selection-multi.v1.min.js"></script> 


<script src="https://unpkg.com/[email protected]"></script> 
</head> 

<body> 
<svg id="map" width ="500" height = "960"></svg> 

<script> 
    var margin = {top: 20, left: 20, right: 20, bottom: 20}, 
     width = 500 - margin.left - margin.right, 
     height = 960 - margin.top - margin.bottom; 

    var svg = d3.select("#map") 
       .append("svg") 
       .attr("width", width + margin.left + margin.right) 
       .attr("height", height + margin.top + margin.bottom) 
       .append("g") 
       .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); 

    d3.queue() 
     .defer(d3.json, "shenzhenroads.json") 
     .await(ready); 

    function ready(error, data){ 
     if (error) throw error; 

     console.log(data) 

     var ShenzhenRoads = topojson.feature(data, { 
      type: "GeometryCollection", 
      geometries: data.objects.shenzhen_china_osm_roads.geometries 
     }); 

     var projection = d3.geoMercator().center([23, 114]).scale(100).translate([width/2, height/2]); 

     var path = d3.geoPath() 
      .projection(projection); 

     svg.select("g") 
      .selectAll("path") 
      .data(ShenzhenRoads.features) 
      .enter().append("path") 
       .attr("class", "roads") 
       .attr("d", path) 
       .attr("fill", "#C5C5C5"); 
    }; 

</script> 
</body> 
</html> 

ich es denke ich, hier verwendet, um die Projektion zurückzuführen könnte ... Ich habe versucht d3.geoMercator, d3.geoTransverseMercator und d3.geoEquirectangular, aber keine von ihnen funktioniert ...

Kann mir jemand sagen, was ist los mit meiner Karte und wie soll ich es beheben? Danke im Voraus!!

Antwort

0

Sie müssen zwei Elemente ansprechen, um Ihre Funktionen zu sehen.

1. svg.select("g") wählt kein Element aus.

Wenn Sie die Variable svg definieren benutzen Sie:

var svg = d3.select("#map") 
    .append("svg") 
    .attr("width", width + margin.left + margin.right) 
    .attr("height", height + margin.top + margin.bottom) 
    .append("g") 
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); 

Dies wird wieder eine Auswahl mit dem g Element, nicht das svg Element. Zum Beispiel versuchen:

console.log(svg.node()); // <g transform="translate(20,20)"> 

Stattdessen benutzen Sie einfach:

svg.selectAll("path").data(....

2. Koordinaten für .center, .rotate und im allgemeinen in d3 [x, y].

Sie benötigen Koordinaten hier tauschen:

var projection = d3.geoMercator().center([23, 114])... 

An:

var projection = d3.geoMercator().center([114, 23])... 
  1. topojson.feature GeoJSON zurückkehrt,

Sie können diese Aussage vereinfachen:

var ShenzhenRoads = topojson.feature(data, { 
     type: "GeometryCollection", 
     geometries: data.objects.shenzhen_china_osm_roads.geometries 
    }); 

zu:

var ShenzhenRoads = topojson.feature(data, data.objects.shenzhen_china_osm_roads); 

Ergebnis

Ihr Zoomfaktor ist viel zu klein, noch Ihre Daten unsichtbar sein können (obwohl es in dem DOM sein soll), ein Skalierungsfaktor von 200 000 könnte angemessener sein.

Zweitens verwenden Sie .attr("fill","color") für Ihre Pfade, wahrscheinlich möchten Sie nicht die Pfade füllen, da dies sie wie Polygone mit einem langen geraden Abschnitt zwischen den ersten und letzten Punkten aussehen wird.Stattdessen versuchen:

  .attr("fill", "none") 
      .attr("stroke","steelblue"); 

Ihre Daten verwenden und die folgende Projektion (zugegebenermaßen zu weit gezoomt):

var projection = d3.geoMercator() 
.center([114, 22.5]) 
.scale(500000) 
.translate([width/2, height/2]); 

bekam ich dieses Bild:

enter image description here

Hier ist ein gist/block (Ich habe queue.js nicht verwendet, stattdessen habe ich d3.json verwendet). Dieser Datensatz ist atypisch groß für d3 - es könnte sich lohnen, in Vektorkacheln (oder Rasterkacheln) zu suchen.

+0

Hallo @AndrewReid! Vielen Dank für Ihre ausführliche Erklärung! Ich habe jedoch meinen Code geändert, aber immer noch ist nichts passiert. Kannst du deinen Code mit mir teilen, damit ich meinen Vergleich überprüfen kann? Übrigens, hier ist mein aktuelles Skript: https://github.com/MandyZou/Mandy-Web/blob/gh-pages/ShenzenMap/shenzhen.html Danke! –

+0

Ah, ich muss die Änderungen verpasst haben, die ich gemacht habe, als ich den Topojson in Geojson konvertiert habe - ich habe die Antwort aktualisiert, und alles sollte jetzt im bl.ock/gist-Beispiel am Ende der Antwort sichtbar sein. –

+0

Vielen Dank !! Deine Antwort hilft mir auch bei meinen anderen Problemen! Ich schätze das wirklich! –