buffer e união em R sem reduzir para um multi-polígono

9

Eu gostaria de realizar uma sobreposição espacial para identificar o polígono no qual um conjunto de pontos se enquadra. No entanto, primeiro quero tamponar e dissolver os polígonos, de modo que os pontos que caem em qualquer lugar dentro dos polígonos mesclados (mas não dentro de quaisquer furos) sejam rotulados de forma semelhante pelo procedimento de sobreposição.

Infelizmente, o processo de buffer e / ou dissolução que estou usando está reduzindo o SpatialPolygonsobjeto a um multi-polígono. O uso gBuffercria um multi-polígono quando byid=FALSE, mas falha ao unir polígonos sobrepostos quando byid=TRUE. No último caso, a dissolução subsequente de polígonos gUnaryUnioncria novamente um multi-polígono. A sobreposição SpatialPointscom esses poligramas múltiplos faz com que todos os pontos contidos sejam relatados como pertencentes ao polígono 1.

Aqui está um exemplo de brinquedo relacionado a pontos com buffer, onde eu gostaria de fazer uma sobreposição dos pontos com os polígonos com buffer:

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)

insira a descrição da imagem aqui

E os resultados de algumas sobreposições ...

  • Com byid=FALSE:

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

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

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

Estou procurando o método correto para obter o resultado 1 1 1 2, ou seja, os pontos 1, 2 e 3 se enquadram no polígono 1 (anteriormente polígonos 1, 2 e 3, que foram mesclados) e o ponto 4 se enquadra no polígono 2 (originalmente polígono 4 )


EDITAR

Meus dados verdadeiros incluem buracos e, idealmente, eu gostaria de poder conservá-los. Atualizei os dados de exemplo acima para incluir um furo após o buffer.

Aplicando a abordagem de @ JeffreyEvans a essas políticas:

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

resulta em:

over(pts, b.exploded)

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

que é o resultado esperado (não estou muito preocupado com a ordem poli - 2,2,2,1vs. 1,1,1,2), mas b.explodedperdi as informações sobre o furo, em vez de representá-lo como um polígono que não é do furo. Obviamente, isso não afeta o resultado do exemplo de brinquedo, mas uma sobreposição envolvendo pontos localizados no furo será enganosa, por exemplo:

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

Respostas:

7

Acontece que sp::disaggregatepode ser usado para separar os polígonos de parte única.

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::aggregatepode ser usado para combiná-los novamente.)

jbaums
fonte
3

Sou solidário, isso é um pouco doloroso. Você precisa explodir os slots, do objeto polígono gBuffer, em polígonos individuais.

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
fonte
Acabei de testar e parece promissor, mas meus buracos não são mais buracos :(. Podemos adaptar isso para manter os orifícios junto com os polys aos quais estão associados? (Eu estava indo ao longo de linhas semelhantes como a sua sugestão, com n <- length(buff@polygons[[1]]@Polygons); SpatialPolygons(mapply(function(x, y) Polygons(list(x), y), buff@polygons[[1]]@Polygons, seq_len(n)))... Eu deveria ter mencionado o problema buraco no post, desculpe.
jbaums