1

I have a polygon object of a transect line that I would like to divide into 3 equal parts that are one-after-the-other along the transect line. So far I have only been able to slice the polygon vertically, which results in non-continuous parts.

Here is a reproducible example using Harvard Forest data, available through the following link

After you have downloaded and unzipped the data, you will see a folder called HARV. In this folder is the shapefile, HARV_roads.shp

Import HARV_roads.shp

lines_HARV <- readOGR("/Your file path/NEON-DS-Site-Layout-Files/HARV/HARV_roads.shp")

Get footpath lines only

footpath_HARV <- lines_HARV[lines_HARV$TYPE == "footpath",]

Plot the footpath

plot(footpath_HARV,
     lwd=6,
     main="NEON Harvard Forest Field Site\n Footpath")

footpath

Create a thicker polygon object from the footpath line using buffer, to simulate a transect line with X width

require(raster)
footpath_buffer <- buffer(footpath_HARV,width=40)

Plot footpath_buffer

plot(footpath_buffer)

buffer

Chop the buffer into 3 equal parts using Barry Rowlingson's code (below) from this post

makeVchopper <- function(pol){
  bb = bbox(pol)
  delta = (bb[2,2] - bb[2,1])/10
  xmin = bb[1,1]-delta
  ymin = bb[2,1]-delta
  ymax = bb[2,2]+delta

  choppoly = function(xmax){
    readWKT(sprintf("POLYGON((%s %s, %s %s, %s %s, %s %s, %s %s))",
                    xmin,ymin, xmin,ymax, xmax,ymax, xmax,ymin,
                    xmin,ymin))
  }
  choppoly
}

slicer <- function(pol, xmin, xmax){
  bb = bbox(pol)
  delta = (bb[2,2] - bb[2,1])/10
  ymax = bb[2,2] + delta
  ymin = bb[2,1] - delta
  r = readWKT(sprintf("POLYGON((%s %s, %s %s, %s %s, %s %s, %s %s))",
                      xmin,ymin, xmin,ymax, xmax,ymax, xmax,ymin, xmin,ymin))
  gIntersection(pol,r)
}

chop_thirds <- function(pol, fractions=c(1/3, 2/3)){
  chopper = makeVchopper(pol)
  bb = bbox(pol)
  xmin = bb[1,1]
  xmax = bb[1,2]

  totalArea = gArea(pol)

  chopped_area = function(x){
    gArea(gIntersection(chopper(x),pol))
  }

  edges = lapply(fractions, function(fraction){
    target = totalArea * fraction
    target_function = function(x){
      chopped_area(x) - target
    }
    uniroot(target_function, lower=xmin, upper=xmax)$root
  })

  xdelta = (xmax-xmin)/10
  chops = matrix(c(xmin-xdelta, rep(edges,rep(2,length(edges))),
                   xmax+xdelta), ncol=2, byrow=TRUE)
  apply(chops, 1, function(edges){
    slicer(pol, edges[1], edges[2])
  })

}

Divide footpath_buffer into 3 equal parts:

parts.footpath <- chop_thirds(footpath_buffer)

Plot footpath_buffer and the 3 equal parts

plot(footpath_buffer)
plot(parts.footpath[[1]], add=TRUE, col=1,border=F)
plot(parts.footpath[[2]], add=TRUE, col=2,border=F)
plot(parts.footpath[[3]], add=TRUE, col=3,border=F)

3 parts

footpath_buffer is now divided into 3 equal parts, but the parts are broken up. I am hoping to achieve something like this, where each part is continuous along the transect:

3 parts transect cont

  • 1
    Not sure how much of the existing code you'll be able to salvage, but the idea would be to traverse the original line geometry, making perpendicular cuts against the buffer & testing as you go. – phloem Nov 9 '18 at 22:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.