paleolimbot / geos

Open Source Geometry Engine ('GEOS') R API
https://paleolimbot.github.io/geos/
Other
61 stars 8 forks source link

Convert geometry collection to vector of geometry #65

Closed kylebutts closed 2 years ago

kylebutts commented 2 years ago

I'm not sure if I'm something, but is there an easier way to convert a geometry collection into a vector of geometries? This code works but is a bit verbose

nc <- sf::read_sf(system.file("shape/nc.shp", package = "sf"))$geometry
coll <- geos::geos_make_collection(nc)
geos::as_geos_geometry(sf::st_collection_extract(sf::st_as_sfc(coll)))
#> <geos_geometry[100] with CRS=NAD27>
#>   [1] <MULTIPOLYGON [-81.741 36.234...-81.240 36.590]>
#>   [2] <MULTIPOLYGON [-81.348 36.365...-80.903 36.573]>
#>   [3] <MULTIPOLYGON [-80.966 36.234...-80.435 36.565]>
#>   [4] <MULTIPOLYGON [-76.330 36.073...-75.773 36.557]>
#>   [5] <MULTIPOLYGON [-77.901 36.163...-77.075 36.556]>

Created on 2022-01-19 by the reprex package (v2.0.1)

I've tried geos_make_polygon() which errors and geos_as_geometry() which returns the collection

paleolimbot commented 2 years ago

I think wk::wk_flatten() or geos::geos_unnest() might be what you're looking for!

nc <- sf::read_sf(system.file("shape/nc.shp", package = "sf"))
wk::wk_flatten(nc)
#> Simple feature collection with 108 features and 14 fields
#> Geometry type: POLYGON
#> Dimension:     XY
#> Bounding box:  xmin: -84.32385 ymin: 33.88199 xmax: -75.45698 ymax: 36.58965
#> Geodetic CRS:  NAD27
#> # A tibble: 108 × 15
#>     AREA PERIMETER CNTY_ CNTY_ID NAME  FIPS  FIPSNO CRESS_ID BIR74 SID74 NWBIR74
#>  * <dbl>     <dbl> <dbl>   <dbl> <chr> <chr>  <dbl>    <int> <dbl> <dbl>   <dbl>
#>  1 0.114      1.44  1825    1825 Ashe  37009  37009        5  1091     1      10
#>  2 0.061      1.23  1827    1827 Alle… 37005  37005        3   487     0      10
#>  3 0.143      1.63  1828    1828 Surry 37171  37171       86  3188     5     208
#>  4 0.07       2.97  1831    1831 Curr… 37053  37053       27   508     1     123
#>  5 0.07       2.97  1831    1831 Curr… 37053  37053       27   508     1     123
#>  6 0.07       2.97  1831    1831 Curr… 37053  37053       27   508     1     123
#>  7 0.153      2.21  1832    1832 Nort… 37131  37131       66  1421     9    1066
#>  8 0.097      1.67  1833    1833 Hert… 37091  37091       46  1452     7     954
#>  9 0.062      1.55  1834    1834 Camd… 37029  37029       15   286     0     115
#> 10 0.091      1.28  1835    1835 Gates 37073  37073       37   420     0     254
#> # … with 98 more rows, and 4 more variables: BIR79 <dbl>, SID79 <dbl>,
#> #   NWBIR79 <dbl>, geometry <POLYGON [°]>

unnested <- lapply(
  geos::as_geos_geometry(nc),
  geos::geos_unnest, 
  keep_multi = FALSE
)

str(head(unnested))
#> List of 6
#>  $ : geos_geometry[1:1] <POLYGON [-81.741 36.234...-81.24 36.59]>
#>  $ : geos_geometry[1:1] <POLYGON [-81.348 36.365...-80.903 36.573]>
#>  $ : geos_geometry[1:1] <POLYGON [-80.966 36.234...-80.435 36.565]>
#>  $ : geos_geometry[1:3] <POLYGON [-76.330 36.073...-75.799 36.557]>, <POLYGON [
#>  $ : geos_geometry[1:1] <POLYGON [-77.901 36.163...-77.075 36.556]>
#>  $ : geos_geometry[1:1] <POLYGON [-77.218 36.23...-76.707 36.556]>

Created on 2022-01-19 by the reprex package (v2.0.1)

kylebutts commented 2 years ago

Thank you!!