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().projection
とd3.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()
これも丸められているので、おそらく書き直す必要があることに注意してください)
あなたは毎日何かを学んでいますよね。