Obtención de la excepción de topología: ¿El geom 1 de entrada no es válido, lo que se debe a una intersección en R?

16

El error de auto-intersección 'TopologyException: input geom 1 is invalid' que surge de geometrías de polígonos no válidas ha sido ampliamente discutido. Sin embargo, no he encontrado una solución conveniente en la web que dependa únicamente de la funcionalidad R

Por ejemplo, he logrado crear un objeto 'SpatialPolygons' a partir de la salida de map("state", ...) siguiendo la buena respuesta de Josh O'Brien aquí .

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)

Elproblemaconesteconjuntodedatosampliamenteaplicadoahoraesquelaauto-intersecciónseproduceenelpuntodadoacontinuación.

rgeos::gIsValid(spydf_states)[1]FALSEWarningmessage:InRGEOSUnaryPredFunc(spgeom,byid,"rgeos_isvalid") :
  Self-intersection at or near point -122.22023214285259 38.060546477866055

Desafortunadamente, este problema impide cualquier uso posterior de 'spydf_states', por ejemplo. al llamar a rgeos::gIntersection . ¿Cómo puedo resolver este problema desde R?

    
pregunta fdetsch 18.09.2015 - 12:27

1 respuesta

28

El uso de un búfer de ancho cero soluciona muchos problemas de topología en R.

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

Sin embargo, trabajar con coordenadas latentes no proyectadas puede hacer que rgeos arroje advertencias.

Aquí hay un ejemplo extendido que reproyecta primero en una proyección de 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)

    
respondido por el hrbrmstr 18.09.2015 - 17:01

Lea otras preguntas en las etiquetas