2016-07-26 14 views
0

我正在嘗試使用D3覆蓋圖通過Leaflet.D3SvgOverlay實用程序庫在Leaflet地圖上繪製路徑。D3選擇導致難以理解的重疊線圖---我該如何解決它?

我檢查了我在Python中使用mplleaflet編寫的路由函數的輸出,得到了非常整潔的輸出(responsible block)。

我寫了一個D3事情應該得到相同的輸出。不過,我不是有一個非常鋸齒線,其中,仔細目測檢查,竟然是幾行以一種不可思議的方式交織在一起:

enter image description here

改變陰謀界的一個替代的路徑顯示這是由於某種奇怪的排列的點:

enter image description here

您可以嘗試自己in this block負責的代碼。

然而,在這兩種情況下(在mplleaflet情節的作品和D3地塊不)我只是想要繪製完全相同的一系列座標:

[[-73.98208, 40.76529], [-73.98225, 40.76476], [-73.98232, 40.76457], [-73.98238, 40.76441], [-73.98239, 40.76438], [-73.98241, 40.76434], [-73.98245, 40.76423], [-73.98249, 40.76412], [-73.98252, 40.76405], [-73.98254, 40.76402], [-73.98257, 40.76396], [-73.98281, 40.76351], [-73.98288, 40.76339], [-73.98293, 40.7633], [-73.983, 40.76318], [-73.98321, 40.76282], [-73.98326, 40.76273], [-73.98332, 40.76264], [-73.9836, 40.76219], [-73.98368, 40.76207], [-73.98387, 40.76178], [-73.98411, 40.76145], [-73.98452, 40.7608], [-73.98456, 40.76072], [-73.98465, 40.76052], [-73.98487, 40.76013], [-73.98487, 40.76013], [-73.98453, 40.75999], [-73.98418, 40.75984], [-73.98418, 40.75984], [-73.98441, 40.75952], [-73.98461, 40.7592], [-73.98507, 40.75858], [-73.98526, 40.75833], [-73.98553, 40.75796], [-73.98568, 40.75778], [-73.986, 40.75734], [-73.98648, 40.7567], [-73.98695, 40.75603], [-73.98695, 40.75603], [-73.98644, 40.75582], [-73.98644, 40.75582], [-73.98668, 40.75505], [-73.98691, 40.75434], [-73.98713, 40.75362], [-73.98723, 40.75332], [-73.98732, 40.75303], [-73.98735, 40.75291], [-73.98754, 40.75218], [-73.98761, 40.75187], [-73.98762, 40.75183], [-73.98771, 40.75145], [-73.98774, 40.7512], [-73.98783, 40.7507], [-73.98789, 40.75036], [-73.98798, 40.74988], [-73.98804, 40.74968], [-73.98809, 40.74957], [-73.98814, 40.74948], [-73.9883, 40.74925], [-73.9883, 40.74924], [-73.98829, 40.74923], [-73.98819, 40.74919], [-73.98804, 40.74912], [-73.98802, 40.74912], [-73.98802, 40.74911], [-73.98801, 40.7491], [-73.98803, 40.749], [-73.98805, 40.74898], [-73.98807, 40.74896], [-73.98808, 40.74894], [-73.9881, 40.74881], [-73.98812, 40.74869], [-73.98813, 40.74863], [-73.98814, 40.74858], [-73.98817, 40.74845], [-73.9882, 40.74831], [-73.98824, 40.74811], [-73.98836, 40.74754], [-73.98839, 40.74735], [-73.98841, 40.74721], [-73.98843, 40.74713], [-73.98844, 40.74707], [-73.98849, 40.74679], [-73.98858, 40.74604], [-73.98867, 40.74582], [-73.98872, 40.74559], [-73.98877, 40.7453], [-73.9889, 40.74455], [-73.98894, 40.74435], [-73.98899, 40.74412], [-73.98903, 40.74392], [-73.98904, 40.7438], [-73.98905, 40.74368], [-73.98911, 40.74337], [-73.98915, 40.74316], [-73.98917, 40.74303], [-73.98919, 40.74294], [-73.98924, 40.74261], [-73.98924, 40.74257], [-73.98924, 40.74253], [-73.98923, 40.74252], [-73.98922, 40.7425], [-73.98902, 40.74231], [-73.98902, 40.74231], [-73.98906, 40.74225], [-73.98931, 40.7419], [-73.9894, 40.7418], [-73.98959, 40.74155], [-73.9901, 40.74087], [-73.99053, 40.74025], [-73.99096, 40.73967], [-73.99139, 40.73908], [-73.99181, 40.73849], [-73.99222, 40.73792], [-73.99267, 40.73732], [-73.99315, 40.73669], [-73.99347, 40.73624], [-73.99352, 40.73618], [-73.99363, 40.73602], [-73.99416, 40.7353], [-73.99459, 40.73467], [-73.99507, 40.73403], [-73.99552, 40.73344], [-73.99594, 40.73284], [-73.99638, 40.73225], [-73.99668, 40.73185], [-73.99698, 40.73141], [-73.99698, 40.73141], [-73.9971, 40.73147], [-73.9985, 40.73216], [-73.99863, 40.73222], [-73.99863, 40.73222], [-73.99873, 40.73211], [-73.99913, 40.73164], [-73.99962, 40.73105], [-73.99962, 40.73105], [-73.99886, 40.73067], [-73.99886, 40.73067], [-73.99903, 40.73046]] 

