Puffer und Vereinigung in R, ohne auf ein Multi-Polygon zu reduzieren

9

Ich möchte eine räumliche Überlagerung durchführen, um das Polygon zu identifizieren, in das eine Reihe von Punkten fällt. Ich möchte jedoch zuerst die Polygone puffern und auflösen, sodass Punkte, die irgendwo in zusammengeführte Polygone (aber nicht in Löcher) fallen, durch das Überlagerungsverfahren ähnlich gekennzeichnet werden.

Leider reduziert der von mir verwendete Puffer- und / oder Auflösungsprozess das SpatialPolygonsObjekt auf ein Multi-Polygon. Die Verwendung von gBuffererstellt ein Multi-Polygon, wenn byid=FALSE, überlappende Polygone jedoch nicht zu vereinen, wenn byid=TRUE. Im letzteren Fall erzeugt das anschließende Auflösen von Polygonen mit gUnaryUnionerneut ein Multi-Polygon. Das Überlagern SpatialPointsmit diesen Multi-Polygonen führt dazu, dass alle enthaltenen Punkte als innerhalb von Polygon 1 liegend gemeldet werden.

Hier ist ein verwandtes Spielzeugbeispiel mit gepufferten Punkten, in dem ich die Punkte mit den gepufferten Polygonen überlagern möchte:

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)

Geben Sie hier die Bildbeschreibung ein

Und die Ergebnisse einiger Überlagerungen ...

  • Mit byid=FALSE:

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

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

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

Ich suche nach der richtigen Methode, um das Ergebnis zu erzielen 1 1 1 2, dh die Punkte 1, 2 und 3 fallen in das Polygon 1 (zuvor Polygone 1, 2 und 3, die zusammengeführt wurden) und Punkt 4 fällt in das Polygon 2 (ursprünglich Polygon 4) ).


BEARBEITEN

Zu meinen wahren Daten gehören Löcher, und im Idealfall möchte ich sie erhalten können. Ich habe die obigen Beispieldaten so aktualisiert, dass sie nach dem Puffern ein Loch enthalten.

Anwendung des Ansatzes von @ JeffreyEvans auf diese Polys:

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

Ergebnisse in:

over(pts, b.exploded)

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

Das ist das erwartete Ergebnis (ich bin nicht zu sehr mit der Poly-Reihenfolge beschäftigt - 2,2,2,1vs. 1,1,1,2), aber ich habe b.explodeddie Informationen über das Loch verloren, anstatt es als Nicht-Loch-Polygon darzustellen. Es hat offensichtlich keinen Einfluss auf das Ergebnis des Spielzeugbeispiels, aber eine Überlagerung mit Punkten im Loch ist irreführend, z.

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

Antworten:

7

Es stellt sich heraus, dass sp::disaggregatedamit die einteiligen Polygone auseinandergezogen werden können.

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::aggregatekann verwendet werden, um sie wieder zu kombinieren.)

jbaums
quelle
3

Ich bin mitfühlend, das ist ein bisschen schmerzhaft. Sie müssen die Slots des gBuffer-Polygonobjekts in einzelne Polygone zerlegen.

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
quelle
Habe gerade getestet und es scheint vielversprechend, aber meine Löcher sind keine Löcher mehr :(. Können wir dies anpassen, um Löcher mit den Polys zusammenzuhalten, mit denen sie verbunden sind? (Ich ging in ähnlicher Weise wie Ihr Vorschlag, mit n <- length(buff@polygons[[1]]@Polygons); SpatialPolygons(mapply(function(x, y) Polygons(list(x), y), buff@polygons[[1]]@Polygons, seq_len(n)))... Ich hätte das
Lochproblem