2016-04-14 11 views
1

OpenStreetMaps verileriyle çalışıyorum. Osmosis tarafından Postgis 2.2 ile Postgres 9.4'e yüklendi, ways tablosu için inşa edilen linestrings geometrileri.Geçersiz linestrings bölgesinden alan nasıl oluşturulur (veya hata önlenir)

Belirli relations'dan çokgenler yapmak istiyorum (ilişki OSM'de, yol dışsal ve içsel olarak işaretlenmiş, bazıları kapalı olarak işaretlenmiş - birden fazla yol dış yüzeyi temsil edebilir) . Ancak OSM verileri mükemmel değil - iç halkaların dış halka ile kesiştiği kötü biçimlendirilmiş ilişkiler var. Örneğin: http://www.openstreetmap.org/relation/6095901#map=17/48.93209/19.14858

ben bu sorguyu

SELECT ST_BuildArea(ST_Collect(w.linestring)) AS geom 
FROM relations r 
JOIN relation_members rm ON r.id = rm.relation_id AND rm.member_type = 'W' 
JOIN ways w ON w.id = rm.member_id 
WHERE r.id = 6095901 -- in reality here is broad condition on relation 
GROUP BY r.id 

çalışıyorum ve sonuç hatadır:

ERROR: LWGEOM_GEOS_buildArea: TopologyException: Input geom 1 is invalid: Self-intersection at or near point 19.149718131981164 48.934732947538478 at 19.149718131981164 48.934732947538478 

Yani, seçeneklerim burada nelerdir? İdeal olarak, bir şekilde "bunu düzeltmek" isterim - sorunlu "delikleri" göz ardı edersiniz ya da dış halka sınırına "klips" diyeyim.

Mümkünse, sorguyu "atla" yapmak istiyorum. NULL geometri) Bu gibi geçersiz ilişkiler için ve sonuçsuz ilk hatada ölmez.

EDIT: Orijinal örnek vaka OSM verilerinde düzeltildi. İşte yeni örnek: ilişki ID 5636774 kendiliğinden kesişen çok kutuplu

+0

Geçersiz geoms için ST_MakeValid (geom) işlevini kullanabilirsiniz. –

cevap

0

Bu hataları ST_Collect yerine ST_Union kullanarak önleyebileceğinize inanıyorum. Bu daha yavaş ama örtüşen bölümlerden kurtulacaktır.

İşte

http://postgis.net/docs/ST_Collect.html

Ben senin ikinci örneği test etmek ne yaptığını: Orada belgelerinde bu konuda notlar ST_Collect içindir

create table ways (id integer, linestring geometry(Linestring, 4326)); 
insert into ways values (1, ST_GeomFromText('LINESTRING(52.3474437 35.3635293,52.347219 35.3636168,52.3472848 35.36407,52.3475095 35.3639826,52.3474437 35.3635293)', 4326)); 
insert into ways values (1, ST_GeomFromText('LINESTRING(52.3473579 35.3642849,52.347274 35.3636982,52.3468764 35.3638506,52.3468949 35.3639796, 52.3472102 35.3638587, 52.3472757 35.3643164, 52.3473579 35.3642849)', 4326)); 
insert into ways values (1, ST_GeomFromText('LINESTRING(52.3468455 35.3636261, 52.34673 35.3636689, 52.3468697 35.3646806, 52.3474622 35.3644612, 52.3474339 35.3642567, 52.3473579 35.3642848, 52.3472762 35.3643151, 52.346957 35.3644333, 52.3468945 35.3639806, 52.3468765 35.3638507, 52.3468455 35.3636261)', 4326)); 
select ST_BuildArea(ST_Collect(linestring)) from ways; 
select ST_BuildArea(ST_Union(linestring)) from ways; 
Ben de ST_IsValid kullanarak kabul

ama ST_IsValid(ST_Collect(linestring)) çıkıyor Bu kötü şekil için bile geçerlidir, bu yüzden size yardımcı olmaz.

+0

ST_Union'u denedim ve bu iyi değil - çokgen içinde herhangi bir "delik" bu şekilde kaybolur - dış kabuk içindeki tüm alan doldurulur. Bu aynı zamanda geçerli çokgenlerde de meydana gelir, bu nedenle bu, sorunlu geçersiz çokgenlerden çok daha fazla geçersiz veri üretecektir – rouen

İlgili konular