bufor i zjednoczenie w R bez redukowania do wieloboku

9

Chciałbym wykonać nakładkę przestrzenną, aby zidentyfikować wielokąt, w którym mieści się zbiór punktów. Najpierw jednak chcę buforować i rozpuszczać wielokąty, tak aby punkty mieszczące się w dowolnym miejscu w połączonych wielokątach (ale nie w żadnych dziurach) zostaną podobnie oznaczone za pomocą procedury nakładania.

Niestety proces buforowania i / lub rozpuszczania, którego używam, redukuje SpatialPolygonsobiekt do wieloboku. Użycie gBufferpowoduje utworzenie wielokąta kiedy byid=FALSE, ale nie powoduje połączenia nakładających się wielokątów kiedy byid=TRUE. W tym drugim przypadku rozpuszczenie wielokątów gUnaryUnionponownie powoduje powstanie wieloboku. Nałożenie SpatialPointstych wieloboków powoduje, że wszystkie zawarte punkty są zgłaszane jako mieszczące się w wielokącie 1.

Oto pokrewny przykład zabawki z buforowanymi punktami, w którym chciałbym wykonać nakładkę punktów na buforowane wielokąty:

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)

wprowadź opis zdjęcia tutaj

I wyniki niektórych nakładek ...

  • Z byid=FALSE:

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

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

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

Szukam właściwej metody, aby osiągnąć wynik 1 1 1 2, tj. Punkty 1, 2 i 3 mieszczą się w wielokącie 1 (wcześniej wielokąty 1, 2 i 3, które zostały połączone), a punkt 4 mieści się w wielokącie 2 (pierwotnie wielokąt 4 ).


EDYTOWAĆ

Moje prawdziwe dane obejmują dziury i idealnie chciałbym móc je zachować. Zaktualizowałem przykładowe dane powyżej, aby uwzględnić dziurę po buforowaniu.

Zastosowanie podejścia @ JeffreyEvans do tych 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))) 

prowadzi do:

over(pts, b.exploded)

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

co jest oczekiwanym rezultatem (nie jestem zbytnio rozkojarzony porządkiem poli - 2,2,2,1vs. 1,1,1,2), ale b.explodedstraciłem informacje o dziurze, reprezentując ją zamiast wielokąta nie-dziury. Oczywiście nie wpływa to na wynik dla przykładu zabawki, ale nakładka obejmująca punkty znajdujące się w otworze będzie myląca, np .:

in_hole <- SpatialPoints(cbind(1.375, 1.5))
over(in_hole, b.exploded)
#   FID
# 1   2
jbaums
źródło

Odpowiedzi:

7

Okazuje się, że sp::disaggregatemożna go użyć do rozerwania pojedynczych wielokątów.

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::aggregatemożna go użyć do ponownego połączenia).

jbaums
źródło
3

Jestem współczujący, to trochę boli. Musisz rozbić szczeliny obiektu wielokąta gBuffer na pojedyncze wielokąty.

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
źródło
Właśnie przetestowałem i wydaje się obiecujące, ale moje dziury nie są już dziurami :(. Czy możemy to dostosować, aby zachować dziury razem z polisami, z którymi są skojarzone? ( n <- length(buff@polygons[[1]]@Polygons); SpatialPolygons(mapply(function(x, y) Polygons(list(x), y), buff@polygons[[1]]@Polygons, seq_len(n)))
Kierowałem się