R 求点的近似规则网格的子集的周长 让我们考虑2-D中的一组近似规则网格。这些网格是相邻的(相邻网格有一个或多个相同顶点)到相邻网格。下面是10个网格的示例,其顶点坐标(经度、纬度)如下所示 A<- lon lat [,1] [,2] [1,] 85.30754 27.91250 [2,] 85.32862 27.95735 [3,] 85.34622 27.89880 [4,] 85.36732 27.94364 [5,] 85.34958 28.00202 [6,] 85.38831 27.98830 [7,] 85.38487 27.88508 [8,] 85.40598 27.92991 [9,] 85.42353 27.87134 [10,] 85.44466 27.91616 [11,] 85.42698 27.97456 [12,] 85.46567 27.96081 [13,] 85.48334 27.90239 [14,] 85.50437 27.94703 [15,] 85.48645 28.00502 [16,] 85.52517 27.99123 [17,] 85.52198 27.88862 [18,] 85.54302 27.93325 [19,] 85.56384 27.97745 A
解决此问题的一种方法是计算点周围的alpha外壳R 求点的近似规则网格的子集的周长 让我们考虑2-D中的一组近似规则网格。这些网格是相邻的(相邻网格有一个或多个相同顶点)到相邻网格。下面是10个网格的示例,其顶点坐标(经度、纬度)如下所示 A<- lon lat [,1] [,2] [1,] 85.30754 27.91250 [2,] 85.32862 27.95735 [3,] 85.34622 27.89880 [4,] 85.36732 27.94364 [5,] 85.34958 28.00202 [6,] 85.38831 27.98830 [7,] 85.38487 27.88508 [8,] 85.40598 27.92991 [9,] 85.42353 27.87134 [10,] 85.44466 27.91616 [11,] 85.42698 27.97456 [12,] 85.46567 27.96081 [13,] 85.48334 27.90239 [14,] 85.50437 27.94703 [15,] 85.48645 28.00502 [16,] 85.52517 27.99123 [17,] 85.52198 27.88862 [18,] 85.54302 27.93325 [19,] 85.56384 27.97745 A,r,computational-geometry,r-grid,R,Computational Geometry,R Grid,解决此问题的一种方法是计算点周围的alpha外壳 alphahull软件包可以做到这一点。该软件包有优秀的文档,包括动画,在 非常值得一看本文档,特别是为了理解alpha参数的含义 首先,复制您的数据 A <- read.table(header=TRUE, text=" lon lat [1,] 85.30754 27.91250 [2,] 85.32862 27.95735 [3,] 85.34622 27.89880 [4,] 85.36732 27.94364 [5,] 85
alphahull
软件包可以做到这一点。该软件包有优秀的文档,包括动画,在
非常值得一看本文档,特别是为了理解alpha
参数的含义
首先,复制您的数据
A <- read.table(header=TRUE, text="
lon lat
[1,] 85.30754 27.91250
[2,] 85.32862 27.95735
[3,] 85.34622 27.89880
[4,] 85.36732 27.94364
[5,] 85.34958 28.00202
[6,] 85.38831 27.98830
[7,] 85.38487 27.88508
[8,] 85.40598 27.92991
[9,] 85.42353 27.87134
[10,] 85.44466 27.91616
[11,] 85.42698 27.97456
[12,] 85.46567 27.96081
[13,] 85.48334 27.90239
[14,] 85.50437 27.94703
[15,] 85.48645 28.00502
[16,] 85.52517 27.99123
[17,] 85.52198 27.88862
[18,] 85.54302 27.93325
[19,] 85.56384 27.97745")
轮廓:所有接近6000m的点对以网格正方形的形式形成图形。构造该图,然后找到所有与正方形同构的子图(大小为4的循环)。外部边的出现频率将低于内部边,因为它们只是一个正方形的一部分(内部边由多个正方形共享)。因此,找到所有内部边并将其放下,然后遍历生成的图,该图应该是一个简单的循环 代码: 结果: 警告:
这是未经测试的网格碎片与孔或网格单元只接触在一个角点。也许这不会发生。此外,我不确定算法的效率,但它似乎非常快。因为点集是一个网格,或者至少非常接近网格,所以使用Delaunay三角剖分似乎是一个好方法
性能应该是
O(N log N)
感谢您的关注和努力来回答我的问题。由于我的数据点不是完全等距的,而且点集的形状非常不规则,我观察到“allphahull”经常漏掉一些边界点。您正确地指出,由于上一个数据处理阶段的一些限制,在我的数据集中,带孔的网格碎片或网格单元仅接触一个角点,因此无法出现。我已经将你的代码用于许多示例。它工作得很好。谢谢你的帮助。再次感谢。我很确定有更简单的方法。1) 删除所有具有4个邻居且邻居次数之和大于等于12的顶点。2) 删除两个顶点的阶数均为3的任何边。它取代了所有同构的东西。1) 这很简单,我找不到一个简单的方法……我刚刚给出了一个基于Delaunay三角剖分的解决方案。虽然我没有包含代码。看起来很像你在评论中的建议。嗨,Spacedman。我又来了。现在,我正在尝试获得轮廓多边形,并且允许多边形内的孔。请您建议修改现有代码以适应这个漏洞。@Janak对此提出一个新问题,并尝试给出一些说明新问题的示例数据。还显示我的代码解决方案如何解决该问题失败…感谢您的回答。我将努力实现你的想法。
library("alphahull")
hull <- with(A, ahull(lat, lon, alpha=0.033))
plot(hull)
library(igraph); library(geosphere)
# main function
perimeterGrid <- function(pts, maxdist=6000, mindist=1){
g = edgeP(makegrid(pts, maxdist=maxdist, mindist=mindist))
loop = graph.dfs(minimum.spanning.tree(g),1)$order
cbind(V(g)$x, V(g)$y)[loop,]
}
# haversine distance matrix
dmat <- function(pts){
n=nrow(pts)
do.call(rbind,lapply(1:n,function(i){distHaversine(pts[i,],pts)}))
}
# make the grid cells given a maxdist (and a mindist to stop self-self edges)
makegrid <- function(pts, maxdist=6000, mindist=1){
dists = dmat(pts)
g = graph.adjacency(dists<maxdist & dists>mindist,
mode="undirected")
V(g)$x=pts[,1]
V(g)$y=pts[,2]
g
}
# clever function that does the grid edge count etc
edgeP <- function(g){
# find all the simple squares
square=graph.ring(4)
subs = graph.get.subisomorphisms.vf2(g,square)
# expand all the edges
subs = do.call(rbind, lapply(subs, function(s){
rbind(s[1:2], s[2:3], s[3:4], s[c(4,1)])
}))
# make new graph of the edges of all the squares
e = graph.edgelist(subs,directed=FALSE)
# add the weight as the edge count
E(e)$weight=count.multiple(e)
# copy the coords from the source
V(e)$x=V(g)$x
V(e)$y=V(g)$y
# remove multiple edges
e=simplify(e)
# internal edges now have weight 256.
e = e - edges(which(E(e)$weight==256))
# internal nodes how have degree 0
e = e - vertices(degree(e)==0)
return(e)
}
plot(pts)
polygon(perimeterGrid(pts),lwd=2)