Bắt TopologyException: Geom đầu vào 1 không hợp lệ là do tự giao nhau trong R?


24

'TopologyException: Geom đầu vào 1 không hợp lệ' Lỗi tự giao nhau phát sinh từ hình học đa giác không hợp lệ đã được thảo luận rộng rãi. Tuy nhiên, tôi chưa tìm thấy một giải pháp tiện lợi nào trên web chỉ dựa vào chức năng R.

Chẳng hạn, tôi đã quản lý để tạo một đối tượng 'SpatialPolygons' từ đầu ra của map("state", ...)câu trả lời hay của Josh O'Brien tại đây .

library(maps)
library(maptools)

map_states = map("state", fill = TRUE, plot = FALSE)

IDs = sapply(strsplit(map_states$names, ":"), "[[", 1)
spydf_states = map2SpatialPolygons(map_states, IDs = IDs, proj4string = CRS("+init=epsg:4326"))

plot(spydf_states)

tiểu bang

Vấn đề với bộ dữ liệu được áp dụng rộng rãi này là bây giờ việc tự giao nhau xảy ra tại điểm được đưa ra dưới đây.

rgeos::gIsValid(spydf_states)
[1] FALSE
Warning message:
In RGEOSUnaryPredFunc(spgeom, byid, "rgeos_isvalid") :
  Self-intersection at or near point -122.22023214285259 38.060546477866055

Thật không may, vấn đề này ngăn không cho sử dụng thêm 'spydf_states', ví dụ như khi gọi rgeos::gIntersection. Làm thế nào tôi có thể giải quyết vấn đề này từ bên trong R?


1
Nếu bạn phóng to xung quanh điểm đó: plot(spydf_states, xlim=c(-122.1,-122.3),ylim=c(38,38.1))bạn sẽ thấy không có "dường như" về điểm đó - có một giao điểm tự.
Spainedman

Câu trả lời:


39

Sử dụng bộ đệm có độ rộng bằng không sẽ dọn sạch nhiều vấn đề cấu trúc liên kết trong R.

spydf_states <- gBuffer(spydf_states, byid=TRUE, width=0)

Tuy nhiên, làm việc với các tọa độ dài không được cung cấp có thể gây ra rgeoscảnh báo.

Đây là một ví dụ mở rộng phản hồi lại phép chiếu Albers trước:

library(sp)
library(rgeos)

load("~/Dropbox/spydf_states.RData")

# many geos functions require projections and you're probably going to end
# up plotting this eventually so we convert it to albers before cleaning up
# the polygons since you should use that if you are plotting the US
spydf_states <- spTransform(spydf_states, 
                            CRS("+proj=aea +lat_1=29.5 +lat_2=45.5 +lat_0=37.5 +lon_0=-96"))

# simplify the polgons a tad (tweak 0.00001 to your liking)
spydf_states <- gSimplify(spydf_states, tol = 0.00001)

# this is a well known R / GEOS hack (usually combined with the above) to 
# deal with "bad" polygons
spydf_states <- gBuffer(spydf_states, byid=TRUE, width=0)

# any bad polys?
sum(gIsValid(spydf_states, byid=TRUE)==FALSE)

## [1] 0

plot(spydf_states)

nhập mô tả hình ảnh ở đây


4
bất kỳ bình luận thêm / đọc về lý do tại sao gBuffer"hack" hoạt động?
MichaelChirico

Bạn có muốn sử dụng gSimplify khi nó xé dữ liệu.frame và chuyển đổi SPDF thành đối tượng đa giác không gian?
wnursal

5
Nếu bạn đang sử dụng, sfbạn cũng có thể sử dụngsf::st_buffer(x, dist = 0)
Phil

cũng hoạt động trong một số trường hợp khi sử dụngPostGIS
natsuapo
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.