2016-05-25 3 views
0

この質問は、this質問の一般化についてです。上記の質問は、穴のな​​いポイントの設定でうまくいきます。現在の質問では、ポリゴン内のグリッドポイントの一部が欠落しているポイントのほぼ規則的なグリッドのサブセット(つまり、ポリゴンと穴)の周辺(境界線)を取得したいと考えています。いくつかのグリッド(穴)が欠落しているグリッドポイントのセットの外側境界を抽出する

グリッドのサンプルデータセットはhereです。

私は上記の質問(穴がない)の答えとして示唆されているようにRコードを使用しました。

次は、これらのコードを使用しての出力です:plot

今、私はそれがセットポイントの内部に穴を無視して、必要なポリゴンとして設定ポイントの外側の境界を検討する必要がしたいです。

ありがとう。

+0

たぶん(chull)https://stat.ethz.ch/R-manual/R-devel/library/grDevices/html/chull.html – bluefish

+0

@bluefishを助けることができます。過去に私はchulllを使いました。しかし、ポイントが等間隔ではないため、いくつかの境界点が欠けています。したがって、この場合は役に立ちません。 – Janak

+1

うーん、私は問題を見る。穴は正方形に相同であるため、他の質問からの私のアルゴリズムはそれらを境界として認識します。今私はこれが解決... – Spacedman

答えて

1

私の以前のコードでこのわずかな変形は、すべてのループを見つけ、外側だけループでなければならない最大のXと1座標を取ることによって穴があるかどう機能します。ループは触れていない限り...ためにもバグの機能の一つでXとYを使用する必要性を注意してください...厳密おそらくそれは最大の面積を持つループを取る必要がありIGRAPHパッケージに(私が報告してきました)。

perimeterGrid <- function(pts, maxdist=6000, mindist=1){ 
    g = edgeP(makegrid(pts, maxdist=maxdist, mindist=mindist)) 

    ## there might be holes. Find the loop with the largest X coordinate. 
    parts = components(g) 
    outer = which.max(tapply(V(g)$x, parts$membership, function(x){max(x)})) 

    g = induced_subgraph(g, which(parts$membership==outer)) 

    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") 
    ## use X and Y here not x and y due to igraph bug 
    ## these get copied to the output later... 
    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 back 
    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) 
} 
+0

ソリューションは、最初の穴を埋め、その後、私の以前のソリューションを使用するか、穴がデータ上で実行して、真の境界である「境界」のどれを把握することですかどうかわからないんだけど私の問題も、このコードはIGRAPH 1.0.1と協力しています。私はあなたの助けに感謝します。どうもありがとうございました。 – Janak

関連する問題