PostGIS ile “uzun ve dar” çokgenlerin belirlenmesi


10

Şehir mahallelerini, geniş alanları temsil eden çokgenler setim var. Aralarındaki büyük örtüşen alanları tanımlamak istiyorum.

Ancak bir sorun var: bazen bu çokgenler çevreleri boyunca örtüşür (çünkü az bir hassasiyetle çizilirler). Bu, umursamadığım uzun ve dar çakışmalar oluşturacaktır.

Ancak diğer zamanlarda, güçlü çokgenlerle büyük örtüşmeler olacak, yani bir mahallenin çokgeninin diğeriyle örtüştüğü geniş alanlar olacak. Sadece bunları seçmek istiyorum.

Yalnızca çakışmaların aşağıdaki resmine bakın. Sadece sol alt köşedeki mavi çokgeni seçmek istediğimi düşünün.

üst üste gelmek

Alanlara bakabilirdim, ama bazen dar olanları o kadar uzun olurlar ki mavi poligon kadar büyük alanlara sahip olurlar. Alan / çevre oranı yapmaya çalıştım, ama bu da karışık sonuçlar verdi.

Kullanmayı bile denedim ST_MinimumClearance, ancak bazen geniş alanların dar bir kısmı veya iki çok yakın köşesi olacak.

Başka yaklaşımlarla ilgili fikirleriniz var mı?


Sonunda benim için en iyi olan şey, aşağıdaki @Cyril ve @FGreg tarafından önerildiği gibi negatif bir tampon kullanmaktı.

Gibi bir şey kullandım:

ST_Area(ST_Buffer(geom, -10)) as neg_buffer_area

Benim durumumda, birimler metre idi, bu yüzden 10 m negatif tampon.

Dar çokgenler için bu alan sıfır döndürdü (ayrıca geometri boş olurdu). Sonra bu sütunu dar çokgenleri filtrelemek için kullandım.


4
Kesinlikle alan / çevre oranı bunun için kullanılabilir.
Vince

Farklı çokgenlerin görüntüden nerede olduğunu söylemek zor, ancak böyle bir şey yapmak gis.stackexchange.com/a/265233/64838 işe yarayabilir mi? Minimum döndürülmüş sınırlama kutusunu hesaplayın, ardından küçük genişlik veya yüksekliğe sahip olanları atın.
FGreg

Ayrıca burada açıklandığı gibi negatif bir arabellek kullanmayı deneyebilirsiniz: Şekil dosyamdaki çok ince çokgenleri nasıl belirleyebilirim?
FGreg

Yanıtlar:


5

Negatif bir tampon oluşturmaya çalışırdım, eğer ince çokgenler yer, o zaman iyi, çokgen yemiyorsa, o zaman benim ... :-)

daha önce doğrusal çokgenlerin genişliğinin 2 / 3'ünü ayarlayan bu komut dosyasını çalıştırın ...

create table name_table as
SELECT ST_Buffer(
(ST_Dump(
(ST_Union(
ST_Buffer(
(geom),-0.0001))))).geom,
0.0001)) as geom from source_table

İŞLETİM SİSTEMİ :-)...


Sonunda öneriniz benim için en iyi olan şeydi. ST_Area(ST_Buffer(geom, -10))Benim durumumda -10 -10 metre gibi bir şey kullanarak bitirdim. Bir şey bu ifadeden 0 döndürürse, filtreleyebilirim.
bplmp

9

Alan / çevre yerine, alanı çevrenin karesine (veya tersine) bölmek daha iyidir.

