Sửa các lỗ mồ côi ở R


18

Tôi đang cố gắng thực hiện một liên minh trên một lĩnh vực chung sau khi hợp nhất hai shapefile liền kề. Các shapefiles kết thúc với ít nhất một mảnh không gian mỏng giữa chúng. Khi tôi cố gắng kết hợp, tôi nhận được lỗi lỗ mồ côi sau đây:

Lỗi trong createPolygonsVer (p): rgeos_PolyCreateVer: lỗ mồ côi, không thể tìm thấy chứa đa giác cho lỗ ở chỉ số 17

Tôi đã tải lên một ví dụ có thể tái tạo lên Dropbox tại liên kết này .

Đây là mã để tạo lại vấn đề:

#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)

Trả về:

Lỗi trong createPolygonsVer (p): rgeos_PolyCreateVer: lỗ mồ côi, không thể tìm thấy chứa đa giác cho lỗ ở chỉ số 17

Đang thử bản sửa lỗi được đề xuất ở đâyđây :

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

Điều này trả về cùng một lỗi xuất phát từ nỗ lực hợp nhất nhưng với số chỉ mục khác nhau:

rgeos_PolyCreateVer: lỗ mồ côi, không thể tìm thấy chứa đa giác cho lỗ ở chỉ số 30

Thử bản sửa lỗi được đề xuất trong hướng dẫn hữu ích của Roger Bivand

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

Trả về cùng một lỗi ở chỉ số 30 như trên.

Những người khác đã nêu ra vấn đề này ở đâyở đây , và trong khi các giải pháp được nêu ở trên dường như có hiệu quả đối với một số trường hợp, các trường hợp khác không được giải quyết. Một người dùng đã sử dụng QGIS để giải quyết vấn đề và người kia đã sửa 2 trong 3 mục, nhưng không có giải pháp nào cho mục cuối cùng.

Có vẻ như mọi người tiếp tục gặp vấn đề mặc dù mã này thỉnh thoảng hoạt động. Có ai tìm thấy một giải pháp trong R?

Tôi đã thực hiện công cụ "sửa chữa hình học" trong ArcGIS và nó đã khắc phục vấn đề, nhưng có vẻ như cần phải sửa lỗi trong R.


Không có dữ liệu của bạn, thật khó để nói vấn đề ở đâu.

@Pascal, tôi vừa tải lên một liên kết dropbox với shapefile giảm xuống 10mb được nén và 16mb không được giải nén sẽ tái tạo vấn đề. Tôi không chắc cách cung cấp dữ liệu như ban đầu là 1,5 gb, nhưng đã quản lý để sử dụng ArcGIS để thu hẹp vấn đề thành một tệp nhỏ hơn. Có một giao thức tốt để tạo và chia sẻ các ví dụ có thể lặp lại có thể quản lý được không?
Luke Macaulay

Thử các cách tiếp cận khác nhau với R không hiệu quả. Và Qgis bị đóng băng khi kiểm tra hình học.

Câu trả lời:


25

Tôi đã phân tích các vấn đề hình học trong dữ liệu đính kèm và có vẻ như nó KHÔNG CHỈ có orphaned holesmà còn geometry validity issues. Đúng orphaned holelà một vấn đề nào đó có giá trị hình học, nhưng rgeos không xử lý nó theo cùng một cách, như đối với các lỗ mồ côi, một lỗi được đưa ra, thay vì một cảnh báo đơn giản. Như bạn chỉ ra, chúng là những gợi ý để kiểm tra các lỗ đa giác, nhưng không phải lúc nào cũng thành công khi áp dụng để sửa các lỗ mồ côi.

Vậy hãy:

  1. làm sạch dữ liệu của bạn (cần thiết nếu bạn muốn thực hiện xử lý địa lý như liên minh)

  2. sử dụng dữ liệu được làm sạch với quy trình hợp nhất của bạn

