使用gIntersect查找多个SpatialPolygons的成对交集?

时间:2017-04-24 00:53:46

标签: r spatial

我希望生成一个空间对象,其中包含空间多边形列表的所有成对交叉点。手动使用gIntersect只需两层的交叉点很容易,但我想同时找到所有成对交叉点。我有13个多边形,因此有156种不同的对组合来检查重叠。无论是lapply还是for循环似乎都可以工作,但我认为我需要一个包含空间多边形的所有可能组合的矩阵。

以下是数据子样本的要点:

https://gist.github.com/dwwolfson/b1dc7b9c084233a4a36401f7e7061897

以下是我迄今为止所做的尝试:

# Overlap in spring and summer of 2016
library(dplyr)
library(gdata)
library(sp)
library(rgdal)
library(rgeos)
library(raster)
library(spatstat)

#Import Data  (from gist)
df16<-df16.sub
#Extract only locations between April 1 to August 1, 2016
sub16<-df16[df16$loctime>"2016-03-31"&df16$loctime<"2016-08-01",]
#Subset by age
colts.16<-sub16[sub16$age=="colt",]
df<-colts.16
df$id<-as.factor(df$id)

#extract coordinates
coordinates(df)<-c("location.long", "location.lat")
#define coordinate ref system
proj4string(df)<-CRS("+proj=longlat +datum=WGS84")
#reproject
df<-spTransform(df, CRS("+proj=aea +lat_1=29.5 +lat_2=45.5 +lat_0=37.5
                        +lon_0=-96 +x_0=0 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m +no_defs "))
colnames(df@coords)<-c("x", "y")
sp.df<-as.data.frame(df)
crane.names<-as.list(unique(sp.df$id))
testdat<-sp.df

temp.crane<-NULL
temp.crane.day<-NULL
dat.summary<-NULL
tempdat<-NULL
firstday<-NULL
lastday<-NULL
dat.summary<-NULL
i<-NULL
j<-NULL
#loop to condense points into just roost sites
for(i in 1:length(unique(testdat$id))){
  temp.crane<-testdat[testdat$id==crane.names[[i]],]
  if(nrow(temp.crane)>0){
    current.crane<-as.character(crane.names[[i]])
    temp.days<-as.list(unique(temp.crane$day))
    days.vec<-unlist(temp.days)
    firstday<-days.vec[1]
    lastday<-last(days.vec)
    for(j in seq.int(from=firstday, to=lastday)){
      tempdat<-temp.crane[which(temp.crane$day==j),]    
      firstrow<-tempdat[1,]
      lastrow<-tempdat[nrow(tempdat),]
      daylocs<-rbind(firstrow, lastrow)

      if((j-1)<firstday)
      {daylocs$night.dist<-NA}
      else{
        prevdat<-temp.crane[which(temp.crane$day==j-1),]    
        firstrow<-prevdat[1,]
        lastrow<-prevdat[nrow(prevdat),]
        prevdaylocs<-rbind(firstrow, lastrow)

        daylocs$night.dist<-sqrt((daylocs$x[1]-prevdaylocs$x[2])^2+(daylocs$y[1]-prevdaylocs$y[2])^2)
      }
            dat.summary<-rbind(dat.summary, daylocs)
          }
  }
}

roosts<-dat.summary
temp.buffer<-NULL
temp.crane<-NULL
current.crane<-NULL
temp.id<-NULL
temp.sp.df<-NULL
buff.spdf<-NULL
crane.names<-as.list(unique(roosts$id))
test<-NULL
#create list of SpatialPolygons
for(i in 1:length(unique(roosts$id))){
  temp.crane<-roosts[roosts$id==crane.names[[i]],]
  current.crane<-as.character(crane.names[[i]])
  coordinates(temp.crane)<-c("x","y")
  proj4string(temp.crane)<-CRS("+proj=aea +lat_1=29.5 +lat_2=45.5 +lat_0=37.5
                          +lon_0=-96 +x_0=0 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m +no_defs ")
  temp.buffer<-gBuffer(temp.crane, width=3000)
  test[i]<-list(temp.buffer)
}

我尝试使用combn()函数调整有关某些事情的问题,其中test是一个空间多边形列表:

combos1<-combn(test,2)
for(k in length(combos1)){
i<-combos[1,k]
j<-combos[2,k]
print(paste("intersecting", i, j))
int[k]<-gIntersection(i,j, byid=T)
}

我收到以下错误消息:

Error in identical(spgeom1@proj4string, spgeom2@proj4string) :                         
trying to get slot "proj4string" from an object of a basic class ("list") with no slots

以下不会产生错误,但在ArcMap的目视检查中,它并没有得到所有重叠的情况,可能只是最后一轮。

   overlap<-list()
for(i in length(test)){
for(j in length(test)){
overlap<-gIntersection(test[[i]],test[[j]])
} 
}

我认为我的问题是我需要&#34; rbind&#34;或者将每次迭代中的所有空间多边形对象合并到一个列表中。也许如果我首先创建SpatialPolygonDataframes而不是SpatialPolygons,它会更容易组合?我还需要避免i和j是相同的数字,否则我会得到相同的多边形重叠。

我尝试使用以下代码将每个迭代的重叠存储到空间对象列表中,但是第一次运行时spRbind会阻塞,因为用于存储结果的对象从NULL开始,我认为。

library(maptools)
over.list<-NULL

for(i in length(test)){
for(j in length(test)){
overlap<-gIntersection(test[[i]],test[[j]])
over.list<-spRbind(over.list, overlap)
} 
}

1 个答案:

答案 0 :(得分:0)

您构建test的方式非常特别。这不是一个Spatial对象,因此特别使用...
您使用combn的方式不正确。它不能使用这样的对象列表。文档说:

  

?combn
  组合的x向量源,或x < - seq_len(n)的整数n。

所以你应该按原样使用它。 您提供的示例和数据不容易按原样使用。我不得不修改不同的东西。下次,您应该提供一个与您的数据问题相对应的简单示例。请参阅:How to make a great R reproducible example?
据我所知,从你的看法来看,我建议你一个可行的方法。但是你需要了解R中SpatialPolygons个对象的组织是什么,以使你的脚本更清晰。

所以在这里,我以可用的方式使用combn。我像你一样检索列表中的所有多边形交叉点。当交集不是NULL时,我也将其检索为Polygons对象,以便能够将所有多边形收集为SpatialPolygons

combos <- combn(length(test),2)
int <- vector("list", length = ncol(combos))
Polygons.list <- list()
k.poly <- 0 # Number of non-null polygons
for(k in 1:ncol(combos)){
  i<-combos[1,k]
  j<-combos[2,k]
  print(paste("intersecting", i, j))
  int.tmp <- gIntersection(test[[i]],test[[j]], byid=FALSE)
  if (!is.null(int.tmp)) {
    k.poly <- k.poly + 1
    int[[k]] <- int.tmp
    Polygons.list[[k.poly]] <- int[[k]]@polygons[[1]]
    Polygons.list[[k.poly]]@ID <- paste(k.poly)
  }
}

all.Intersections <- SpatialPolygons(Polygons.list)
plot(all.Intersections, col = "red")