มีวิธีการจัดกลุ่มที่ดีอย่างน้อยสองวิธีสำหรับ PostGIS: k -means (ผ่านkmeans-postgresql
ส่วนขยาย) หรือรูปทรงเรขาคณิตการทำคลัสเตอร์ภายในระยะทางที่กำหนด (PostGIS 2.2)
1) k-หมายถึงด้วยkmeans-postgresql
การติดตั้ง:คุณต้องมี PostgreSQL 8.4 หรือสูงกว่าบนระบบโฮสต์ POSIX (ฉันไม่รู้ว่าจะเริ่มต้นที่ MS Windows ได้ที่ไหน) หากคุณมีการติดตั้งจากแพ็คเกจตรวจสอบให้แน่ใจว่าคุณมีแพ็คเกจการพัฒนา (เช่นpostgresql-devel
สำหรับ CentOS) ดาวน์โหลดและแตกไฟล์:
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/
ก่อนการสร้างคุณต้องตั้งค่าUSE_PGXS
ตัวแปรสภาพแวดล้อม (โพสต์ก่อนหน้าของฉันได้รับคำสั่งให้ลบส่วนนี้ของMakefile
ซึ่งไม่ได้เป็นตัวเลือกที่ดีที่สุด) หนึ่งในสองคำสั่งเหล่านี้ควรใช้ได้กับ Unix shell
# bash
export USE_PGXS=1
# csh
setenv USE_PGXS 1
ตอนนี้สร้างและติดตั้งส่วนขยาย:
make
make install
psql -f /usr/share/pgsql/contrib/kmeans.sql -U postgres -D postgis
(หมายเหตุ: ฉันได้ลองกับ Ubuntu 10.10 แล้ว แต่ไม่มีโชคเพราะไม่มีเส้นทางpg_config --pgxs
อยู่นี่อาจเป็นข้อผิดพลาดในการบรรจุภัณฑ์ของ Ubuntu)
การใช้งาน / ตัวอย่าง:คุณควรมีตารางจุดหนึ่ง (ฉันวาดคะแนนสุ่มหลอกใน QGIS) นี่คือตัวอย่างของสิ่งที่ฉันทำ:
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
ฉันให้ไว้ในอาร์กิวเมนต์ที่สองของkmeans
ฟังก์ชั่นหน้าต่างเป็นKจำนวนเต็มในการผลิตห้ากลุ่ม คุณสามารถเปลี่ยนเป็นจำนวนเต็มใดก็ได้ที่คุณต้องการ
ด้านล่างเป็นจุดสุ่มหลอก 31 จุดที่ฉันวาดและเซนทรอยด์ห้ารายการที่มีป้ายกำกับแสดงจำนวนในแต่ละคลัสเตอร์ สิ่งนี้ถูกสร้างขึ้นโดยใช้แบบสอบถาม SQL ด้านบน
คุณสามารถพยายามแสดงให้เห็นว่ากลุ่มเหล่านี้อยู่ที่ไหนกับ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) การจัดกลุ่มภายในระยะทางขีด จำกัด ด้วย ST_ClusterWithin
ฟังก์ชันการรวมนี้รวมอยู่ใน PostGIS 2.2 และส่งกลับอาร์เรย์ของ GeometryCollections ที่ส่วนประกอบทั้งหมดอยู่ภายในระยะทางซึ่งกันและกัน
นี่คือตัวอย่างการใช้งานโดยที่ระยะทาง 100.0 เป็นเกณฑ์ที่ให้ผลลัพธ์ใน 5 คลัสเตอร์ที่แตกต่างกัน:
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;
กลุ่มกลางที่ใหญ่ที่สุดมีรัศมีวงกลมล้อมรอบเป็น 65.3 หน่วยหรือประมาณ 130 ซึ่งมีขนาดใหญ่กว่าเกณฑ์ นี่เป็นเพราะระยะทางระหว่างแต่ละรูปทรงเรขาคณิตของสมาชิกนั้นน้อยกว่าขีด จำกัด ดังนั้นมันจึงเชื่อมโยงเข้าด้วยกันเป็นกระจุกดาวที่ใหญ่กว่า