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
.
# 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.