Home > Back-end >  R terra SpatVectorCollection: How to convert SpatVectorCollection to SpatVector (multiple polygons)
R terra SpatVectorCollection: How to convert SpatVectorCollection to SpatVector (multiple polygons)

Time:04-01

In general, is it possible to convert a terra SpatVectorCollection to a multi-polygon SpatVector so that it can be plotted etc? Specifically, I have a data.frame of extents (bounding boxes) that I need to convert to a set of polygons. I can create a terra SpatVectorCollection but can't get any further. Or, should I be doing this in sf not terra?


    library(terra)

    library(sf)

    exts <- data.frame(xmin = c(-82,80), xmax = c(-80,-78), ymin = c(-2,-2), ymax = c(0,0))

    exts.svc <- apply(exts, 1, ext) %>% lapply(as.polygons) %>% svc()

    merge(exts.svc) # doesn't work

    union(exts.svc) # doesn't work

    vect(exts.svc) # doesn't work

CodePudding user response:

If you can avoid the call to svc() it is a little easier to get to sf polygons. If not, the beginnings of a method to get polygons from the SpatVectorCollection is included below as well.

library(terra)
library(sf)
library(tidyverse) #just dplyr should work too

exts <- data.frame(xmin = c(-82,80), xmax = c(-80,-78), ymin = c(-2,-2), ymax = c(0,0))

# This gives a spatrastercollection, but is more difficult to work with
exts.svc <- apply(exts, 1, ext) %>% lapply(as.polygons) %>% svc()

# Avoiding spatrastercollection using exts directly
# create extent, make polygons, make sf, bind, and set crs to 4326
exts_sf <- apply(exts, 1, ext) %>% 
  lapply(as.polygons) %>%
  lapply(st_as_sf) %>%
  bind_rows() %>%
  st_set_crs(4326)

head(exts_sf)
#> Simple feature collection with 2 features and 0 fields
#> Geometry type: POLYGON
#> Dimension:     XY
#> Bounding box:  xmin: -82 ymin: -2 xmax: 80 ymax: 0
#> Geodetic CRS:  WGS 84
#>                         geometry
#> 1 POLYGON ((-82 -2, -82 0, -8...
#> 2 POLYGON ((80 -2, 80 0, -78 ...

Above returns an sf object of POLYGON type, use st_union on exts_sf if you need MULTIPOLYGON. enter image description here

# Working with exts.svc
# two slots
length(exts.svc)
#> [1] 2

# transforming the first polygon/slot to an sf polygon
exts.svc[1] %>% st_as_sf() %>% st_set_crs(4326)
#> Simple feature collection with 1 feature and 0 fields
#> Geometry type: POLYGON
#> Dimension:     XY
#> Bounding box:  xmin: -82 ymin: -2 xmax: -80 ymax: 0
#> Geodetic CRS:  WGS 84
#>                         geometry
#> 1 POLYGON ((-82 -2, -82 0, -8...

Maybe a loop, apply, or map function would work to programmatically get each slot of exts.svc to return an sf polygon object if you're stuck with an object like exts.svc.

Created on 2022-03-31 by the reprex package (v2.0.1)

CodePudding user response:

Taking your data:

exts <- data.frame(xmin = c(-82,80), xmax = c(-80,-78), ymin = c(-2,-2), ymax = c(0,0))

#as expected
exts
  xmin xmax ymin ymax
1  -82  -80   -2    0
2   80  -78   -2    0
# then your apply
> exts.ext <- apply(exts, 1, ext) 
> exts.ext
[[1]]
SpatExtent : -82, -80, -2, 0 (xmin, xmax, ymin, ymax)

[[2]]
SpatExtent : 80, -78, -2, 0 (xmin, xmax, ymin, ymax)

# then you lapply using just as.polygons
> exts.polys <- lapply(exts.ext, as.polygons)
exts.polys
[[1]]
 class       : SpatVector 
 geometry    : polygons 
 dimensions  : 1, 0  (geometries, attributes)
 extent      : -82, -80, -2, 0  (xmin, xmax, ymin, ymax)
 coord. ref. :  

[[2]]
 class       : SpatVector 
 geometry    : polygons 
 dimensions  : 1, 0  (geometries, attributes)
 extent      : -78, 80, -2, 0  (xmin, xmax, ymin, ymax)
 coord. ref. : 
#then, I suppose svc()
exts.svc <- lapply(exts.polys, svc)
> exts.svc
[[1]]
 class       : SpatVectorCollection 
 length      : 1 
 geometry    : polygons (1)

[[2]]
 class       : SpatVectorCollection 
 length      : 1 
 geometry    : polygons (1)

And then do whatever other operations. When working out (even simple) workflows, I generally do this step by step before introducing %>% or |> so I can check the results of intermediate steps and that they are progressing as expected.

  • Related