How to select certain geometries from a geometrycollection after st_intersect?
Asked Answered
E

1

8

I am running an intersect of two polygons or other sf objects using the fantastic new sf package. It's similar to this:

a <- st_polygon(list(cbind(c(0,0,7.5,7.5,0),c(0,-1,-1,0,0))))
b <- st_polygon(list(cbind(c(0,1,2,3,4,5,6,7,7,0),c(1,0,.5,0,0,0.5,-0.5,-0.5,1,1))))
i <- st_intersection(a,b)
## GEOMETRYCOLLECTION(POINT(1 0), LINESTRING(4 0, 3 0), POLYGON((5.5 0, 7 0, 7 -0.5, 6 -0.5, 5.5 0)))

how do I only keep the POLYGON of the GEOMETRYCOLLECTION? Selecting different types in a feature collection is easy enough, but I can't seem to find the equivalent of ST_CollectionExtract in the sf package.

Evidentiary answered 16/8, 2017 at 22:10 Comment(0)
G
14

Output is a list so that you can extract with i[[3]] here.
If you a more standard way to find which element is a polygon use:

w.pol <- purrr::map_lgl(i, ~st_is(.x, c("POLYGON", "MULTIPOLYGON")))
pol <- i[[which(w.pol)]]

##> pol
## POLYGON((5.5 0, 7 0, 7 -0.5, 6 -0.5, 5.5 0))

Edit: If you have a sfc, you can use st_cast to separate feature types, and then select the lines of interest:

# Simple feature data frame of spatial collection
a1 <- st_sf(a=1, geom = st_sfc(i))
a2 <- st_sf(a=2, geom = st_sfc(i))

ii <- rbind(a1, a2)

# Use st_cast to separate all features types
st_cast(ii)[which(st_is(st_cast(ii), c("POLYGON", "MULTIPOLYGON"))),]

Edit: 2017-12-23

You can directly use:

st_collection_extract(i, "POLYGON") 
Gingivitis answered 22/8, 2017 at 12:43 Comment(2)
Thx, this works well in this case! @StatnMap, how would you do that when the geometrycollection is part of a simple features data frame and not just a single object? This will just remove all collections then, but they may have polygons inside.Evidentiary
What if the simple features data frame contains not only GEOMETRYCOLLECTIONs but also other geometries, e.g. if I change a2 <- st_sf(a=2, geom = st_sfc(i)) to a2 <- st_sf(a=2, geom = st_sfc(a)) in the above?Noriega

© 2022 - 2024 — McMap. All rights reserved.