R 确定给定板条是否属于多边形

R 确定给定板条是否属于多边形,r,point-in-polygon,R,Point In Polygon,假设我有一个名为zone的数据文件,其中1994包含2D坐标的字符串,表示多边形顶点的坐标,如下所示(每行右侧的第一个数字表示zone) c1首先,将多边形定义为矩阵,每行代表一个顶点: poly1 <- rbind(c(1,21), c(31,50), c(45,65), c(75,80)) poly2 <- rbind(c(3,20), c(5,15), c(2,26), c(70,-85)) 这意味着(请参见?pip2d)该点位于poly1外部和poly2内部 注意pip2d

假设我有一个名为
zone
的数据文件,其中
1994
包含
2D
坐标的字符串,表示多边形顶点的坐标,如下所示(每行右侧的第一个数字表示
zone


c1首先,将多边形定义为矩阵,每行代表一个顶点:

poly1 <- rbind(c(1,21), c(31,50), c(45,65), c(75,80))
poly2 <- rbind(c(3,20), c(5,15), c(2,26), c(70,-85))
这意味着(请参见
?pip2d
)该点位于
poly1
外部和
poly2
内部

注意
pip2d
中的
rbind(点)
。我们使用
rbind
,因为我们可以更一般地对同一多边形中的多个点运行测试

如果您需要帮助转换

c1 <- "1 21, 31 50, 45 65, 75 80"
第二版 对于第二个问题,您的数据太大。我能看到的唯一解决方案是将数据分割成更小的部分

但首先,
pip2d
函数似乎也会导致R会话崩溃。因此,请使用另一个函数:
pnt.in.poly
,该函数来自软件包
SDMTools

下面是对该函数的一个小修改,通过删除无用的输出使其更快:

library(SDMTools)
pnt.in.poly2 <- function(pnts, poly.pnts){
  if (poly.pnts[1, 1] == poly.pnts[nrow(poly.pnts), 1] && 
      poly.pnts[1, 2] == poly.pnts[nrow(poly.pnts), 2]){ 
    poly.pnts = poly.pnts[-1, ]
  }
  out = .Call("pip", pnts[, 1], pnts[, 2], nrow(pnts), poly.pnts[,1], poly.pnts[, 2], nrow(poly.pnts), PACKAGE = "SDMTools")
  return(out)
}
现在,运行以下代码:

library(data.table)
for(i in 1:70){
  DT <- data.table(V1 = pnt.in.poly2(lat_lon_list[[i]], polys[[1]]))
  for(j in 2:length(polys)){
    DT[, (sprintf("V%d",j)):=pnt.in.poly2(lat_lon_list[[i]], polys[[j]])]
  }
  fwrite(DT, sprintf("results%02d.csv", i))
  rm(DT)
}

这个问题可能属于
gis.stackexchange
。您可以控制如何定义
c1
c2
?它们总是以
lat-lon,lat-lon,lat-lon,…
的形式出现,还是您可以随意定义它们?相关:@symbolXau:是的,正如您所指出的,它们都是这种格式。该格式中有整个
1614
字符串。当然,我们可以用R中的代码来改变它,对吗?@user177196-Hmm。我测试得很快。我现在将运行代码以查看发生了什么。@user177196查看我的更新。错误出现在
lat_lon_list
中。哦,对不起,我忘了单击“保存编辑”^^^^现在已经完成了。@user177196我崩溃了<代码>错误:无法分配大小为7.6 Mb的向量
。循环一直运行到
j=1422
。对你有用吗?否则我们需要更精细的分割。@user177196大约10分钟,这是第一个文件。更精细的分割工作,但csv文件约2Gb,我无法在Excel中打开它们,因为它们太大了。你能打开吗?
c1 <- "1 21, 31 50, 45 65, 75 80"
poly1 <- rbind(c(1,21), c(31,50), c(45,65), c(75,80))
c1 <- "1 21, 31 50, 45 65, 75 80"

Numextract <- function(string){
  unlist(regmatches(string, gregexpr("[[:digit:]]+\\.*[[:digit:]]*", string)))
}

poly1 <- matrix(as.numeric(Numextract(c1)), ncol=2, byrow=TRUE)
> poly1
     [,1] [,2]
[1,]    1   21
[2,]   31   50
[3,]   45   65
[4,]   75   80
library(SDMTools)
pnt.in.poly2 <- function(pnts, poly.pnts){
  if (poly.pnts[1, 1] == poly.pnts[nrow(poly.pnts), 1] && 
      poly.pnts[1, 2] == poly.pnts[nrow(poly.pnts), 2]){ 
    poly.pnts = poly.pnts[-1, ]
  }
  out = .Call("pip", pnts[, 1], pnts[, 2], nrow(pnts), poly.pnts[,1], poly.pnts[, 2], nrow(poly.pnts), PACKAGE = "SDMTools")
  return(out)
}
lat_lon_list <- vector("list", 70)
for(i in 1:69){
  lat_lon_list[[i]] = lat_lon[(1+(i-1)*1e6):(i*1e6),]
}
lat_lon_list[[70]] <- lat_lon[69000001:nrow(lat_lon),]
library(data.table)
for(i in 1:70){
  DT <- data.table(V1 = pnt.in.poly2(lat_lon_list[[i]], polys[[1]]))
  for(j in 2:length(polys)){
    DT[, (sprintf("V%d",j)):=pnt.in.poly2(lat_lon_list[[i]], polys[[j]])]
  }
  fwrite(DT, sprintf("results%02d.csv", i))
  rm(DT)
}
lat_lon_list <- vector("list", 2*69+1)
for(i in 1:(2*69)){
  lat_lon_list[[i]] = lat_lon[(1+(i-1)*1e6/2):(i*1e6/2),]
}
lat_lon_list[[2*69+1]] <- lat_lon[69000001:nrow(lat_lon),]

for(i in 1:(2*69+1)){
  DT <- data.table(V1 = pnt.in.poly2(lat_lon_list[[i]], polys[[1]]))
  for(j in 2:length(polys)){
    DT[, (sprintf("V%d",j)):=pnt.in.poly2(lat_lon_list[[i]], polys[[j]])]
  }
  fwrite(DT, sprintf("results%02d.csv", i))
  rm(DT)
}