¿Cómo realizar un verdadero clip SIG de capa de polígonos usando una capa de polígono en R?


16

Me gustaría hacer un verdadero Clip SIG en R de polígonos de suelos usando una serie de polígonos de límite único, pero no puedo encontrar una función R para hacerlo correctamente. Debería funcionar igual que la clipfunción en ArcMap de ESRI. He probado el overmétodo en el sppaquete pero no parece funcionar para polys sobre polys.

Una sugerencia fue usar el paquete gIntersectionin rgeoscomo un clip usando el siguiente código:

#------------------------------------
library(rgeos)
library(maptools)

#Read layers as SpatialPolygonsDataFrame (both the same Albers projection)
Soils_poly = readShapePoly("Soils_polygons")  #Note - Has 400 polygons
clipper_poly = readShapePoly("clipper_polygon")  #Note - Has 1 polygon

#Try gintersection as clip 
Clipped_polys = gIntersection(Clipper_Tile_poly, Soils_poly)

#-----------------------------------

Esto tarda 5 minutos en ejecutarse (demasiado lento) y errores con esto:

Error en RGEOSBinTopoFunc (spgeom1, spgeom2, byid, id, drop_not_poly, "rgeos_intersection"): TopologyException: no se encontró dirEdge saliente en -721459.77681285271 2009506.5980877089

También probé este código para verificar la superposición:

gIntersects(Clipper_Tile_poly, Soils_poly)

y el resultado fue VERDADERO. clipLa función en ESRI ArcMap funciona bien para estos datos.

¿Alguien sabe de una función R para hacer correctamente un clip en polígonos espaciales usando polígonos espaciales?


Intente gIntersection con byid = TRUE (creo que es un problema colgar topologías para ciertos clips, y a veces hacerlo de esta manera ayuda), para ver la velocidad gUnarySTRtreeQuery () o gBinarySTRtreeQuery () para identificar cajas delimitadas de pares de polígonos que se intersectan y solo interseca esos pares. No hay envoltorios fáciles de alto nivel para todo este afaik
mdsumner

Respuestas:


20

La sugerencia proporcionada por @mdsummer de usar byid=TRUEfunciona con precisión.

Vea el ejemplo reproducible a continuación:

library(rgeos)
library(sp)

#Create SpatialPlygons objects
polygon1 <- readWKT("POLYGON((-190 -50, -200 -10, -110 20, -190 -50))") #polygon 1
polygon2 <- readWKT("POLYGON((-180 -20, -140 55, 10 0, -140 -60, -180 -20))") #polygon 2

par(mfrow = c(1,2)) #in separate windows
plot(polygon1, main = "Polygon1") #window 1
plot(polygon2, main = "Polygon2") #window 2

polígonos uno al lado del otro

polygon_set <- readWKT(paste("POLYGON((-180 -20, -140 55, 10 0, -140 -60, -180 -20),",
                     "(-190 -50, -200 -10, -110 20, -190 -50))"))

par(mfrow = c(1,1)) #now, simultaneously
plot(polygon_set, main = "Polygon1 & Polygon2")

ingrese la descripción de la imagen aquí

clip <- gIntersection(polygon1, polygon2, byid = TRUE, drop_lower_td = TRUE) #clip polygon 2 with polygon 1
plot(clip, col = "lightblue")

ingrese la descripción de la imagen aquí

GT <- GridTopology(c(-175, -85), c(10, 10), c(36, 18))
gr <- as(as(SpatialGrid(GT), "SpatialPixels"), "SpatialPolygons")
plot(gr)

ingrese la descripción de la imagen aquí

clip2 <- gIntersection(clip, gr, byid = TRUE, drop_lower_td = TRUE)
plot(clip2, col = "pink")

ingrese la descripción de la imagen aquí


1
Funciona un sueño, increíblemente rápido. Estoy usando esto para recortar polilíneas. Quería hacer subconjuntos del shapefile para los ríos británicos, porque es mucho más rápido trabajar con un subconjunto más pequeño de datos.
CJB

1
@AndreSilva, pensé que sí, ¡pero supongo que no! Re: comunidad, desearía que la comunidad de desarrolladores de R GIS fuera un poco más grande TBH. Probablemente tendré que recurrir a ArcMap para realizar algunas digitalizaciones y otros procesos que son rápidos en la GUI.
Rich Pauloo

3

También puede usar el paquete ráster raster::intersect(spdf1, spdf2). Tiene la ventaja de mantener los atributos en caso de que tenga un SpatialPolygonsDataFrame.

library(sp); library(rgeos)

coords1 <- matrix(c(-1.841960, -1.823464, -1.838623, -1.841960, 55.663696,
                55.659178, 55.650841, 55.663696), ncol=2)
coords2 <- matrix(c(-1.822606, -1.816790, -1.832712, -1.822606, 55.657887,
                55.646806, 55.650679, 55.657887), ncol=2)
p1 <- Polygon(coords1)
p2 <- Polygon(coords2)
p1 <- Polygons(list(p1), ID = "p1")
p2 <- Polygons(list(p2), ID = "p2")
myPolys <- SpatialPolygons(list(p1, p2))
spdf1 = SpatialPolygonsDataFrame(myPolys, data.frame(variable1 = c(232,
                                                               242), variable2 = c(235, 464), row.names = c("p1", "p2")))
coords1a <- matrix(c(-1.830219, -1.833753, -1.821154, -1.830219, 55.647353,
                 55.656629, 55.652122, 55.647353), ncol=2)
p1a <- Polygon(coords1a)
p1a <- Polygons(list(p1a), ID = "p1a")
myPolys1 <- SpatialPolygons(list(p1a))
spdf2 = SpatialPolygonsDataFrame(myPolys1, data.frame(variable1 = c(2),
                                                  variable2 = c(3), row.names = c("p1a")))

# works but drop the attributes
#gIntersection(spdf1, spdf2, byid=T)

#better to keep attributes
inter1=raster::intersect(spdf1, spdf2)

plot(spdf1, col="red")
plot(spdf2, col="yellow", add=T)
plot(inter1,col="blue", add=T)

ingrese la descripción de la imagen aquí

Gracias a esta pregunta por señalarlo y por el código de muestra.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.