Tôi muốn thực hiện các thử nghiệm kề trên một lớp bưu kiện (đa giác) và hợp nhất chúng nếu chúng phù hợp với các tiêu chí nhất định (có thể là kích thước). Theo hình dưới đây, tôi muốn hợp nhất các đa giác 1,2,3 và 4, nhưng không phải là 5.
Tôi có hai vấn đề:
ST_TOUCHES
trả về TRUE nếu chỉ các góc chạm và không phải là một đoạn thẳng. Tôi nghĩ rằng tôi cần ST_RELATE để kiểm tra các phân đoạn dòng được chia sẻ.- Lý tưởng nhất, tôi muốn hợp nhất TẤT CẢ các đa giác liền kề thành một, nhưng tôi không chắc chắn làm thế nào để vượt quá hai - như trong, hợp nhất 1,2,3 và 4 (và có thể nhiều hơn trên dữ liệu thực tế) trong một vòng.
Cấu trúc tôi có bây giờ dựa trên tự tham gia ST_TOUCHES
.
Dữ liệu đồ chơi
CREATE TABLE testpoly AS
SELECT
1 AS id, ST_PolyFromText('POLYGON ((0 0, 10 0, 10 20, 00 20, 0 0 ))') AS geom UNION SELECT
2 AS id, ST_PolyFromText('POLYGON ((10 0, 20 0, 20 20, 10 20, 10 0 ))') AS geom UNION SELECT
3 AS id, ST_PolyFromText('POLYGON ((10 -20, 20 -20, 20 0, 10 0, 10 -20 ))') AS geom UNION SELECT
4 AS id, ST_PolyFromText('POLYGON ((20 -20, 30 -20, 30 0, 20 0, 20 -20 ))') AS geom UNION SELECT
5 AS id, ST_PolyFromText('POLYGON ((30 0, 40 0, 40 20, 30 20, 30 0 ))') AS geom ;
Lựa chọn
SELECT
gid, adj_gid,
st_AStext(st_union(l2.g1,l2.g2)) AS geo_combo
from (
--level 2
SELECT
t1.id AS gid,
t1.geom AS g1,
t2.id AS adj_gid,
t2.geom AS g2
from
testpoly t1,
testpoly t2
where
ST_Touches( t1.geom, t2.geom )
AND t1.geom && t2.geom
)
l2
Đây là đầu ra:
+-----+---------+-------------------------------------------------------------------------------+
| gid | adj_gid | geo_combo |
+-----+---------+-------------------------------------------------------------------------------+
| 1 | 2 | POLYGON((10 0,0 0,0 20,10 20,20 20,20 0,10 0)) |
+-----+---------+-------------------------------------------------------------------------------+
| 1 | 3 | MULTIPOLYGON(((10 0,0 0,0 20,10 20,10 0)),((10 0,20 0,20 -20,10 -20,10 0))) |
+-----+---------+-------------------------------------------------------------------------------+
| 2 | 1 | POLYGON((10 20,20 20,20 0,10 0,0 0,0 20,10 20)) |
+-----+---------+-------------------------------------------------------------------------------+
| 2 | 3 | POLYGON((10 0,10 20,20 20,20 0,20 -20,10 -20,10 0)) |
+-----+---------+-------------------------------------------------------------------------------+
| 2 | 4 | MULTIPOLYGON(((20 0,10 0,10 20,20 20,20 0)),((20 0,30 0,30 -20,20 -20,20 0))) |
+-----+---------+-------------------------------------------------------------------------------+
| 3 | 1 | MULTIPOLYGON(((10 0,20 0,20 -20,10 -20,10 0)),((10 0,0 0,0 20,10 20,10 0))) |
+-----+---------+-------------------------------------------------------------------------------+
| 3 | 2 | POLYGON((20 0,20 -20,10 -20,10 0,10 20,20 20,20 0)) |
+-----+---------+-------------------------------------------------------------------------------+
| 3 | 4 | POLYGON((20 -20,10 -20,10 0,20 0,30 0,30 -20,20 -20)) |
+-----+---------+-------------------------------------------------------------------------------+
| 4 | 2 | MULTIPOLYGON(((20 0,30 0,30 -20,20 -20,20 0)),((20 0,10 0,10 20,20 20,20 0))) |
+-----+---------+-------------------------------------------------------------------------------+
| 4 | 3 | POLYGON((20 0,30 0,30 -20,20 -20,10 -20,10 0,20 0)) |
+-----+---------+-------------------------------------------------------------------------------+
| 4 | 5 | MULTIPOLYGON(((30 0,30 -20,20 -20,20 0,30 0)),((30 0,30 20,40 20,40 0,30 0))) |
+-----+---------+-------------------------------------------------------------------------------+
| 5 | 4 | MULTIPOLYGON(((30 0,30 20,40 20,40 0,30 0)),((30 0,30 -20,20 -20,20 0,30 0))) |
+-----+---------+-------------------------------------------------------------------------------+
Lưu ý rằng đa giác id = 3 chia sẻ một điểm với id = 1 và do đó được trả về là kết quả dương. Nếu tôi thay đổi mệnh đề WHERE thành ST_Touches( t1.geom, t2.geom ) AND t1.geom && t2.geom AND ST_Relate(t1.geom, t2.geom ,'T*T***T**');
tôi không nhận được hồ sơ nào cả.
Vì vậy, trước tiên , làm cách nào để chỉ định ST_Relate để đảm bảo chỉ các bưu kiện chia sẻ một đoạn đường được xem xét.
Và sau đó, làm cách nào để hợp nhất các đa giác 1,2,3,4 trong một vòng, thu gọn kết quả từ cuộc gọi trên, tất cả trong khi nhận ra rằng kề 1 đến 2 giống như ngược lại?
Cập nhật
Nếu tôi thêm điều này vào where
mệnh đề, rõ ràng tôi chỉ nhận được đa giác chứ không phải đa bội, do đó loại bỏ các kết quả dương tính giả cho mục đích của tôi - các góc chạm sẽ bị bỏ qua.
GeometryType(st_union(t1.geom,t2.geom)) != 'MULTIPOLYGON'
Mặc dù điều này không lý tưởng (tôi muốn sử dụng kiểm tra cấu trúc liên kết với ST_RELATE
tư cách là một giải pháp tổng quát hơn), nhưng đó là một cách tiến về phía trước. Sau đó, vẫn là vấn đề khử và hợp nhất những điều này. Có thể, nếu tôi có thể tạo ra một chuỗi chỉ chạm vào đa giác, tôi có thể kết hợp với nó.
Cập nhật II
Cái này dường như hoạt động để chọn các đường chia sẻ đa giác (nhưng không phải là các góc) và do đó là một giải pháp tổng quát hơn so với MULTIPOLYGON
thử nghiệm trên . Mệnh đề where của tôi bây giờ trông như thế này:
WHERE
ST_Touches( t1.geom, t2.geom )
AND t1.geom && t2.geom
-- 'overlap' relation
AND ST_Relate(t1.geom, t2.geom)='FF2F11212') t2
Bây giờ, những gì còn lại vẫn là làm thế nào để hợp nhất không chỉ là một cặp đa giác, mà là một con số tùy ý phù hợp với tiêu chí, trong một lần.
ST_IntersectionArray
[hàm] [1] để hoạt động với ST_Union [1]: gis.stackexchange.com/a/60295/38886