penyangga dan penyatuan dalam R tanpa mengurangi ke multi-poligon

9

Saya ingin melakukan overlay spasial untuk mengidentifikasi poligon di mana satu set titik jatuh. Namun saya pertama-tama ingin buffer dan melarutkan poligon, sehingga poin jatuh di mana saja di dalam poligon gabungan (tetapi tidak dalam lubang) akan diberi label yang sama dengan prosedur overlay.

Sayangnya, proses buffering dan / atau pelarutan yang saya gunakan adalah mengurangi SpatialPolygonsobjek menjadi multi-poligon. Menggunakan gBuffermenciptakan multi-poligon kapan byid=FALSE, tetapi gagal untuk menyatukan tumpang tindih poligon saat byid=TRUE. Dalam kasus terakhir, selanjutnya melarutkan poligon dengan gUnaryUnionlagi menciptakan multi-poligon. Overlay SpatialPointsdengan hasil multi-poligon ini di semua titik yang terkandung dilaporkan termasuk dalam poligon 1.

Berikut ini contoh mainan terkait dengan titik buffer, di mana saya ingin melakukan overlay poin dengan poligon buffered:

library(sp)
library(rgeos)
pts <- SpatialPoints(cbind(c(1, 1, 2, 3), c(1, 2, 1.5, 2.5))) 
plot(gBuffer(pts, width=0.6), lwd=2)
points(pts, pch=20, cex=2)
text(coordinates(pts), labels=seq_len(length(pts)), pos=4, font=2)

masukkan deskripsi gambar di sini

Dan hasil dari beberapa overlay ...

  • Dengan byid=FALSE:

    b <- gBuffer(pts, width=0.6) 
    over(pts, b)
    # [1] 1 1 1 1
    
  • Dengan byid=TRUE:

    b2 <- gBuffer(pts, width=0.6, byid=TRUE) 
    over(pts, b2)
    # [1] 1 2 3 4
    
  • Dengan byid=TRUEdan selanjutnya gUnaryUnion:

    b3 <- gUnaryUnion(b2)
    over(pts, b3)
    # [1] 1 1 1 1
    

Saya mencari metode yang benar untuk mencapai hasil 1 1 1 2, yaitu poin 1, 2 dan 3 termasuk dalam poligon 1 (sebelumnya poligon 1, 2, dan 3, yang telah digabung), dan titik 4 termasuk dalam poligon 2 (awalnya poligon 4 ).


EDIT

Data saya yang sebenarnya termasuk lubang, dan idealnya saya ingin dapat melestarikannya. Saya telah memperbarui contoh data di atas untuk memasukkan lubang setelah buffering.

Menerapkan pendekatan @ JeffreyEvans untuk polis ini:

polys <- b@polygons[[1]]@Polygons
pl <- vector("list", length(polys))
for (i in 1:length(polys)) { pl[i] <- Polygons(list(polys[[i]]), i) }
b.spolys <- SpatialPolygons(pl)
row.ids <- sapply(slot(b.spolys, "polygons"), function(i) slot(i, "ID"))    
b.exploded <- SpatialPolygonsDataFrame(b.spolys, data.frame(FID=as.numeric(row.ids))) 

menghasilkan:

over(pts, b.exploded)

#   FID
# 1   2
# 2   2
# 3   2
# 4   1

yang merupakan hasil yang diharapkan (saya tidak terlalu sibuk tentang urutan poli - 2,2,2,1vs 1,1,1,2), tetapi b.explodedtelah kehilangan informasi tentang lubang, sebaliknya menyatakannya sebagai poligon non-lubang. Ini jelas tidak mempengaruhi hasil untuk contoh mainan, tetapi hamparan yang melibatkan titik-titik yang terletak di lubang akan menyesatkan, misalnya:

in_hole <- SpatialPoints(cbind(1.375, 1.5))
over(in_hole, b.exploded)
#   FID
# 1   2
jbaums
sumber

Jawaban:

7

Ternyata itu sp::disaggregatebisa digunakan untuk memisahkan poligon singlepart.

pts <- SpatialPoints(cbind(c(1, 1, 2, 3), c(1, 2, 1.5, 2.5))) 
b <- gBuffer(pts, width=0.6) 
over(pts, disaggregate(b))

# [1] 1 1 1 2

in_hole <- SpatialPoints(cbind(1.375, 1.5))
over(in_hole, disaggregate(b))

# [1] NA

( raster::aggregatedapat digunakan untuk menggabungkannya lagi.)

jbaums
sumber
3

Saya simpatik, ini agak menyebalkan. Anda harus meledakkan slot, dari objek poligon gBuffer, menjadi poligon individual.

require(sp)
require(rgeos)
pts <- SpatialPoints(cbind(c(1, 1, 3), c(1, 2, 3))) 

b <- gBuffer(pts, width=0.6)

over(pts, b)

###########################################################
# explodes slots into individual polygons
polys <- b@polygons[[1]]@Polygons
  pl <- vector("list", length(polys))
    for (i in 1:length(polys)) { pl[i] <- Polygons(list(polys[[i]]), i) }
      b.spolys <- SpatialPolygons(pl)
        row.ids=sapply(slot(b.spolys, "polygons"), function(i) slot(i, "ID"))    
b <- SpatialPolygonsDataFrame(b.spolys, data.frame(FID=as.numeric(row.ids)) ) 
###########################################################

over(pts, b)
Jeffrey Evans
sumber
Baru saja diuji dan tampaknya menjanjikan, tetapi lubang saya tidak lagi lubang :(. Bisakah kita mengadaptasi ini untuk menjaga lubang bersama dengan polis yang terkait dengannya? (Saya sedang menuju garis yang sama seperti saran Anda, dengan n <- length(buff@polygons[[1]]@Polygons); SpatialPolygons(mapply(function(x, y) Polygons(list(x), y), buff@polygons[[1]]@Polygons, seq_len(n)))... Saya seharusnya menyebutkan masalah lubang di pos, maaf.
jbaums