このクラスタリングの目的は、ポイントシンボルの表示を簡略化することです。多くのものがマップ上で接近している場合、それらは単一のシンボルに置き換えられてグループを示します。
要件は、シンプルで適応性のあるソリューションの必要性を示しています。ポイントシンボルは更新でき、ユーザーがズームインすると、マップ(または画面)の範囲の異なる場所に異なるシンボルが表示されます。
優れた候補は明らかに地域四分木です。
領域四分木のように機能する、より簡単な方法があります。コーディングが少なくて済み、データ構造を事前に作成する必要はありませんが、ズームやパン中にオンザフライで計算を実行する必要があるため、(小さな)価格を支払う必要があります。 地図をグリッド表示するだけです。具体的には、マップの現在の範囲内に描画されるポイントシンボルがn個あり、長さがdxで高さがdyであるとします。地図の原点を基準にして、シンボルは座標(x [i]、y [i])、i = 1、2、...、nに描画する必要があります。cのグリッドセルサイズを選択すると、マップがセルのグリッドに分割されます。場所(x、y)は行j(y)= Floor [ y / c ]と列j(x)に属します(0から数え、行は下から上へ、列は左から右へ)。 2つ以上のポイントを受信するセルを「クラスター」と見なすことができます。 クラスターシンボルは、座標を持つセルの中心に描画できます。(j + c / 2、k + c / 2)。
これにより、疑似コードで表される次のソリューションが導き出されます。
m = Floor(dy/c)+1
n = Floor(dx/c)+1
Dimension a[m,n] = 0
For each (x[i], y[i]) to be displayed:
Increment( a[ j(y[i]), j(x[i]) ] )
End for
For each (x[i], y[i]) to be displayed:
row = j(y[i])
col = j(x[i])
If a[row, col] > 1:
Draw a symbol for a cluster of k points at (c*(col+0.5), c*(row+0.5))
a[row, col] = 0
Else
Draw a point symbol at (x[i], y[i])
End if
End for
明らかに、アルゴリズムの計算負荷は、時間ではO(ポイント数)、ストレージではO(dx * dy / c ^ 2)です。 セルサイズcの選択に伴うトレードオフは次のとおりです。
Cできるだけ大きくする必要があります:ストレージはに反比例するC ^ 2:の値が小さいC RAMの平均大量。(スパース配列または辞書を使用することで、ストレージをO(ポイント数)に減らすことができます。)
cは可能な限り大きくする必要があります。2つのシンボル(ポイントまたはクラスター)がc / 2 よりも近くなることはありません。
cはできるだけ小さくする必要があります。すべてのクラスターシンボルは、それからc / sqrt(2)以下の場所を表します。
cはできるだけ小さくする必要があります。cの値が大きいと、多くのクラスターが作成され、個々の点がほとんど表示されなくなります。
(4)を簡単に分析してみましょう。出発点として、マッピングされる場所がランダムに均一に発生し、互いに独立していると仮定します。セルの数はN(c)=(Floor(dx / c)+1)*(Floor(dy / c)+1)であり、少なくともcの値が大きい場合はcに正比例します ^ 2。細胞数の分布は、強度ラムダ = n / N(c)= n * c ^ 2 /(dx * dyのポアソンの法則にほぼ従います。)。予想されるクラスター数は
e(c)= n(1-exp(-lambda)(1 + lambda))。
これは、ラムダが0に縮小するにつれて小さくなります。つまり、セルサイズcは次第に小さくなります。この分析の要点は、前の式ではクラスターの数を予測できるため、e(c)が許容値を下回る初期値cを選択できます(RAMを制限するのに十分な大きさのまま)要件)。閉じた形のソリューションはありませんが、いくつかのニュートンラフソンのステップは1つに急速に収束します。
このアプローチは非常に動的です-グリッドとそれに続くクラスタリングがズームとパンごとに計算できるほど高速であり、事前に計算されたデータ構造を必要としません-データが更新されるときに必要な「増分変更」が自動的に行われます。