Bir parsel (poligon) katmanında bitişiklik testleri yapmak ve belirli ölçütlere uymaları durumunda (boyutta olabilirler) birleştirmek istiyorum. Aşağıdaki resimde, poligon 1,2,3 ve 4'ü birleştirmek istiyorum, fakat 5'i değil .
İki sorunum var:
ST_TOUCHES
Sadece köşeler dokunduğunda ve bir çizgi parçasına dokunmadığında TRUE değerini döndürür. Paylaşılan satır segmentlerini kontrol etmek için ST_RELATE'e ihtiyacım olduğunu düşünüyorum.- İdeal olarak, TÜM komşu çokgenleri bire birleştirmek isterim, ancak iki turda 1,2,3 ve 4'ü (ve muhtemelen gerçek veriler üzerinde daha fazlasını) bir turda nasıl birleştireceğinden emin değilim.
Şu an sahip olduğum yapı, kendimi birleştirmeye dayanıyor ST_TOUCHES
.
Oyuncak verileri
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 ;
seçim
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
İşte çıktı:
+-----+---------+-------------------------------------------------------------------------------+
| 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))) |
+-----+---------+-------------------------------------------------------------------------------+
Çokgen id = 3 öğesinin id = 1 ile bir puan paylaştığını ve bu nedenle pozitif sonuç olarak döndürüldüğünü unutmayın. WHERE yan tümcesini değiştirirsem ST_Touches( t1.geom, t2.geom ) AND t1.geom && t2.geom AND ST_Relate(t1.geom, t2.geom ,'T*T***T**');
hiç kayıt alamam.
Yani ilk , nasıl bir çizgi parçasını paylaşmak emin sadece parsel düşünülmektedir sağlamak ST_Relate belirtebilirim.
Ve sonra, bir turda 1,2,3,4 poligonları nasıl birleştiririm, yukarıdaki çağrıdan gelen sonuçları daraltırken, 1'den 2'ye bitişikliğin tersinin aynı olduğunu kabul ederken?
Güncelleştirme
Bunu where
maddeye eklersem, açıkça sadece çokgenler alıyorum ve çokgenler almıyorum, bu yüzden amaçlarıma göre yanlış pozitifler çıkarıyor - köşe dokunuşları göz ardı ediliyor.
GeometryType(st_union(t1.geom,t2.geom)) != 'MULTIPOLYGON'
Bu ideal olmasa da ( ST_RELATE
daha genel bir çözüm olarak topoloji kontrollerini kullanmayı tercih ederim ), ileriye dönük bir yoldur. Öyleyse bunları aldatma ve sendikalaşma meselesi olmaya devam ediyor. Muhtemelen, sadece dokunan çokgenler için bir sekans oluşturabilirsem, bunun üzerinde birleşebilirdim.
Güncelleme II
Bu, çizgileri paylaşan (ancak köşeleri değil) çokgenleri seçmek için çalışıyor gibi görünüyor ve bu nedenle yukarıdaki MULTIPOLYGON
testten daha genel bir çözüm . Benim şimdiki cümlesi şunun gibi görünüyor:
WHERE
ST_Touches( t1.geom, t2.geom )
AND t1.geom && t2.geom
-- 'overlap' relation
AND ST_Relate(t1.geom, t2.geom)='FF2F11212') t2
Şimdi geriye kalan, hala bir çift poligondan daha fazlası için bir araya getirme, ancak ölçütlere uyan keyfi bir sayı için tek seferde nasıl yapılacağıdır.
ST_IntersectionArray
[işlev] [1] 'i ST_Union [1] ile çalışacak şekilde değiştirebilirsiniz: gis.stackexchange.com/a/60295/36886