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)
}