knitr::opts_chunk$set(echo = TRUE, paged.print = FALSE)
The original R-GRASS interface [@bivand:00; @neteler+mitasova:08] was designed to move raster and later vector data between R and GRASS GIS. To do this, use was made of intermediate files, often using the external GDAL library on both sides. On the R side, the rgdal now archived package was used, interfacing GDAL and PROJ as GRASS GIS also did. The GRASS commands r.in.gdal
, r.out.gdal
, v.in.ogr
and v.out.ogr
were matched by rgdal functions using the same underlying external libraries:
knitr::include_graphics("fig1.png")
GDAL was supplemented for raster data by simply reading and writing uncompressed binary files using r.in.bin
and r.out.bin
, with custom functions on the R side. As then written, the R-GRASS interface used sp classes for both raster and vector data, supplemented more recently with sf classes for vector data only.
The current version of the R-GRASS interface has been simplified to use the terra package because it, like sf and rgdal before it, links to the important external libraries. The workhorse driver is known as RRASTER
, and has been widely used in raster and terra (see also (https://rspatial.org)). It uses GDAL but writes a flat uncompressed binary file. Using terra::rast()
also appears to preserve category names and colour tables, but needs further testing (see (https://github.com/rsbivand/rgrass/issues/42)).
knitr::include_graphics("fig2_p7_RRASTER_GRASS.png")
From GDAL 3.5.0, the RRASTER
driver also supports WKT2_2019 CRS representations; in earlier versions of GDAL, the driver only supported the proj-string representation (https://github.com/rsbivand/rgrass/issues/51).
These changes mean that users transferring data between R and GRASS will need to coerce between terra classes SpatVector
and SpatRaster
and the class system of choice. In addition, SpatRaster
is only read into memory from file when this is required, so requiring some care.
This vignette is constructed conditioning on the availability of aforementioned R packages, i.e. if some were missing at the time of package building, some code blocks will not be displayed.
terra_available <- requireNamespace("terra", quietly = TRUE) sf_available <- requireNamespace("sf", quietly = TRUE) sp_available <- requireNamespace("sp", quietly = TRUE) stars_available <- requireNamespace("stars", quietly = TRUE) && packageVersion("stars") > "0.5.4" raster_available <- requireNamespace("raster", quietly = TRUE)
On loading and attaching, terra displays its version:
library("terra")
library("sf")
library("sp")
library("stars")
library("raster")
terra::gdal()
tells us the versions of the external libraries being used by terra:
gdal(lib = "all")
When using CRAN binary packages built static for Windows and macOS, the R packages will use the same versions of the external libraries, but not necessarily the same versions as those against which GRASS was installed.
"SpatVector"
coercionIn the terra package [@terra], vector data are held in "SpatVector"
objects. This means that when read_VECT()
is used, a "SpatVector"
object is returned, and the same class of object is needed for write_VECT()
for writing to GRASS.
fv <- system.file("ex/lux.shp", package = "terra") (v <- vect(fv))
These objects are always held in memory, so there is no inMemory()
method:
try(inMemory(v))
The coordinate reference system is expressed in WKT2-2019 form:
cat(crs(v), "\n")
"sf"
Most new work should use vector classes defined in the sf package [@sf; @sf-rj]. In this case, coercion uses st_as_sf()
:
v_sf <- st_as_sf(v) v_sf
and the vect()
method to get from sf to terra:
v_sf_rt <- vect(v_sf) v_sf_rt
all.equal(v_sf_rt, v, check.attributes = FALSE)
"Spatial"
To coerce to and from vector classes defined in the sp package [@asdar], methods in raster are used as an intermediate step:
v_sp <- as(v, "Spatial") print(summary(v_sp))
v_sp_rt <- vect(st_as_sf(v_sp)) all.equal(v_sp_rt, v, check.attributes = FALSE)
"SpatRaster"
coercionIn the terra package, raster data are held in "SpatRaster"
objects. This means that when read_RAST()
is used, a "SpatRaster"
object is returned, and the same class of object is needed for write_RAST()
for writing to GRASS.
fr <- system.file("ex/elev.tif", package = "terra") (r <- rast(fr))
In general, "SpatRaster"
objects are files, rather than data held in memory:
try(inMemory(r))
"stars"
The stars package [@stars] uses GDAL through sf. A coercion method is provided from "SpatRaster"
to "stars"
:
r_stars <- st_as_stars(r) print(r_stars)
which round-trips in memory.
(r_stars_rt <- rast(r_stars))
When coercing to "stars_proxy"
the same applies:
(r_stars_p <- st_as_stars(r, proxy = TRUE))
with coercion from "stars_proxy"
also not reading data into memory:
(r_stars_p_rt <- rast(r_stars_p))
"RasterLayer"
From version 3.6-3 the raster package [@raster] uses terra for all GDAL operations. Because of this, coercing a "SpatRaster"
object to a "RasterLayer"
object is simple:
(r_RL <- raster(r))
inMemory(r_RL)
The WKT2-2019 CRS representation is present but not shown by default:
cat(wkt(r_RL), "\n")
This object (held on file rather than in memory) can be round-tripped:
(r_RL_rt <- rast(r_RL))
"Spatial"
"RasterLayer"
objects can be used for coercion from a "SpatRaster"
object to a "SpatialGridDataFrame"
object:
r_sp_RL <- as(r_RL, "SpatialGridDataFrame") summary(r_sp_RL)
The WKT2-2019 CRS representation is present but not shown by default:
cat(wkt(r_sp_RL), "\n")
This object can be round-tripped, but use of raster forefronts the Proj.4 string CRS representation:
(r_sp_RL_rt <- raster(r_sp_RL)) cat(wkt(r_sp_RL_rt), "\n")
(r_sp_rt <- rast(r_sp_RL_rt))
crs(r_sp_RL_rt)
Coercion to the sp "SpatialGridDataFrame"
representation is also provided by stars:
r_sp_stars <- as(r_stars, "Spatial") summary(r_sp_stars)
cat(wkt(r_sp_stars), "\n")
and can be round-tripped:
(r_sp_stars_rt <- rast(st_as_stars(r_sp_stars)))
``
cat(crs(r_sp_rt), "\n")
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.