R'deki artık delikleri sabitleme


18

İki bitişik şekil dosyasını birleştirdikten sonra ortak bir alanda birlik oluşturmaya çalışıyorum. Şekil dosyaları, aralarında en az bir ince şerit ile sonuçlanır. Bir sendika girişiminde bulunduğumda şu yetim delik hatasını alıyorum:

CreatePolygonsComment (p) hatası: rgeos_PolyCreateComment: artık delik, dizin 17'deki delik için çokgen içeren bulunamadı

Bu bağlantıdan Dropbox'a tekrarlanabilir bir örnek yükledim .

Sorunu yeniden oluşturmak için kod:

#loading required packages
require(sp)    
require(rgdal)
require(maptools)
require(rgeos)

#load example data, set "dsn=" to your working directory or specify the path
example <- readOGR(dsn=".",layer="ReproducibleExample")

#Attempting a UnionSpatialPolygons based on the COUNTY field
example.df <- as(example, "data.frame")
countycol <- example.df$COUNTY
example.diss <- unionSpatialPolygons(example, countycol)

İadeler:

CreatePolygonsComment (p) hatası: rgeos_PolyCreateComment: artık delik, dizin 17'deki delik için çokgen içeren bulunamadı

Burada ve burada önerilen düzeltmeyi deneyin :

slot(example, "polygons") <- lapply(slot(example, "polygons"), checkPolygonsHoles)

Bu, sendika girişiminden gelen aynı hatayı döndürür, ancak farklı dizin numarasıyla döner:

rgeos_PolyCreateComment: artık delik, dizin 30'daki delik için çokgen içeren bulunamadı

Roger Bivand'ın yararlı eğitiminde önerilen düzeltmeyi denemek

fix <- slot(example, "polygons")
fixa <- lapply(fix, checkPolygonsHoles)

Yukarıdaki 30 dizininde aynı hatayı döndürür.

Diğerleri bu sorunu burada ve burada ortaya attılar ve yukarıda ortaya konan çözümler bazı durumlarda işe yarıyor gibi görünse de, diğer davalar çözülmedi. Bir kullanıcı sorunu çözmek için QGIS kullandı ve diğerinde 3 öğeden 2'si düzeltildi, ancak sonuncusu için çözüm yoktu.

Bu kod zaman zaman çalışmasına rağmen insanlar sorun yaşamaya devam ediyor gibi görünüyor. R içinde bir çözüm bulan var mı?

ArcGIS'de "onarım geometrisi" aracını kullandım ve sorunu düzeltti, ancak R'de bir düzeltme olması gerektiği anlaşılıyor.


Verileriniz olmadan, sorunun nerede olduğunu söylemek zor.

@Pascal, sadece 10mb fermuarlı ve 16mb fermuarlı bir aşağı açılan şekil dosyası ile sorunu yeniden oluşturacak bir dropbox bağlantısı yükledim. Orijinal 1.5 gb olduğu gibi verilerin nasıl sağlanacağından emin değildim, ancak sorunu daha küçük bir dosyaya daraltmak için ArcGIS'i kullanmayı başardım. Yönetilebilir boyutlu tekrarlanabilir örnekler oluşturmak ve paylaşmak için iyi bir protokol var mı?
Luke Macaulay

R ile farklı yaklaşımlar denemek işe yaramadı. Ve geometrileri kontrol ederken Qgis donuyor.

Yanıtlar:


25

Ekli verilerdeki geometri sorunlarını analiz ettim ve SADECE değil, orphaned holesaynı zamanda var gibi görünüyor geometry validity issues. A'nınorphaned hole bir şekilde bir geometri geçerlilik sorunu olduğu doğrudur , ancak rgeos , yetim delikler için olduğu gibi basit bir uyarı yerine bir hata ortaya çıkarır . Belirttiğiniz gibi, bunlar çokgen deliklerini kontrol etmek için ipuçlarıdır, ancak yetim delikleri düzeltmek için uygulandığında her zaman başarılı değildir.

Öyleyse:

  1. verilerinizi temizleyin (sendika gibi coğrafi işlem yapmak istiyorsanız gereklidir)

  2. temizlenmiş verileri sendika sürecinizle birlikte kullanın

