Search code examples
rgiscutcontourpolygons

Cut polygons using contour line beneath the polygon layers


I would like to cut a polygon layer, according to the elevation, into two parts (upper and lower part). The polygon might convex or concave, and the position to cut might vary from each other. The contour line has an interval of 5m, which means I might need to generate a contour with much condensed contour lines, e.g, 1m interval. Any idea on how to do it, better in ArcGIS, or in R? Below is the running example for the Q:

library(sp)
library(raster)
r<-raster(ncol=100,nrow=100)
values(r)<-rep(1:100,100)
plot(r)   ### I have no idea why half of the value is negative...
p1<-cbind(c(-100,-90,-50,-100),c(60,70,30,30,60))
p2<-cbind(c(0,50,100,0),c(0,-25,10,0))
p1p<-Polygons(list(Polygon(p1,hole=T)),"p1")
p2p<-Polygons(list(Polygon(p2,hole=T)),"p2")
p<-SpatialPolygons(list(p1p,p2p),1:2)
plot(p,add=T)
segments(-90,80,-90,20)  ##where the polygon could be devided
segments(50,20,50,-30)  ##

Thanks in advance~

Marco


Solution

  • If I understand correctly, you can use the rgeos package and related Spatial tools in R.

    I took the trick to buffer an intersected line and then generate the "difference" polygon from this site:

    http://www.chopshopgeo.com/blog/?p=89

    Generate example raster, and an overlying polygon.

    vdata <- list(x = 1:nrow(volcano), y = 1:ncol(volcano), z = volcano)
    
    ## raw polygon data created using image(vdata); xy <- locator()
    
    xy <- structure(list(x = c(43.4965355534823, 41.7658494766076, 36.2591210501883, 
    25.560334393145, 13.7602020508178, 18.7949251835441, 29.179041644792, 
    40.6645037913237, 44.2832110429707, 47.272577903027, 47.5872480988224
    ), y = c(30.0641086410103, 34.1278207016757, 37.6989616034726, 
    40.900674136118, 32.7732500147872, 27.4781100569505, 22.5523984682652, 
    22.7986840476995, 24.5226831037393, 29.3252519027075, 33.8815351222414
    )), .Names = c("x", "y"))
    
    ## close the polygon
    coords <- cbind(xy$x, xy$y)
    coords <- rbind(coords, coords[1,])
    
    library(sp)
    
    ## create a Spatial polygons object
    poly <- SpatialPolygons(list(Polygons(list(Polygon(coords, hole = FALSE)), "1")))
    
    
    ## create a contour line that cuts the polygon at height 171
    cl <- contourLines(vdata, levels = 171)
    
    ## for ContourLines2SLDF
    library(maptools)
    
    clines <- ContourLines2SLDF(cl)
    

    Now, intersect the polygon with the line, then buffer the line slightly and difference that again with the polygon to give a multipart poly.

    library(rgeos)
    lpi <- gIntersection(poly, clines)
    
    blpi <- gBuffer(lpi, width = 0.000001)
    
    dpi <- gDifference(poly, blpi)
    

    Plot the original data, and the polygon halves extracted manually from the Spatial object.

    par(mfrow = c(2,1))
    
    image(vdata)
    plot(poly, add = TRUE)
    
    plot(SpatialPolygons(list(Polygons(list(dpi@polygons[[1]]@Polygons[[1]]), "1"))), 
         add = TRUE, col = "lightblue")
    
    image(vdata)
    plot(poly, add = TRUE)
    cl <- contourLines(vdata, levels = 171)
    
    plot(SpatialPolygons(list(Polygons(list(dpi@polygons[[1]]@Polygons[[2]]), "2"))), 
         add = TRUE, col = "lightgreen")
    

    That works for this fairly simple case, it might be useful for your scenario.