Hier ist ein Spielzeugbeispiel, mit dem ich gerungen habe
# Make points
point1 <- c(.5, .5)
point2 <- c(.6, .6)
point3 <- c(3, 3)
mpt <- st_multipoint(rbind(point1, point2, point3)) # create multipoint
# Make polygons
square1 <- rbind(c(0, 0), c(1, 0), c(1,1), c(0, 1), c(0, 0))
square2 <- rbind(c(0, 0), c(2, 0), c(2,2), c(0, 2), c(0, 0))
square3 <- rbind(c(0, 0), c(-1, 0), c(-1,-1), c(0, -1), c(0, 0))
mpol <- st_multipolygon(list(list(square1), list(square2), list(square2))) # create multipolygon
# Convert to class' sf'
pts <- st_sf(st_sfc(mpt))
polys <- st_sf(st_sfc(mpol))
# Determine which points fall inside which polygons
st_join(pts, polys, join = st_contains)
Die letzte Zeile erzeugt
Error in as.data.frame.default(x[[i]], optional = TRUE, stringsAsFactors = stringsAsFactors) :
cannot coerce class "c("sfc_MULTIPOINT", "sfc")" to a data.frame
Wie kann ich eine räumliche Verknüpfung durchführen, um zu bestimmen, welche Punkte in welche Polygone fallen?
Ich arbeite mich auch an den Features des sf
-Pakets durch, also entschuldigt, wenn dies nicht korrekt ist oder gibt es bessere Möglichkeiten. Ich denke, ein Problem besteht darin, dass Sie beim Erstellen der Geometrien wie in Ihrem Beispiel nicht das bekommen, was Sie denken:
> pts
Simple feature collection with 1 feature and 0 fields
geometry type: MULTIPOINT
dimension: XY
bbox: xmin: 0.5 ymin: 0.5 xmax: 3 ymax: 3
epsg (SRID): NA
proj4string: NA
st_sfc.mpt.
1 MULTIPOINT(0.5 0.5, 0.6 0.6...
> polys
Simple feature collection with 1 feature and 0 fields
geometry type: MULTIPOLYGON
dimension: XY
bbox: xmin: 0 ymin: 0 xmax: 2 ymax: 2
epsg (SRID): NA
proj4string: NA
st_sfc.mpol.
1 MULTIPOLYGON(((0 0, 1 0, 1 ...
Sie sehen, dass Sie sowohl in pts
als auch in polys
nur ein "Feature" haben. Dies bedeutet, dass Sie ein "Multipolygon" -Feature erstellen (d. H. Ein aus 3 Teilen bestehendes Polygon) und nicht drei verschiedene Polygone. Gleiches gilt für die Punkte.
Nachdem ich ein wenig gegraben hatte, fand ich es anders (und meiner Meinung nach einfacher), die Geometrien mithilfe der WKT-Notation zu erstellen:
polys <- st_as_sfc(c("POLYGON((0 0 , 0 1 , 1 1 , 1 0, 0 0))",
"POLYGON((0 0 , 0 2 , 2 2 , 2 0, 0 0 ))",
"POLYGON((0 0 , 0 -1 , -1 -1 , -1 0, 0 0))")) %>%
st_sf(ID = paste0("poly", 1:3))
pts <- st_as_sfc(c("POINT(0.5 0.5)",
"POINT(0.6 0.6)",
"POINT(3 3)")) %>%
st_sf(ID = paste0("point", 1:3))
> polys
Simple feature collection with 3 features and 1 field
geometry type: POLYGON
dimension: XY
bbox: xmin: -1 ymin: -1 xmax: 2 ymax: 2
epsg (SRID): NA
proj4string: NA
ID .
1 poly1 POLYGON((0 0, 0 1, 1 1, 1 0...
2 poly2 POLYGON((0 0, 0 2, 2 2, 2 0...
3 poly3 POLYGON((0 0, 0 -1, -1 -1, ...
> pts
Simple feature collection with 3 features and 1 field
geometry type: POINT
dimension: XY
bbox: xmin: 0.5 ymin: 0.5 xmax: 3 ymax: 3
epsg (SRID): NA
proj4string: NA
ID .
1 point1 POINT(0.5 0.5)
2 point2 POINT(0.6 0.6)
3 point3 POINT(3 3)
sie sehen, dass jetzt sowohl polys
als auch pts
drei Funktionen haben.
Wir können jetzt die "Kreuzungsmatrix" finden mit:
# Determine which points fall inside which polygons
pi <- st_contains(polys,pts, sparse = F) %>%
as.data.frame() %>%
mutate(polys = polys$ID) %>%
select(dim(pi)[2],1:dim(pi)[1])
colnames(pi)[2:dim(pi)[2]] = levels(pts$ID)
> pi
polys point1 point2 point3
1 poly1 TRUE TRUE FALSE
2 poly2 TRUE TRUE FALSE
3 poly3 FALSE FALSE FALSE
dies bedeutet (wie in den Kommentaren auf @symbolixau hingewiesen), dass die Polygone 1 und 2 die Punkte 1 und 2 enthalten, während das Polygon 3 keine Punkte enthält. Punkt 3 ist stattdessen in keinem Polygon enthalten.
HTH.
Ich sehe eine andere Ausgabe:
> # Determine which points fall inside which polygons
> st_join(pts, polys, join = st_contains)
Simple feature collection with 1 feature and 0 fields
geometry type: MULTIPOINT
dimension: XY
bbox: xmin: 0.5 ymin: 0.5 xmax: 3 ymax: 3
epsg (SRID): NA
proj4string: NA
geometry
1 MULTIPOINT(0.5 0.5, 0.6 0.6...
war dies mit der neuesten CRAN-Version von sf
?
Beachten Sie, dass der ursprüngliche Satz von Multipoint und Multipolygon in Punkte und Polygone umgewandelt werden kann, ohne neue Objekte zu erstellen:
st_contains(polys %>% st_cast("POLYGON"), pts %>% st_cast("POINT"), sparse = F)
# [,1] [,2] [,3]
#[1,] TRUE TRUE FALSE
#[2,] TRUE TRUE FALSE
#[3,] FALSE FALSE FALSE