檢查的控制檯顯示D3地塊重新plopping彼此過來的頂線,指向某種錯誤在我的部分:

enter image description here

我的問題是:其中this code我是否搞砸了,我該如何解決?

回答

2

這裏有兩個主要問題。

首先,每次用戶放大時,都會在疊加元素上附加一行。這是多條線彼此重疊的原因。標準的d3方法只是在底層數據發生變化時更新畫布,因此更好的方法是僅在輸入新數據時更新路徑。注意使用的selectAllenter()方法:

// Paints a single sampler path. 
    function paintPath(linearray) { 

     // Define x and y conversions. 
     var line = d3.svg.line() 
       .x(function(d) { return proj.latLngToLayerPoint(d).x}) 
       .y(function(d) { return proj.latLngToLayerPoint(d).y}); 

     var updateSelection = sel.selectAll('path').data([linearray]); 
     updateSelection.enter() 
       .append("path") 
       .attr({ 
        "class": "sample-line", 
        "d": line, 
        "fill": "transparent", 
        "stroke": "steelblue", 
        "stroke-width": 0.1, 
        "shape-rendering": "crispEdges" 
       }) 
    } 

第二個問題是與latLngToPoint功能。從文檔,這個功能:

項目在特定的變焦地理座標爲像素 座標

當你縮小,映射到像素不是很精確的(因此參差不齊的行你看)。由於在用戶放大時不會刪除此線,因此附加的線會覆蓋此初始參差不齊的線,該線也會放大。在更接近的縮放級別下,映射到像素會更接近地反映真實座標,並且你會得到一條更好的線條。這解釋了你所看到的奇怪的鋸齒覆蓋。

這會產生一些問題,因爲只調用.enter()不會更新該行,因爲基礎數據沒有更改。一個簡單的解決方案(可能不是在性能方面完美)將每個用戶放大時間重繪行:

// Paints a single sampler path. 
    function paintPath(linearray) { 

     // Define x and y conversions. 
     var line = d3.svg.line() 
       .x(function(d) { return proj.latLngToLayerPoint(d).x}) 
       .y(function(d) { return proj.latLngToLayerPoint(d).y}); 

     sel.selectAll('path').remove(); 
     var updateSelection = sel.selectAll('path').data([linearray]); 
     updateSelection.enter() 
       .append("path") 
       .attr({ 
        "class": "sample-line", 
        "d": line, 
        "fill": "transparent", 
        "stroke": "steelblue", 
        "stroke-width": 0.1, 
        "shape-rendering": "crispEdges" 
       }) 
    } 

更好的解決辦法可能是使用數據從latLngToLayerPoint返回你的D3 data元素。這樣,您可以在放大到更高分辨率時更新線條。我會離開你來實現這一點。

爲了在縮放時保持恆定的線寬,可以使用「矢量效果」:「非縮放筆畫」。請注意筆劃寬度的變化。這幾乎是我要拉入CSS的東西。

.attr({ 
     "class": "sample-line", 
     "d": line, 
     "fill": "transparent", 
     "stroke": "steelblue", 
     "stroke-width": 1, 
     "shape-rendering": "crispEdges", 
     "vector-effect": "non-scaling-stroke" 
     }) 

編輯:忽略我對性能的評論。看起來,即使沒有刪除和重新顯示線條(即只保留第一條線),當您滾動地圖時仍然有點滯後。這可能是傳單方面的一個問題。

EDIT2:請注意,我也改變paintPathSampler刪除第二個呼叫paintPath

  // Paints all of the paths. 
      function paintPathSampler() { 
       d3.json("path_sampler.json", function (data) { 
        paintPath(data[0]); 
        // paintPath(data[1]); 
//      paintPointPath(data[0]); 

       }); 
      } 
+0

驚人!我希望你不介意我再次回到這個答案前進;這個例子給了我一個動機,最終出去學習如何選擇和數據綁定在d3 *真正*工作。 另外,在實現重繪/更新方法時,問D3讓行保持相同的每個縮放級別的寬度是否微不足道? –

+1

爲了達到這個目的,你可以在行屬性中加入''矢量效果「:」非縮放筆畫「。它在IE中不起作用。 –

+0

是的,值得學習D3的選擇和數據綁定如何工作。它可能需要一段時間才能點擊,但一旦它出現,它非常有用。 –

相關問題