获取TopologyException:输入几何1无效,这是由于R中的自相交导致的?


24

由无效的多边形几何形状引起的“ TopologyException:输入几何1无效”自相交错误已得到广泛讨论。但是,我没有在网络上找到仅依赖于R功能的便捷解决方案。

例如,我已经设法从map("state", ...)遵循Josh O'Brien 在这里的好答案的输出中创建一个“ SpatialPolygons”对象。

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)

状态

现在,这种广泛应用的数据集的问题在于自相交发生在以下给定的点。

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

不幸的是,此问题阻止了对spydf_states的任何进一步使用,例如在调用时rgeos::gIntersection。如何在R中解决此问题?


1
如果您放大该点:plot(spydf_states, xlim=c(-122.1,-122.3),ylim=c(38,38.1))您会发现那里没有“貌似”的地方-有一个自相交处。
Spacedman

Answers:


39

使用零宽度缓冲区可以清除R中的许多拓扑问题。

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

但是,使用未投影的经纬度坐标可能会rgeos引发警告。

这是一个扩展的示例,该示例首先重新投影为Albers投影:

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)

在此处输入图片说明


4
关于gBuffer“ hack” 为何起作用的任何额外评论/阅读?
MichaelChirico

您是否要使用gSimplify分解data.frame并将SPDF转换为空间多边形对象?
wnursal

5
如果您正在使用sf,也可以使用sf::st_buffer(x, dist = 0)
Phil

在使用某些情况下也可以工作PostGIS
natsuapo
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.