37 votos

Obteniendo TopologyException: La geomática de entrada 1 no es válida debido a la auto-intersección en R?

Se ha detectado la "TopologyException: Input geom 1 is invalid' error de auto-intersección 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 se base únicamente en la funcionalidad de R.

Por ejemplo, he conseguido crear un objeto 'SpatialPolygons' a partir de la salida de map("state", ...) tras la bonita 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)

states

El problema de este conjunto de datos ampliamente aplicado es que ahora la autointersección se produce en el punto indicado a continuación.

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

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

51voto

Nelson Reis Puntos 2889

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 lat-long no proyectadas puede causar rgeos para lanzar advertencias.

Aquí hay un ejemplo extendido que reproyecta a una proyección Albers primero:

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)

enter image description here

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X