PostGIS için en az iki iyi kümeleme yöntemi vardır: k-değeri ( kmeans-postgresql
uzatma yoluyla ) veya eşik uzaklıktaki kümeleme geometrileri (PostGIS 2.2)
1) k - ile demektirkmeans-postgresql
Kurulum: POSIX ana sisteminde PostgreSQL 8.4 veya daha üstü olması gerekir (MS Windows için nereden başlayacağımı bilemiyorum). Bunu paketlerden kurduysanız, geliştirme paketlerinin de olduğundan emin olun (örneğin, postgresql-devel
CentOS için). İndirin ve çıkarın:
wget http://api.pgxn.org/dist/kmeans/1.1.0/kmeans-1.1.0.zip
unzip kmeans-1.1.0.zip
cd kmeans-1.1.0/
İnşa etmeden önce, USE_PGXS
ortam değişkenini ayarlamanız gerekir (önceki yazımın bu bölümün silinmesi talimatı vardı Makefile
, bu seçeneklerin en iyisi değildi). Bu iki komuttan birinin Unix kabuğunuz için çalışması gerekir:
# bash
export USE_PGXS=1
# csh
setenv USE_PGXS 1
Şimdi uzantıyı derleyip kurun:
make
make install
psql -f /usr/share/pgsql/contrib/kmeans.sql -U postgres -D postgis
(Not: Bunu Ubuntu 10.10 ile de denedim, fakat yolu olmadığından şans pg_config --pgxs
yok! Bu muhtemelen bir Ubuntu paketleme hatasıdır)
Kullanım / Örnek: Bir yerde bir puan tablosuna sahip olmalısınız (QGIS'de bir grup sahte rastgele nokta çizdim). İşte yaptığım şeye bir örnek:
SELECT kmeans, count(*), ST_Centroid(ST_Collect(geom)) AS geom
FROM (
SELECT kmeans(ARRAY[ST_X(geom), ST_Y(geom)], 5) OVER (), geom
FROM rand_point
) AS ksub
GROUP BY kmeans
ORDER BY kmeans;
5
ikinci bağımsız değişken sağlanan bir kmeans
pencere fonksiyonu olan K beş kümelerinin üretilmesinde tamsayıdır. Bunu, istediğiniz tamsayı olarak değiştirebilirsiniz.
Aşağıda çizdiğim 31 sözde rastgele nokta ve her kümedeki sayımı gösteren etiketli beş centroid. Bu, yukarıdaki SQL sorgusu kullanılarak oluşturuldu.
Ayrıca, bu kümelerin nerede ST_MinimumBoundingCircle ile olduğunu göstermeye çalışabilirsiniz :
SELECT kmeans, ST_MinimumBoundingCircle(ST_Collect(geom)) AS circle
FROM (
SELECT kmeans(ARRAY[ST_X(geom), ST_Y(geom)], 5) OVER (), geom
FROM rand_point
) AS ksub
GROUP BY kmeans
ORDER BY kmeans;
2) Bir eşik mesafesi içinde kümeleme ST_ClusterWithin
Bu toplama işlevi PostGIS 2.2'ye dahil edilmiştir ve tüm bileşenlerin birbirinden uzakta olduğu bir GeometryCollections dizisi döndürür.
İşte 100.0'lık bir mesafenin 5 farklı kümeye neden olan eşik olduğu örnek bir kullanım:
SELECT row_number() over () AS id,
ST_NumGeometries(gc),
gc AS geom_collection,
ST_Centroid(gc) AS centroid,
ST_MinimumBoundingCircle(gc) AS circle,
sqrt(ST_Area(ST_MinimumBoundingCircle(gc)) / pi()) AS radius
FROM (
SELECT unnest(ST_ClusterWithin(geom, 100)) gc
FROM rand_point
) f;
En büyük orta küme, eşikten daha büyük olan 65.3 ünite veya yaklaşık 130'luk bir kapalı çember yarıçapına sahiptir. Bunun nedeni, üye geometrileri arasındaki bireysel mesafelerin eşikten daha az olmasıdır, bu nedenle onu bir büyük küme olarak birbirine bağlar.