buffer e unione in R senza riduzione in un poligono multiplo


9

Vorrei eseguire una sovrapposizione spaziale per identificare il poligono all'interno del quale rientrano una serie di punti. Tuttavia, per prima cosa voglio bufferizzare e dissolvere i poligoni, in modo tale che i punti che ricadono ovunque all'interno dei poligoni uniti (ma non all'interno di alcun foro) saranno etichettati in modo simile dalla procedura di sovrapposizione.

Sfortunatamente, il processo di buffering e / o dissolvenza che sto usando sta riducendo l' SpatialPolygonsoggetto a un poligono. L'uso di gBuffercrea un poligono multiplo quando byid=FALSE, ma non riesce a unire poligoni sovrapposti quando byid=TRUE. In quest'ultimo caso, la successiva dissoluzione dei poligoni con gUnaryUnionnuovamente crea un poligono. La sovrapposizione SpatialPointscon questi poligonali comporta la segnalazione di tutti i punti contenuti come rientranti nel poligono 1.

Ecco un esempio di giocattolo correlato con punti bufferizzati, in cui mi piacerebbe fare una sovrapposizione dei punti con i poligoni bufferati:

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)

inserisci qui la descrizione dell'immagine

E i risultati di alcuni overlay ...

  • Con byid=FALSE:

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

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

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

Sto cercando il metodo corretto per ottenere il risultato 1 1 1 2, ovvero i punti 1, 2 e 3 rientrano nel poligono 1 (precedentemente poligoni 1, 2 e 3, che sono stati uniti) e il punto 4 rientra nel poligono 2 (originariamente poligono 4 ).


MODIFICARE

I miei dati reali includono buchi, e idealmente mi piacerebbe essere in grado di conservarli. Ho aggiornato i dati di esempio sopra per includere un buco dopo il buffering.

Applicando l'approccio di @ JeffreyEvans a questi polis:

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))) 

risulta in:

over(pts, b.exploded)

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

che è il risultato atteso (non sono troppo agitato per il poli ordine - 2,2,2,1vs. 1,1,1,2), ma b.explodedha perso le informazioni sul buco, invece di rappresentarlo come un poligono non buco. Ovviamente non influisce sul risultato dell'esempio di giocattolo, ma una sovrapposizione che coinvolge punti situati nel foro sarà fuorviante, ad esempio:

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

Risposte:


7

Si scopre che sp::disaggregatepuò essere usato per separare i poligoni a parte singola.

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::aggregatepuò essere usato per combinarli di nuovo.)


3

Sono comprensivo, questo è un po 'doloroso. Devi far esplodere gli slot, dell'oggetto poligono gBuffer, in singoli poligoni.

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)

Ho appena testato e sembra promettente, ma i miei buchi non sono più buchi :(. Possiamo adattare questo per mantenere i buchi insieme ai polis a cui sono associati? (Mi stavo muovendo in modo simile al tuo suggerimento, con n <- length(buff@polygons[[1]]@Polygons); SpatialPolygons(mapply(function(x, y) Polygons(list(x), y), buff@polygons[[1]]@Polygons, seq_len(n)))... Avrei dovuto menzionare il problema del buco nel post, scusa.
jbaums
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.