シェイプファイルがあり、他のポリゴンにどのポリゴンが接触するかを各ポリゴンについて知りたい。その目的のために私はこのコードを持っています:複数のポリゴン間の共有境界の長さを計算する
require("rgdal")
require("rgeos")
download.file("https://www.dropbox.com/s/vbxx9dic34qwz63/Polygons.zip?dl=1", "Polygons.zip")
Shapefile <- readOGR(".","Polygons")
Touching_List <- gTouches(Shapefile, byid = TRUE, returnDense=FALSE)
Touching_DF <- setNames(stack(lapply(Touching_List, as.character)), c("TOUCHING", "ORIGIN"))
ここで、各ポリゴンが他のポリゴンに触れている程度をさらに理解したいと思います。 Touching_DF
の各行の後ろには、ORIGIN
ポリゴンの合計長さ/周囲長と、各TOUCHING
ポリゴンが元のポリゴンに接触している全長があります。これにより、共有境界のパーセンテージが計算されます。私はこれの出力がTouching_DF
の3つの新しい列であると想像することができます(例えば、最初の行については、原点パラメータ1000m、長さ500mに触れる、共有境界50%)。ありがとう。私は私の本当のデータセットにStatnMapの答え@適用されている1
EDIT。ポリゴンがエッジとポイントの両方を共有する場合、gTouches
は結果を返すように見えます。これらのポイントは長さがないため問題を引き起こしています。 StatnMapのコード部分を修正しましたが、最後にデータフレームを作成する場合は、共有エッジ/頂点の数gTouchesが返す値と、長さがあるエッジの数の不一致があります。ここで
は私の実際のデータセットのサンプルを使用して、問題を実証するためのいくつかのコードです:
library(rgdal)
library(rgeos)
library(sp)
library(raster)
download.file("https://www.dropbox.com/s/hsnrdfthut6klqn/Sample.zip?dl=1", "Sample.zip")
unzip("Sample.zip")
Shapefile <- readOGR(".","Sample")
Touching_List <- gTouches(Shapefile, byid = TRUE, returnDense=FALSE)
# ---- Calculate perimeters of all polygons ----
perimeters <- sp::SpatialLinesLengths(as(Shapefile, "SpatialLines"))
# ---- All in a lapply loop ----
all.length.list <- lapply(1:length(Touching_List), function(from) {
lines <- rgeos::gIntersection(Shapefile[from,], Shapefile[Touching_List[[from]],], byid = TRUE)
if(class(lines) != "SpatialLines"){lines <- [email protected]}
l_lines <- sp::SpatialLinesLengths(lines, longlat=FALSE)
results <- data.frame(origin = from,
perimeter = perimeters[from],
touching = Touching_List[[from]],
t.length = l_lines,
t.pc = 100*l_lines/perimeters[from])
results
})
これは、特にポリゴンのいずれかの問題を示しています
from <- 4
lines <- rgeos::gIntersection(Shapefile[from,], Shapefile[Touching_List[[from]],], byid = TRUE)
if(class(lines) != "SpatialLines"){lines <- [email protected]}
l_lines <- sp::SpatialLinesLengths(lines, longlat=FALSE)
plot(Shapefile[c(from, Touching_List[[from]]),])
plot(lines, add = TRUE, col = 1 + 1:length(Touching_List[[from]]), lwd = 2)
2つの解決策I 1. gTouchesに0または2より大きい長さの共有エッジのみを返すようにする。エッジではなくポイントに遭遇したときにエラーの代わりにゼロの長さを返す。これまでのところ、私はこれらのことのいずれかを行うことはできません。 StatnMapの改訂ソリューション@
EDIT 2
は素晴らしい作品。しかし、ポリゴンはその隣接ポリゴンとスナップ国境を共有していない場合(すなわち、それがポイントになり、その後、島のスリザーリンクのポリゴンを作成します)、それは私が探しているlines <- rgeos::gIntersection(Shapefile[from,], Shapefile[Touching_List[[from]],], byid = TRUE)
Error in RGEOSBinTopoFunc(spgeom1, spgeom2, byid, id, drop_lower_td, unaryUnion_if_byid_false, :
Geometry collections may not contain other geometry collections
した後に、このエラーを思い付きます境界線がひどく描画されたポリゴンを特定できず、計算を実行せずにres
に 'NA'を戻すことができるソリューション(これは後で識別することができます)。しかし、問題の多いポリゴンを「通常の」ポリゴンと区別するコマンドを見つけることができませんでした。これら8つのポリゴンとStatnMapの改訂ソリューション@実行
は、問題を示しています
download.file("https://www.dropbox.com/s/ttg2mi2nq1gbbrq/Bad_Polygon.zip?dl=1", "Bad_Polygon.zip")
unzip("Bad_Polygon.zip")
Shapefile <- readOGR(".","Bad_Polygon")
ありがとうございます。私のサンプルデータに基づいて、私は正確に何をしています。しかし、私はあなたのソリューションを私の「本当の」データセットに適用していくつかの問題に遭遇しました。私は私の質問を編集して、私の言いたいことを示しました。 – Chris
私はこのケースを説明するために私の答えを編集しました。 –
ありがとうございます。あなたのコードは完全に機能します。私の現在の唯一の問題は、入力ポリゴンのいくつかがひどく描画されていることです。私はこれについて何もすることはできませんので、ドッジポリゴンをスキップする(つまりresでNAを返す)か、Slither islandポリゴンに対処できる解決法を見つける必要があります。最初のオプションは私にとっては良い解決策のようですが、私は 'rgeos :: gIntersection(Shapefile [n、]、Shapefile [Touching_List [[n]]、byid = TRUE)'の前にifステートメントを見つけることができません。問題のポリゴンを特定できるようにする。私は8つのポリゴンの小さなセットを私の質問に追加して、私が意味することを実証しました。 – Chris