Buna "şekil dizini" de denir. Çevrenin alana bölünen karesi minimum 4 * Pi () değerine sahiptir (en kompakt 2D geometrisi olan bir disk durumunda), böylece kolay bir şekilde 4 * Pi () ile normalleştirilebilir yorumlama (1'e yakın normalleştirilmiş değerler, çok kompakt nesneleriniz ve kareleriniz yaklaşık 1,27 değerine sahip olduğunuz anlamına gelir).

DÜZENLEME: Alandaki bir eşik, kompakt olabilen çok küçük eserleri kaldırmak için yararlı olacaktır. O zaman şekil endeksi daha iyi kontrast gösterecektir. DÜZENLEME: Bu yanıta ek olarak, ST_Snap kullanımı sorunu oluşmadan çözmenize yardımcı olabilir.


Teşekkürler! Ama ST_Snap'ın bu durumda nasıl yardımcı olabileceğinden emin değilim ... Doğru yaparsam, böyle bir şey (o.overlap_perimeter^2 / o.overlap_area) / (4 * Pi()) as overlap_ratiomi öneriyorsun ? Bu benim için sadece alandan / çevreden daha kötü sonuçlar veriyor.
bplmp

Şimdi o.overlap_perimeter / (4 * sqrt(o.overlap_area)) as overlap_ratiobu makaleye göre kullanıyorum , ancak yine de daha kötü sonuçlar (daha kötüsü ile ne demek istediğimi ölçmek zor olsa da) isprs-ann-photogramm-remote-sens-spatial-inf-sci.net/I-7/135/… , sayfa 183.
bplmp

2
Bunun için teşekkür ederim, "şekil endeksi" ni hiç duymamıştım. Her zaman minimum sınırlayıcı bir dikdörtgen kullanmanın bu tür sorulara cevap vermenin en iyi yolu olduğunu düşünmüştüm. Bunu buldum , ilginç olan repository.asu.edu/attachments/111230/content/… .
John Powell

@ JohnPowell intersting kağıt, teşekkürler. Şekil indeksi olarak bildiğim şeye gazetede dairesellik indeksi denir. Minimum sınırlayıcı dikdörtgenlerle ilgili sorunum, çok içbükey nesnelerle (örn. U şeklinde)
çalışmamasıdır

@bplmp ST_Snap, "neredeyse" bitişik çokgenlerin köşelerini kapatmanıza yardımcı olur, böylece artık çakışma olmazlar. Rakamlarınız üzerinde ölçek yok, ancak eseriniz çizgiler gibi görünüyor, bu yüzden eserleri önlemek için yeterli bir tolerans değeri teatisini kullanabileceğinizi, ancak büyük çokgenleri etkilemediğini düşünüyorum.
radouxju

5

Bir seçenek, çokgen alanının uçları kullanılarak çizilebilecek en uzun çizgiye oranını kullanmak olacaktır. Uzun dar çokgenlerin belirlenmesi.

select * from polygons where ST_Length(ST_LongestLine(geom, geom)) < ST_Area(geom) * 4

Bu şerit çokgenler için oldukça iyi çalışır. İhtiyaçlarınıza ve projeksiyonunuza göre oranın (alanı çoğalttığınız şey) ayarlayabilirsiniz.


1

Bunun kullanım durumunuzla eşleşebileceği anlaşılıyor : Seçili çokgenleri ortadan kaldırın

Giriş katmanının seçilen çokgenlerini, ortak sınırlarını silerek belirli bitişik çokgenlerle birleştirir. Bitişik çokgen, en büyük veya en küçük alana sahip olan veya çıkarılacak çokgen ile en büyük ortak sınırı paylaşan poligon olabilir.

Eliminat, normal olarak şerit çokgenlerden, yani girdilerin sınırlarının benzer olduğu ancak aynı olmadığı çokgen kesişme işlemlerinin bir sonucu olan küçük çokgenlerden kurtulmak için kullanılır.

"En Büyük Ortak Sınır" seçeneğini denemek istediğiniz anlaşılıyor.


Şimdi qgis çözümleri değil postgis çözümleri istediğini anlıyorum. Özür dilerim, postgis'in eşdeğer bir işlevi olduğunu sanmıyorum ama bunu gelecek nesiller için bırakacağım.
FGreg

0

Bu bana PostGIS topolojisi uzantısı için mükemmel bir kullanım örneği gibi görünüyor . Topolojinin tolerans parametresi, köşelerin diğer mevcut çokgenlere yapışmasına, kaynak verilerin düşük hassasiyetiyle başa çıkmasına ve temizlenmesine ne kadar izin vereceğinizi belirleyecektir.

Kısacası, strateji:

1. Topoloji uzantısını etkinleştirin

CREATE EXTENSION postgis_topology;

2. Yeni bir boş topoloji oluşturun

SELECT topology.CreateTopology('neighborhoods_topo', 4326, 1e-7);

Üçüncü parametre, CRS birimlerinde toleranstır; akıllıca seçin. İdeal olarak, birimin metre olduğu bir CRS istiyorsunuz. CRS ünitesi metre değilse, WGS 84 aka 4326'da olduğu gibi, ST_Transformçokgenlerinizi yeniden projekte etmek için kullanın .

3. Çokgenler tablosuna bir TopoGeometry sütunu ekleyin

SELECT topology.AddTopoGeometryColumn('neighborhoods_topo', 'public', 'neighborhoods', 'topogeom', 'POLYGON');

Bu yeni bir sonuç verir layer_id. Kaydet, daha sonra gerekecek. 1Başlangıçtan itibaren sıfırdan katman olacak ve her yeni çağrıda artırılacaktır .

4. Tüm çokgenleri topolojiye ekleyin

UPDATE public.neighborhoods
SET topogeom = topology.toTopoGeom(geom, 'neighborhoods_topo', 1, 1e-7);

Bu, büyük bir veri kümesi için birkaç saat sürebilir, sabırlı olun. 1daha önce döndürülen katman_kididir.

5. Çeşitli mahallelerde görünen yüzleri bulun

Topolojiden 2 veya daha fazla topogeometride bulunan tüm yüzleri bulun. Sorguyu bir alıştırma olarak bırakacağım. En kolayı muhtemelen GetTopoGeomElementsişleve göre, sonra yüz kimliğine göre gruplandırın ve 2 veya daha fazla sayıya sahip olanlara bakın. Alternatif olarak, topogeom sütunundan temizlenmiş geometri ile yeni bir tablo oluşturabilir, sadece standart geometriye atabilir topogeom::geometryve şu anda sahip olduğunuz şeyi tekrarlayabilirsiniz, ancak şimdi şerit üst üste gelmeden temiz bir veri kümesiyle.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.