2016-07-26 5 views
0

D3オーバレイを使用して、Leafletマップ上のパスを、Leaflet.D3SvgOverlayユーティリティライブラリ経由で描画しようとしています。D3の選択によって、完全に重複しないラインプロットが発生します---どうすれば修正できますか?

私はmplleafletをPythonで使って書いたルーティング関数の出力を調べ、非常にきれいな出力(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

私の質問は次のとおりです。どこで私は物事を台無しにした、どうすれば修正できますか?

答えて

2

ここでは主に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" 
       }) 
    } 

より良い解決策は、あなたのD3 data要素としてlatLngToLayerPointから返されたデータを使用することであってもよいです。これにより、高解像度にズームインするときにラインを更新することができます。私はこれを実装するためにあなたを残します。

ズーム時に一定の線幅を維持するには、「ベクトル効果」:「非スケーリングストローク」を使用できます。ストローク幅の変更に注意してください。これはほとんど私がCSSに引き出すものです。

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

編集:パフォーマンスに関するコメントは無視してください。行を削除して再適用しなくても(つまり、最初の行をそのまま残していても)、地図をスクロールしても少し遅れているようです。これはおそらくリーフレット側の問題です。

EDIT2:

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

       }); 
      } 
+0

アメージング:私はpaintPathへの2回目の呼び出しを削除するpaintPathSamplerをも変更したことに注意してください!私はあなたがこの答えに再び戻ることに気にしないことを願っています。この例は私に、最終的に外に出て、d3 *の実際の作業における選択とデータバインディングの仕方を学ぶ動機を与えてくれます。 再描画/更新メソッドを実装する際、D3にラインを同じズーム/ズームレベルに保つように頼むのは簡単でしょうか? –

+1

これを実現するために '' vector-effect ': "non-scaling-stroke"を行属性に追加することができます。 IEでは動作しません。 –

+0

はい、D3の選択とデータバインディングの仕組みを学ぶ価値があります。クリックするのに時間がかかることがありますが、一度やり直すと非常に便利です。 –

関連する問題