我有一個shapefile,我想知道每個多邊形還有哪些其他多邊形接觸它。爲此我有這樣的代碼:計算多個多邊形之間共享邊界的長度
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_DF
中的3個新列(例如,對於第一行,它可以是起始參數1000m,觸摸長度500m,共享邊界50%)。謝謝。
編輯1
我已經申請@ StatnMap的回答讓我真正的數據集。看起來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)
兩個可能的解決方案我請參閱1.獲取gTouches僅返回長度大於零的共享邊,或2.返回長度爲零(而不是錯誤),當遇到點而不是邊時。到目前爲止,我找不到任何可以做這些事情的事情。
EDIT 2
@ StatnMap修訂後的解決方案的偉大工程。但是,如果多邊形不與它相鄰的多邊形共享抓拍邊界(即它關係到一個點,然後創建一個島嶼滑行多邊形),則與此錯誤後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」(因此它們仍然可以在稍後識別)的解決方案。但是,我一直無法找到一個區分這些有問題的多邊形與「正常」多邊形的命令。
運行@ StatnMap與這些多邊形8修訂後的解決方案演示了這個問題:
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
我編輯了我的答案來解釋這種情況。 –
謝謝。你的代碼完美地工作。我現在唯一的問題是一些輸入多邊形被嚴重繪製。我無法對此做任何事情,所以我需要找到一個解決方案,它可以跳過不規則的多邊形(即,在資源庫中返回NA),或者可以處理滑動的島多邊形。第一個選項似乎是一個更好的解決方案,我只是在'rgeos :: gIntersection(Shapefile [n,],Shapefile [Touching_List [[n]],],byid = TRUE)'之前找不到if語句'能夠識別問題多邊形。我在我的問題中添加了一小組8個多邊形來展示我的意思。 – Chris