3

I have a set of random segments drawing a kind of tessellation (of triangles, rectangles ...) in a window (in spatstat R). I need to convert it into a set of polygons (SpatialPolygons) to calculate some indices (like area, shape indices ...).

This is apparently simple but I couldn't find how to do it ...

Here is a bit of code from Carl Witthoft that generate a random pattern of self-intercepting segments :

ranpoly <- function(numsegs=10,plotit=TRUE) {

require(spatstat)
# temp fix: put the first seg into segset. Later make it a constrained random.
segset<-psp(c(0,1,1,0,.25),c(0,0,1,1,0),c(1,1,0,0,1),c(0,1,1,0,.75),owin(c(0,1),c(0,1)) ) #frame the frame
for (jj in 1: numsegs) {
# randomly select a segment to start from, a point on the seg, the slope,and direction
# later... watch for slopes that immediately exit the frame
endx <-sample(c(-0.2,1.2),1)  #force 'x1' outside the frame
# watch that sample() gotcha
if(segset$n<=5) sampset <- c(5,5) else sampset<-5:segset$n
startseg<-sample(sampset,1) #don't select a frame segment
# this is slope of segment to be constructed
slope <- tan(runif(1)*2*pi-pi) # range +/- Inf 
# get length of selected segment
seglen<-lengths.psp(segset)[startseg]
startcut <- runif(1) 
# grab the coords of starting point (similar triangles)
startx<- segset$ends$x0[startseg] + (segset$ends$x1[startseg]-segset$ends$x0[startseg])*startcut #seglen
starty<- segset$ends$y0[startseg] + (segset$ends$y1[startseg]-segset$ends$y0[startseg])*startcut #seglen
# make a psp object with that startpoint and slope; will adjust it after finding intersections
endy <- starty + slope*(endx-startx)
newpsp<-psp(startx,starty,endx,endy,segset$window,check=FALSE)
# don't calc crossing for current element of segset
hits <- crossing.psp(segset[-startseg],newpsp)
segdist <- dist(cbind(c(startx,hits$x),c(starty,hits$y)))
# dig back to get the crosspoint desired -- have to get matrixlike object out of class "dist" object
# And, as.matrix puts a zero in location 1,1 kill that row.
cutx <- hits$x[ which.min( as.matrix(segdist)[-1,1] )]
cuty <- hits$y[which.min(as.matrix(segdist)[-1,1] )]
segset <- superimpose(segset,psp(startx,starty,cutx,cuty,segset$window))

} #end jj loop
if(plotit) plot(segset,col=rainbow(numsegs))
return(invisible(segset))
}

segset=ranpoly()

segset is the psp object from wich I need to create a SpatialPolygons object.

Community
  • 1
  • 1
  • I down voted you because you question is very unclear. Your response to the first answer suddenly mentions "extracting polygons from self-intercepting segments". This is a very different question then first presented. To receive an answer to your question I would clarify it and provide code that generated the data and what you have already tried. – Jeffrey Evans Jan 28 '13 at 17:58
  • Because you modified your post to provide example code, I removed your down vote. – Jeffrey Evans Jan 29 '13 at 21:16

2 Answers2

1

Googling for spatstat as spatialPolygons lead me to this first hit, which is the vignette in spatstat dedicated to handeling shapefiles. It spends a lot of time on how to convert sp-classes into spatstat objects. You might be most interested in section 3.2.5: Objects of class SpatialPolygons and section 3.2.6: Objects of class SpatialPolygonsDataFrame.

Paul Hiemstra
  • 59,984
  • 12
  • 142
  • 149
  • Thank you, but I've already read that (and read it once again^^), and it does not explain what I need. It's about merging existing polygons and not about extracting polygons from self-intercepting segments. – Yollanda Beetroot Jan 28 '13 at 13:29
1

Assuming that you have a set of spatstat objects, you can try something like (untested):

require(sp)

# VECTOR OF spatstat OBJECT NAMES
segs <- (seg1,seg2,seg3)

segPolys <- as(segs[1], "SpatialPolygons")
  for( i in 2:length(segs)) {
    y <- as(segs[i], "SpatialPolygons")
      slot(y[[i]], "ID") <- paste(i)
    segPolys <- c(slot(y, "polygons"),segPolys)
   }
Jeffrey Evans
  • 2,325
  • 12
  • 18
  • Assuming _seg1_, _seg2_ are segments in _segs_ (a _psp_), you cannot convert it in a _SpatialPolygons_ like that. `as(segs[1], "SpatialPolygons")` R answers that there is no methods to do this. Here is the probleme... – Yollanda Beetroot Jan 28 '13 at 20:19
  • Is is exactly what was not clear in your post! It would have been very helpful to know that you had a psp object and wanted to create polygons from intersecting lines. – Jeffrey Evans Jan 28 '13 at 20:54
  • Sorry for this misunderstanding ... So, do you think it is possible ? I searched all day long and still have nothing... – Yollanda Beetroot Jan 28 '13 at 21:24
  • I would start with converting the psp object to SpatialLines and working at it from there. It is a dead end thinking of this as a coercion problem. The rgeos library likely has a functions to generate polygon topology from intersecting lines. You may get a quick answer if you subscribe and post to the RGeo list (http://dir.gmane.org/gmane.comp.lang.r.geo). – Jeffrey Evans Jan 29 '13 at 16:15
  • A quick look at the psp object and I realized that you have the line endpoint coordinates in the "ends" data.frame. Based on the object you create inyour example you can extract the object thus: line.coords <- segset$ends Using this object you can iterate through each row to create your polygons. The sp vignette shows how to create polygons from segment coordinates. – Jeffrey Evans Jan 29 '13 at 21:14
  • Yes I know that, but this (apparently simple but in fact not) require algorithmic skills that I haven't so I hope there was a easy way I hadn't found. Thanks for helping. – Yollanda Beetroot Jan 30 '13 at 07:59