1. Temizleme geometri i inşa deneysel R paketi (bkz denedim böylece Ar geometri sabitleme, bazen zor olabilir https://github.com/eblondel/cleangeo temizlik kolaylaştırmak niyetinde) spnesneler (şimdi de sınırlı çokgen şekiller). Paketi aşağıdakilerle kurabilirsiniz:

require(devtools)
install_github("eblondel/cleangeo")
require(cleangeo)

Başlamak için, kaynak verilerinizdeki geometri sorunlarının neler olduğunu görmeniz iyi olur. Bunun için aşağıdakileri çalıştırabilirsiniz (verileriniz büyük olduğundan biraz zaman alabilir):

#get a report of geometry validity & issues for a sp spatial object
report <- clgeo_CollectionReport(sp)
summary <- clgeo_SummaryReport(report)
issues <- report[report$valid == FALSE,]

Bununla, verilerinizin 2 tür sorunu olduğunu göreceksiniz: orphaned holes ve geometry validity issues. Her ikisi de (ve yalnızca öksüz delikler değil) unionişlemin başarısız olmasına neden olabilir , bu nedenle veriler daha önce mümkün olduğunca otomatik bir şekilde temizlenmelidir. Hızlı bir çoğaltma için, aşağıdaki ilk örnek kod yalnızca şüpheli olarak etiketlenen özelliklerin alt kümesini alır (en sonuncusu hariç, orijinal verilerde index = 9002 ile - aşağıdaki notuma bakın)

#get suspicious features (indexes)
nv <- clgeo_SuspiciousFeatures(report)
mysp <- sp[nv[-14],]

#try to clean data
mysp.clean <- clgeo_Clean(mysp, print.log = TRUE)

#check if they are still errors
report.clean <- clgeo_CollectionReport(mysp.clean)
summary.clean <- clgeo_SummaryReport(report.clean)

Eğer clgeo_Clean iyi iş yapar, artık tüm geometriler geçerli almalısınız. Bunu tüm veri kümesine uygulayabilirsiniz (özellik dizini = 9002 hariç)

#try to clean data
mysp <- sp[-9002,]
mysp.clean <- clgeo_Clean(mysp, print.log = TRUE)

#check if they are still errors
report.clean <- clgeo_CollectionReport(mysp.clean)
summary.clean <- clgeo_SummaryReport(report.clean)

2. Birlik süreci Şimdi, unionbu veri kümesindeki çalışmaların olup olmadığına bakalım :

#Attempting a UnionSpatialPolygons based on the COUNTY field
mysp.df <- as(mysp, "data.frame")
countycol <- mysp.df$COUNTY
mysp.diss <- unionSpatialPolygons(mysp.clean, countycol)

Not: daha önce de belirtildiği gibi, bir özelliği kaldırdım (index = 9002). plot(sp[9002,]) bu özelliğin çok (çok) karmaşık olduğunu göreceksiniz. Sadece delikleri kontrol etmek çok zaman aldığından numuneden hariç tuttum. Şimdi, aynı problemin verileri okumak için readShapePoly(from maptools) kullanarak meydana gelip gelmediğine bakalım ...

3. Veri okumak için readShapePoly ve readOGR'ye geçin (GÜNCELLEME)

readOGRşekil dosyalarını okumak için kullanılabilen tek işlev değildir. Ayrıca kullanabilirsiniz readShapePolygelen maptoolsbirincisinden daha genel olarak daha fazla ölçülebilir, paketin:

require(maptools)
mysp <- readShapePoly("ReproducibleExample.shp")

Daha hızlı koşmanın yanı sıra:

  • eğer yukarıdaki kodu kullanarak kullanırsanız clgeo_CollectionReport , öksüz deliklerle ilgili bir sorun yoktur, ancak yine de geometri sorunları vardır.

  • Geometri ile temizleme clgeo_Clean de iyi çalışıyor ve şimdi 9002 özellik indeksi ile sıkışmıyor

  • Ve ... birlik süreci işe yarıyor.

Çizim sonucunun altına bakın:

#plot the result
plot(mysp, border= "lightgray")
plot(mysp.diss, border="red", add = TRUE)

Birlik sonucu

Sonuç : şekil dosyası verilerinizi okumak için maptools'u tercih edin ve herhangi bir coğrafi işlemden önce verilerinizi temizlemek için cleangeo kullanmayı düşünün .


Teşekkürler eblondel! Bunu deneyeceğim. Paket geliştirme için teşekkürler!
Luke Macaulay

Merhaba eblondel, Bu iyi çalıştı, ancak geometriyi düzeltirken, karmaşık ve karmaşık özelliklerle uğraşırken çoğu zaman çok büyük bir çokgen oluşturacağını bildirmek istedim. Örneğin, bir yol ağı, temel olarak ağın kapsamı olan büyük bir çokgene düzeltildi. Bunun düzeltilmesinin ne kadar kolay olduğundan emin değilim, ama size bildirmek istedim.
Luke Macaulay

Vay. Çok etkileyici bir paket. Bu çok iş olmalı.
nograpes

3
Geri bildiriminiz için @nograpes'e teşekkürler. Bu paket gönderildiğinde bu paketi sıfırdan oluşturdum, çünkü geometrileri temizlemek her zaman kolay bir iş değil. Github üzerinde iseniz, ben senin 'yıldız' :-) hoş geldiniz, ben gelecekte paketi daha da geliştirmek ve muhtemelen CRAN yayınlamak istiyorum.
eblondel

7
Cleangeo'nun CRAN'da ( cran.r-project.org/package=cleangeo ) yayınlandığını bildirmek için, onu kullanan tüm insanlara Github'daki geliştirme isteklerini veya hatalarını bildirmekten çekinmeyin.
eblondel

1

R'de benim için çalışmaya devam eden uygun bir çözüm, sıfır genişlikli bir tampon uygulamaktır :

#loading required packages
require(sp)    
require(rgdal)
require(maptools)
require(rgeos)

#load example data, set "dsn=" to your working directory or specify the path
example <- readOGR(dsn=".",layer="ReproducibleExample")

#project your data (I'm using California Albers here) and apply a zero-width buffer
example <- spTransform(example, CRS("+init=epsg:3310"))
example <- gBuffer(example, byid = T, width = 0)

#Attempting a UnionSpatialPolygons based on the COUNTY field
example.df <- as(example, "data.frame")
countycol <- example.df$COUNTY
example.diss <- unionSpatialPolygons(example, countycol)

unionSpatialPolygons bu veri kümesiyle biraz zaman alıyor, ancak iyi çalışıyor gibi görünüyor.

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.