1. Làm sạch hình học Việc sửa hình học trong R đôi khi có thể khó khăn, vì vậy tôi đã cố gắng xây dựng gói R thử nghiệm (xem https://github.com/eblondel/cleangeo ) có ý định tạo điều kiện thuận lợi cho việc làm sạch các spvật thể (hiện tại đã giới hạn hình đa giác). Bạn có thể cài đặt gói với:

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

Để bắt đầu, thật tốt khi bạn thấy các vấn đề hình học với dữ liệu nguồn của bạn là gì. Đối với điều này, bạn có thể chạy như sau (dữ liệu của bạn lớn để có thể mất một chút thời gian):

#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,]

Với điều này, bạn sẽ thấy rằng dữ liệu của bạn có 2 loại vấn đề: orphaned holesgeometry validity issues. Cả hai (và không chỉ các lỗ mồ côi) có khả năng làm cho unionquá trình không thành công, vì vậy dữ liệu cần được làm sạch trước, theo cách tự động hóa khi có thể. Để tái tạo nhanh, mã mẫu đầu tiên bên dưới chỉ lấy tập hợp các tính năng được gắn thẻ là đáng ngờ (ngoại trừ mã mới nhất, với chỉ số = 9002 trong dữ liệu gốc - xem ghi chú của tôi bên dưới về điều này)

#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)

Nếu clgeo_Cleanlàm tốt công việc, bạn sẽ nhận được tất cả hình học hợp lệ ngay bây giờ. Bạn có thể áp dụng điều này cho bộ dữ liệu hoàn chỉnh (ngoại trừ chỉ số tính năng = 9002)

#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. Quá trình liên kết Bây giờ, hãy xem liệu các uniontác phẩm trên bộ dữ liệu này:

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

Lưu ý: như đã nói trước đây, tôi đã xóa một tính năng (index = 9002). Vì tôi đang vẽ nó : plot(sp[9002,]), bạn sẽ thấy tính năng này rất (rất) phức tạp. Tôi đã loại nó ra khỏi mẫu chỉ vì việc kiểm tra các lỗ đã mất quá nhiều thời gian. Bây giờ chúng ta hãy xem nếu cùng một vấn đề xảy ra bằng cách sử dụng readShapePoly(từ maptools) để đọc dữ liệu ...

3. Chuyển sang readShapePoly so với readOGR để đọc dữ liệu (CẬP NHẬT)

readOGRkhông phải là chức năng duy nhất có sẵn để đọc shapefiles. Bạn cũng có thể sử dụng readShapePolytừ maptoolsgói, thường hiệu quả hơn so với gói đầu tiên:

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

Ngoài việc chạy nhanh hơn:

  • Nếu bạn sử dụng mã trên dựa trên clgeo_CollectionReport, không có vấn đề về các lỗ mồ côi, nhưng vẫn có vấn đề về hình học.

  • Làm sạch hình học clgeo_Cleancũng chạy tốt, và bây giờ nó không bị kẹt với chỉ số tính năng 9002

  • Và ... quá trình công đoàn hoạt động.

Xem bên dưới kết quả cốt truyện:

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

Kết quả liên minh

Kết luận : thích maptools đọc dữ liệu shapefile của bạn và xem xét sử dụng cleangeo để làm sạch dữ liệu của bạn trước khi xử lý địa lý.


Cảm ơn eblondel! Tôi sẽ thử nó. Cảm ơn sự phát triển gói!
Luke Macaulay

Xin chào eblondel, Điều này hoạt động tốt, nhưng tôi muốn cho bạn biết rằng khi sửa hình học, đôi khi nó sẽ tạo ra một đa giác rất lớn khi xử lý các tính năng phức tạp và phức tạp. Ví dụ, một mạng lưới đường được sửa thành một đa giác lớn về cơ bản là phạm vi của mạng. Tôi không chắc cách dễ dàng để sửa, nhưng muốn cho bạn biết.
Luke Macaulay

Ồ Gói rất ấn tượng. Đó hẳn là rất nhiều công việc.
nogpes 7/07/2015

3
Cảm ơn @nogpes cho phản hồi của bạn. Tôi đã xây dựng gói này từ đầu khi vấn đề này được đăng, cũng bởi vì làm sạch hình học không phải lúc nào cũng dễ dàng. Nếu bạn đang ở trên Github, tôi sẽ chào đón 'ngôi sao' của bạn :-), tôi muốn cải thiện hơn nữa gói trong tương lai và có thể phát hành nó trên CRAN.
eblondel

7
Chỉ để cho bạn biết rằng cleangeo đã được xuất bản trong CRAN ( cran.r-project.org/package=cleangeo ), cho tất cả những người sử dụng nó, vui lòng báo cáo các yêu cầu nâng cao hoặc lỗi trong Github.
eblondel

1

Một giải pháp tiện lợi giúp tôi làm việc trong R là áp dụng bộ đệm có độ rộng bằng không :

#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 mất một lúc với bộ dữ liệu này, nhưng dường như chỉ hoạt động tốt.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.