12

リーフレットとd3でマップを作成しています。地図上にたくさんの円がプロットされます。ブラウザーの互換性に関しては、ブラウザーがレンダリングできる svg 要素の数に予想される制限があります。ただし、ユーザー エクスペリエンスの観点からは、ユーザーがマップ上でできるだけ多くの要素を表示できるようにすることをお勧めします (そうしないと、ユーザーは常にズームインおよびズームアウトする必要があり、ajax がデータを返すのを待つ必要がある場合があります)。検討する必要があるいくつかの最適化があります (ユーザーの待機時間、ユーザー、サーバーのクエリ負荷、ブラウザーが処理できるもの)。

プロットを参照してください。現在、サーバーが返すポイントの数には制限があるため、マップの一部しか塗りつぶされていません。

ここに画像の説明を入力

ブラウザはここで完全に塗りつぶされたマップを処理できず、ユーザーはサーバーの応答も長時間待つ必要があります。

私が直面している問題は、次の 2 つの質問に答えて解決する必要があると思います。

  • マップ上の単純な svg 形状 (円) の数に関して、平均的なブラウザーが処理できる基準はありますか?
  • マップ上にできるだけ多くの図形を表示するための最適な手法は何ですか?

次の点を検討していますが、役立つかどうかはわかりません。

  • 丸の代わりに四角を使う
  • D3 の代わりにリーフレット API を使用する
4

5 に答える 5

5

(サイズ、グラデーション塗りつぶしの使用などに応じて) 顕著な速度低下が見られるようになる前に、最大 2 ~ 5k の SVG 要素しかレンダリングできませんが、はるかに大きなデータセットをクライアント側で保存および操作できます。多くの場合、SVG では数万または数十万のデータ ポイントを効率的に処理できます。秘訣は、実際にレンダリングするものを非常に厳選し、デバウンスなどの手法を使用して必要な場合にのみ再描画することです。

(非常に大きなデータセットの場合: はい、ポイントを集約/サブサンプリングするか、事前にレンダリングする必要があります。)

これを念頭に置いて、特に d3 マップに使用した 1 つの手法はd3.geom.quadtree()、ユーザーがパン/ズームするときにポイントを動的にカリングするために使用することです。より具体的には、次のいずれかの点を描画することは避けます。

  1. 現在のマップ境界ボックスの外側 (これらはまったく表示されないため)、または
  2. 他のポイントに近すぎる(これらは視覚的な混乱を招き、とにかく操作が難しいため).

JS っぽい疑似コードでは、これはおおよそ次のようになります。

function getIndicesToDraw(data, r, bbox) {
  var indicesToDraw = [];
  var Q = d3.geom.quadtree();
  // set bounds in pixel space
  for (var i = 0; i < data.length; i++) {
    var d = data[i];
    var p = getPointForDatum(d);
    if (isInsideBoundingBox(bbox, p) && !hasPointWithinRadius(Q, r, p)) {
      Q.add(p); 
      indicesToDraw.push(i);
    }
  }
  return indicesToDraw;
}

function redraw(svg, data, r, bbox) {
  var indicesToDraw = getIndicesToDraw(data, r, bbox);
  var points = svg.selectAll('.data-point')
    .data(indicesToDraw, function(i) { return i; });

  // draw new points for points.enter()

  points.exit().remove();

  // update positions of points (or SVG transforms, etc.)
}
于 2016-04-04T18:44:44.877 に答える
4

これは技術の問題であると同時に、地図作成の問題でもあります。マップ上に何千ものポイントを配置できるからといって、そうすべきであるとは限りません。ユーザーが一度にできるだけ多くのポイントを表示する必要があるかどうかを自問する必要があります。そうすることで、データをよりよく理解できます。これほど多くのポイントを見ると、ユーザーは混乱して圧倒されますか? それとも、ユーザーが目的のタスクを達成するのに役立ちますか? すべてのポイントを一度に描画する必要がないように、データをフィルタリングする方法はありますか?

この問題の最も一般的な解決策は、クラスターを使用することです。通常は、Leaflet MarkerClusterのようなものを使用します。過去に D3 と Leaflet を使用しているときに、任意のグリッドを作成し、各ポイントをビンに割り当て、グリッドにカラー ランプを適用して、一種のヒート マップを作成しました。ただし、元の懸念に戻ると、かなり計算集約的です。

サポートするプラットフォームによっては、携帯電話やタブレットで SVG を適切に処理できるとは限らないことに注意してください。特に、何千ものフィーチャを描画する場合は注意が必要です。

潜在的なパフォーマンス向上の別の場所は、ポイント ジオメトリの配信です。現在それらをどのようにロードしているかはわかりませんが、空間的にインデックス付けされた PostGIS テーブルを使用し、バウンディング ボックスで選択することは、多くの場合非常に高速ですが、ポリゴンではなくポイントを描画しているため、それらをブラウザにロードすることさえできます。 GeoJSON または Topojson よりも大幅に小さい CSV 経由。

于 2013-09-18T01:15:09.403 に答える
1

すべてのデータを一度にロードしますが、十分な大きさの円のみをビュー ポートに描画します。ズームまたはパンで、表示されるべきではない円を削除し、以前に非表示の円を追加する必要があるかどうかを確認します。

于 2013-09-09T16:20:49.563 に答える