6

Mike Bostock の元の D3 + Leaflet の例: http://bost.ocks.org/mike/leaflet/を採用 して、Leaflet のズームごとにすべてのパスを再描画しないようにしました。

コードはこちら: https://github.com/madeincluj/Leaflet.D3/blob/master/js/leaflet.d3.js

具体的には、地理座標からピクセルへの投影は次の場所で行われます: https://github.com/madeincluj/Leaflet.D3/blob/master/js/leaflet.d3.js#L30-L35

最初の読み込みで SVG パスを描画し、マップに合わせて SVG を単純にスケーリング/変換します。

これは、1 つの問題を除いて非常にうまく機能します。D3 のパスのリサンプリングは、最初のズーム レベルでは見栄えがしますが、ズームインを開始すると徐々に壊れて見えます。

リサンプリングを無効にする方法はありますか?

これを行っている理由について:多くの図形 (数千) を描画したいのですが、ズームごとにすべてを再描画するのは非現実的です。

編集 掘り下げた後、ここでリサンプリングが行われているようです:

function d3_geo_pathProjectStream(project) {
   var resample = d3_geo_resample(function(x, y) {
     return project([ x * d3_degrees, y * d3_degrees ]);
   });
  return function(stream) {
    return d3_geo_projectionRadians(resample(stream));
  };
}

リサンプリング手順をスキップする方法はありますか?

編集 2

何という赤いニシン!生の関数の送信d3.geo.path().projectiond3.geo.transformオブジェクトの送信を行ったり来たりしましたが、役に立ちませんでした。

しかし、実際には問題は、latLngToLayerPoint(明らかに!) point.x & point.y を整数に丸めるリーフレットの にあります。つまり、SVG レンダリングを初期化するときにズームアウトすればするほど、精度が失われます。

解決策は、次のようなカスタム関数を使用することです。

function latLngToPoint(latlng) {
  return map.project(latlng)._subtract(map.getPixelOrigin());
};

var t = d3.geo.transform({
    point: function(x, y) {
      var point = latLngToPoint(new L.LatLng(y, x));
      return this.stream.point(point.x, point.y);
    }
  });

this.path = d3.geo.path().projection(t);

リーフレット独自のものに似てlatLngToLayerPointいますが、丸めはありません。(map.getPixelOrigin()これも丸められているので、おそらく書き直す必要があることに注意してください)

あなたは毎日何かを学んでいますよね。

4

1 に答える 1

4

偶然にも、最近チュートリアルを更新して、新しいd3.geo.transform機能を使用するようにしました。これにより、カスタムの幾何学的変換を簡単に実装できます。この場合、変換は、D3 の高度な地図作成機能を一切使用せずに Leaflet の組み込み投影法を使用するため、適応リサンプリングが無効になります。

新しい実装は次のようになります。

var transform = d3.geo.transform({point: projectPoint}),
    path = d3.geo.path().projection(transform);

function projectPoint(x, y) {
  var point = map.latLngToLayerPoint(new L.LatLng(y, x));
  this.stream.point(point.x, point.y);
}

以前と同様に、生の射影関数を d3.geo.path に引き続き渡すことができますが、適応型リサンプリングと逆子午線切断が自動的に行われます。したがって、これらの機能を無効にするには、カスタム プロジェクションを定義する必要があります。d3.geo.transform は、単純な点ベースの変換でこれを行う簡単な方法です。

于 2013-11-01T00:12:02.737 に答える