2017-06-14 136 views
1

我正在爲中國深圳的城市建立路線圖。我從mapzen.com獲得數據集並使用topojson命令行(topojson -o -p)將形狀文件轉換爲JSON文件。d3.js - D3地圖不會顯示在中國城市數據集中

這裏是我的JSON文件:https://raw.githubusercontent.com/MandyZou/Mandy-Web/gh-pages/ShenzhenMap/shenzhenroads.json

這裏是我的代碼:

<!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> 

我想這可能是由於我在這裏使用的投影......我試過d3.geoMercator,d3.geoTransverseMercator ,和d3.geoEquirectangular,但他們都沒有工作...

有人可以告訴我我的地圖有什麼問題,我該如何解決它?提前致謝!!

回答

0

您需要解決兩個項目以查看您的功能。

1. svg.select("g")不選擇任何元素。

當你定義變量SVG使用:

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 + ")"); 

這將返回一個選擇與g元素,而不是svg元素。例如嘗試:

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

相反,只需使用:

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

2. .center,.rotate座標和一般在D3爲[X,Y]。

這裏需要交換你的座標:

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

要:

var projection = d3.geoMercator().center([114, 23])... 
  • topojson.feature返回GeoJSON的,
  • 您可以簡化此聲明:
    var ShenzhenRoads = topojson.feature(data, { 
         type: "GeometryCollection", 
         geometries: data.objects.shenzhen_china_osm_roads.geometries 
        }); 
    

    到:

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

    加細

    你的變焦倍數的方式小,你的數據可能仍是不可見的(儘管它應該是在DOM),比例因子20萬可能更合適。

    其次,你正在使用.attr("fill","color")作爲你的路徑,你可能不想填充路徑,因爲這樣會使它們看起來像多邊形,連接第一個和最後一個點的長直線部分。相反,嘗試:

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

    使用您的數據和下面的投影(在太遠誠然縮放):

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

    我得到這個圖片:

    enter image description here

    這裏是一個gist/block (我沒有使用queue.js,而是使用d3.json),使用你的數據集。這是數據集對d3非常大 - 可能值得查看矢量圖塊(或光柵圖塊)。

    +0

    嗨@AndrewReid!非常感謝您的詳細解釋!但是,我更改了代碼,但仍然沒有發生任何事情。你可以與我分享你的代碼,以便我可以交叉檢查我的嗎?順便說一句,這裏是我更新的腳本:https://github.com/MandyZou/Mandy-Web/blob/gh-pages/ShenzhenMap/shenzhen.html謝謝! –

    +0

    啊,我必須錯過我在將topojson轉換爲geojson時所做的修改 - 我已經更新了答案,並且現在應該在bl.ock/gist示例中顯示所有內容。 –

    +0

    非常感謝!您的回答也可以幫助我解決其他問題!對此,我真的非常感激! –