Có ít nhất hai phương pháp phân cụm tốt cho PostGIS: k -means (thông qua kmeans-postgresql
tiện ích mở rộng) hoặc phân cụm hình học trong một khoảng cách ngưỡng (PostGIS 2.2)
1) k -means vớikmeans-postgresql
Cài đặt: Bạn cần phải có PostgreSQL 8.4 trở lên trên hệ thống máy chủ POSIX (Tôi không biết bắt đầu từ đâu cho MS Windows). Nếu bạn đã cài đặt gói này từ các gói, hãy đảm bảo bạn cũng có các gói phát triển (ví dụ: postgresql-devel
đối với CentOS). Tải xuống và giải né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/
Trước khi xây dựng, bạn cần đặt USE_PGXS
biến môi trường (bài viết trước của tôi đã hướng dẫn xóa phần này Makefile
, đây không phải là tùy chọn tốt nhất). Một trong hai lệnh này sẽ hoạt động cho shell Unix của bạn:
# bash
export USE_PGXS=1
# csh
setenv USE_PGXS 1
Bây giờ xây dựng và cài đặt tiện ích mở rộng:
make
make install
psql -f /usr/share/pgsql/contrib/kmeans.sql -U postgres -D postgis
(Lưu ý: Tôi cũng đã thử điều này với Ubuntu 10.10, nhưng không may mắn, vì đường dẫn trong pg_config --pgxs
không tồn tại! Đây có thể là một lỗi đóng gói Ubuntu)
Cách sử dụng / Ví dụ: Bạn nên có một bảng điểm ở đâu đó (Tôi đã vẽ một loạt các điểm ngẫu nhiên giả trong QGIS). Đây là một ví dụ với những gì tôi đã làm:
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;
đối số 5
tôi cung cấp trong đối số thứ hai của kmeans
hàm window là số nguyên K để tạo ra năm cụm. Bạn có thể thay đổi điều này thành bất kỳ số nguyên nào bạn muốn.
Dưới đây là 31 điểm ngẫu nhiên giả mà tôi đã vẽ và năm điểm với nhãn hiển thị số đếm trong mỗi cụm. Điều này đã được tạo bằng cách sử dụng truy vấn SQL ở trên.
Bạn cũng có thể cố gắng minh họa vị trí của các cụm này với 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) Phân cụm trong một khoảng cách ngưỡng với ST_ClusterWithin
Hàm tổng hợp này được bao gồm trong PostGIS 2.2 và trả về một mảng GeometryCollections trong đó tất cả các thành phần nằm trong khoảng cách của nhau.
Dưới đây là một ví dụ sử dụng, trong đó khoảng cách 100.0 là ngưỡng dẫn đến 5 cụm khác nhau:
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;
Cụm giữa lớn nhất có bán kính vòng tròn bao quanh là 65,3 đơn vị hoặc khoảng 130, lớn hơn ngưỡng. Điều này là do khoảng cách riêng giữa các hình học thành viên nhỏ hơn ngưỡng, vì vậy nó liên kết nó với nhau như một cụm lớn hơn.