If your transects are line segments that are monotonically increasing in X (and if not, I don't know how you can define what is north and what is south of a line) you can use this code. Basically it constructs the buffer with gBuffer
and intersects that with a polygon created by extending the line segment south.
northbuff <- function(l1, width){
if(length(l1)!=1){
stop("line is not a single line element")
}
lines = l1@lines
if(length(l1@lines)!=1){
stop("line element is not a single line string")
}
bb = bbox(l1)
xy = coordinates(l1@lines[[1]])[[1]]
if(any(diff(xy[,1])<=0)){
stop("x coord not monotone increasing")
}
xy = xy[order(xy[,1]),]
nx = nrow(xy)
xm = bb[1,1]-width*2
ym = bb[2,1]-width*2
xp = bb[1,2] + width*2
coords = rbind(xy,
c(xp,xy[nx,2]),
c(xp,ym),
c(xm,ym),
c(xm,xy[1,2]),
c(xy[1,1],xy[1,2])
)
p = SpatialPolygons(list(Polygons(list(Polygon(coords)),ID=1)))
b = gBuffer(l1, capStyle="FLAT", width=width)
gDifference(b,p)
}
Test:
> require(sp)
> require(rgeos)
> l1 = readWKT("LINESTRING(0 0,1 5,4 5,5 2,8 2,9 4)")
> plot(northbuff(l1,.2))
> plot(l1,add=TRUE,col="blue",lwd=2)
You'll have to loop over your data frame to do this for each SpatialLines
component.
If your transects are single line segments (ie a straight line from x,y to x',y') then its trivial and doable without rgeos
. If your transects aren't strictly increasing in x-coordinate then you'll have to figure out how to define north and south of a line. This code could be easily modified to produce two polygons as output, which you could then input into a function to decide which was more 'North'.