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 求点的近似规则网格的子集的周长 让我们考虑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

解决此问题的一种方法是计算点周围的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.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三角剖分似乎是一个好方法

  • 找到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)