I cannot not find some stuff in the raster
and rgeos
package and wrote a small example that calculates ONLY the segments (egdes in igraph
speech) between two layers from scratch, not very fast. To build lines (topologies) from this point is not a straight forward to handle task. One point can join four segments, if you have a chess board pattern for example. If you connect all segments you will get a line graph not a line string. I think there are better solutions and you could investigate the capabilities of igraph
.
Here is the script:
# Load packages
require('raster')
# ----------------------------------------
# Create a test raster with
# cell transitions 2 -> 1
# some open cells at the border
# and 0 hole in the center
makeTestRaster <- function() {
nc <-5; nr <-5;
rs<-raster(nrow=nr,ncol=nc);
for (c in 1:nc) {
for (r in 1:nr) {
if( r==2 | c==2 | r==4 | c==4 ) {
rs[r,c]=2;
}
else if (r==3 | c == 3) {
rs[r,c]=1;
}
else {
rs[r,c]=0;
}
}
}
rs[3,3] <-0
return(rs)
}
# ----------------------------------------------
# Calculate all segments with a <-> b connection
# (without a iteration pattern)
# df - the serialized form
# rs - the raster
# pos - pos in the table
# a - cell sourrounded by
# b - cell neighbor type
calcSegmentAtPos <- function(df,rs, pos, a, b, DEBUG=FALSE) {
nc<-ncol(rs) # number of columns
nr<-nrow(rs) # number of rows
pcol<-(pos-1) %% nc + 1; # raster col
prow<-(pos-1) %/% nc + 1; # raster row
result<-c(); # result vector
# Position in raster OK?
if (pcol < 0 | prow < 0 |
pcol > nc | prow > nr ) {
return (result);
}
# Call is of type A
if (rs[prow, pcol] != a) return (result);
# Cell resolution x and y
dx <- xres(rs);
dy <- yres(rs);
# Test positions and type (horizontal, vertical)
tcol <- c(pcol-1, pcol+1, pcol, pcol);
trow <- c(prow, prow, prow-1, prow+1);
ttype <- c(TRUE, TRUE, FALSE, FALSE);
# Run tests and calc segments
for (ix in 1:4) {
scol <- tcol[ix] # test column
srow <- trow[ix] # test row
vertical <- ttype[ix]; # generation type
# Test position in raster OK?
if (scol < 1 | scol > nc |
srow < 1 | srow > nr ) {
next;
}
# Test type a <-> b between cells OK ?
va = rs[prow,pcol]
vb = rs[srow,scol]
if (rs[prow,pcol] == a &
rs[srow,scol] == b) {
# Somcontraol messages if wanted
if (DEBUG) {
cat("pcol", pcol, "| prow", prow,
"| scol", scol, "| srow", srow,
"| a",va,"| b",vb,"| vert", vertical,
"\n")
}
dta <- df[pos, ] # get the data row
x <- dta$x; # center of the cell X
y <- dta$y; # center of the cell Y
# Vertical segment
if ( vertical ){
x1 <- x + (scol-pcol) * dx/2
x2 <- x1
y1 <- y - dy/2
y2 <- y + dy/2
}
# Horizontal segment
else {
y1 <- y + (prow-srow) * dy/2
y2 <- y1;
x1 <- x - dx/2
x2 <- x + dx/2
}
# push data to the result vector
result<-c(result,c(pos,x,y,x1,y1,x2,y2))
} # in frame an state a b
} #iterate test positions
return (result)
}
# --------------------------------------------
# Calculate the segments of over all
# raster points of rs with the transtition a,b
calcSegments <- function(rs, a, b) {
# Serialized form of the raster
# with all coordinates
df <- as.data.frame(rs,xy=TRUE)
# Understand cell addressing
nall <- ncell(rs);
# df$col <- seq(0,nall-1) %% nc +1
# df$row <- seq(0,nall-1) %/% nc +1
#Resulting segment buffer
segs <- c();
for (pos in 1:nall) {
v <- calcSegmentAtPos(df, rs, pos, a, b);
if (length(v)>0) segs <-c(segs,v)
}
# Re-arrange the segment vector into a data frame
len<-length(segs)/7; sq <-(0:(len-1))*7 # Index sequenz
return(data.frame(id=segs[sq+1],
x=segs[sq+2],
y=segs[sq+3],
x0=segs[sq+4],
y0=segs[sq+5],
x1=segs[sq+6],
y1=segs[sq+7]))
}
rs <- makeTestRaster()
# Calculate the segments
df <- calcSegments(rs, 2, 1)
The result is a segment table could be a start point to use igraph
to compose a graph.
> head(df)
id x y x0 y0 x1 y1
1 2 -72 72 -36 54 -36 90
2 4 72 72 36 54 36 90
3 6 -144 36 -180 18 -108 18
4 8 0 36 -36 54 36 54
5 10 144 36 108 18 180 18
6 12 -72 0 -108 -18 -108 18
- id - index of the raster cell
- x - center of the cell x
- y - center of the cell y
- x0 - start point edge x
- y0 - start point edge y
- x1 - end point edge x
- y1 - end point edge y
The visualisation of the resulting segments looks like this.
# Plot the raster
plot(rs);
# Draw the segments
segments(df$x0,df$y0,df$x1,df$y1)
# Draw the center points
points(df$x,df$y)