Istnieją co najmniej dwie dobre metody grupowania dla PostGIS: k- oznacza (poprzez kmeans-postgresql
rozszerzenie) lub geometrie grupowania w odległości progowej (PostGIS 2.2)
1) k- oznacza zkmeans-postgresql
Instalacja: Musisz mieć PostgreSQL 8.4 lub nowszy na systemie hosta POSIX (nie wiedziałbym od czego zacząć dla MS Windows). Jeśli masz to zainstalowane z pakietów, upewnij się, że masz również pakiety programistyczne (np. postgresql-devel
Dla CentOS). Pobierz i rozpakuj:
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/
Przed budowaniem musisz ustawić USE_PGXS
zmienną środowiskową (mój poprzedni post polecił usunąć tę część Makefile
, która nie była najlepsza z opcji). Jedno z tych dwóch poleceń powinno działać dla twojej powłoki Unix:
# bash
export USE_PGXS=1
# csh
setenv USE_PGXS 1
Teraz skompiluj i zainstaluj rozszerzenie:
make
make install
psql -f /usr/share/pgsql/contrib/kmeans.sql -U postgres -D postgis
(Uwaga: próbowałem tego również z Ubuntu 10.10, ale bez powodzenia, ponieważ ścieżka pg_config --pgxs
nie istnieje! To prawdopodobnie błąd pakowania Ubuntu)
Zastosowanie / przykład: Powinieneś gdzieś mieć tabelę punktów (narysowałem kilka pseudolosowych punktów w QGIS). Oto przykład tego, co zrobiłem:
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
, że znajduje się w drugim argumencie kmeans
funkcji okna jest K całkowitą produkować pięciu klastrów. Możesz zmienić to na dowolną liczbę całkowitą, którą chcesz.
Poniżej znajduje się 31 pseudolosowych punktów, które narysowałem i pięć centroidów z etykietą pokazującą liczbę w każdej grupie. Zostało to utworzone przy użyciu powyższego zapytania SQL.
Możesz także spróbować zilustrować położenie tych klastrów za pomocą ST_MinimumBoundingCircle :
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) Grupowanie w odległości progowej za pomocą ST_ClusterWithin
Ta funkcja agregująca jest zawarta w PostGIS 2.2 i zwraca tablicę GeometryCollections, w której wszystkie komponenty znajdują się w pewnej odległości od siebie.
Oto przykład zastosowania, w którym odległość 100,0 to próg, który daje 5 różnych klastrów:
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;
Największa środkowa gromada ma promień otaczającego okręgu wynoszący 65,3 jednostki lub około 130, czyli więcej niż próg. Wynika to z faktu, że indywidualne odległości między geometriami prętów są mniejsze niż próg, więc wiąże je razem jako jedna większa gromada.