буфер и объединение в R без редукции до многогранника

9

Я хотел бы выполнить пространственное наложение, чтобы идентифицировать полигон, в который попадает набор точек. Однако сначала я хочу буферизовать и растворить многоугольники, чтобы точки, падающие где-либо внутри объединенных многоугольников (но не внутри каких-либо отверстий), были помечены аналогично с помощью процедуры наложения.

К сожалению, процесс буферизации и / или растворения, который я использую, сводит SpatialPolygonsобъект к многоугольнику. Использование gBufferсоздает многоугольник, когда byid=FALSE, но не может объединить перекрывающиеся полигоны, когда byid=TRUE. В последнем случае последующее растворение многоугольников gUnaryUnionснова создает многоугольник. Наложение SpatialPointsэтих многоугольников приводит к тому, что все содержащиеся точки попадают в полигон 1.

Вот похожий пример игрушки с буферизованными точками, где я хотел бы сделать наложение точек с буферизованными полигонами:

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)

введите описание изображения здесь

И результаты некоторых оверлеев ...

  • С byid=FALSE:

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

    b2 <- gBuffer(pts, width=0.6, byid=TRUE) 
    over(pts, b2)
    # [1] 1 2 3 4
  • С byid=TRUEи последующим gUnaryUnion:

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

Я ищу правильный метод для достижения результата 1 1 1 2, то есть точки 1, 2 и 3 попадают в полигон 1 (ранее были объединены полигоны 1, 2 и 3), а точка 4 попадает в полигон 2 (первоначально полигон 4). ).


РЕДАКТИРОВАТЬ

Мои настоящие данные включают дыры, и в идеале я бы хотел сохранить их. Я обновил данные примера выше, чтобы включить дыру после буферизации.

Применение подхода @ JeffreyEvans к этим полисам:

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

результаты в:

over(pts, b.exploded)

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

это ожидаемый результат (я не слишком беспокоюсь о поли-порядке - 2,2,2,1против 1,1,1,2), но b.explodedпотерял информацию о дыре, вместо этого представив ее как многоугольник без дыр. Очевидно, это не влияет на результат для примера с игрушкой, но наложение, включающее точки, расположенные в отверстии, будет вводить в заблуждение, например:

in_hole <- SpatialPoints(cbind(1.375, 1.5))
over(in_hole, b.exploded)
#   FID
# 1   2
jbaums
источник

Ответы:

7

Оказывается, что sp::disaggregateможно использовать, чтобы разделить отдельные части полигонов.

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::aggregateможно использовать, чтобы объединить их снова.)

jbaums
источник
3

Я сочувствую, это немного боли. Вы должны разбить слоты объекта полигона gBuffer на отдельные полигоны.

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)
Джеффри Эванс
источник
Только что проверил и кажется многообещающим, но мои дыры больше не дыры :(. Можем ли мы адаптировать это, чтобы держать дыры вместе с полисами, с которыми они связаны? (Я шел в том же духе, что и ваше предложение, с n <- length(buff@polygons[[1]]@Polygons); SpatialPolygons(mapply(function(x, y) Polygons(list(x), y), buff@polygons[[1]]@Polygons, seq_len(n)))... Я должен был упомянуть проблему дыр в посте, извините.
Jbaums