Reading and writing spatial data

Introduction

Reading and writing spatial data is complicated by the fact that there are many different file formats. However, there are a few formats that are most common that we discuss here.

Vector files

The shapefile is the most commonly used file format for vector data (if you are not familiar with this file format, an important thing to understand is that a shapefile is really a set of at least three (ideally four) files, with all the same name, but different extension. For shapefile x you must have, in the same directory, these three files: x.shp, x.shx, x.dbf, and ideally also x.prj.

It is easy to read and write such files. Here we use a shapefile that comes with the terra package.

Reading

We use the system.file function to get the full path name of the file’s location. We need to do this as the location of this file depends on where the terra package is installed. You should not use the system.file function for your own files. It only serves for creating examples with data that ship with R. With your own files, just use the filename (and path if the file is not in your working directory).

library(terra)
filename <- system.file("ex/lux.shp", package="terra")
basename(filename)
## [1] "lux.shp"

Now we have the filename we can use the vect function to read the file.

s <- vect(filename)
s
##  class       : SpatVector
##  geometry    : polygons
##  dimensions  : 12, 5  (geometries, attributes)
##  extent      : 5.74414, 6.528252, 49.44781, 50.18162  (xmin, xmax, ymin, ymax)
##  coord. ref. : +proj=longlat +datum=WGS84 +no_defs
##  names       :  ID_1   NAME_1  ID_2   NAME_2  AREA
##  type        : <num>    <chr> <num>    <chr> <num>
##  values      :     1 Diekirch     1 Clervaux   312
##                    1 Diekirch     2 Diekirch   218
##                    1 Diekirch     3  Redange   259

The vect function returns SpatVector objects. It is important to recognise the difference between this type of R object (SpatVector), and the file (“shapefile”) that was used to create it. Thus, you should never say “I have a shapefile in R”, say “I have a SpatVector of polygons in R”, (and in some cases you can add “created from a shapefile”). The shapefile is one of many file formats for vector data.

Writing

You can write new files using the writeVector method. You need to add argument overwrite=TRUE if you want to overwrite an existing file.

outfile <- "shp_test.shp"
writeVector(s, outfile, overwrite=TRUE)

To remove the file again you can use file.remove or unlink (be careful!)

ff <- list.files(patt="^shptest")
file.remove(ff)
## logical(0)

Raster files

The terra package can read and write several raster file formats.

Reading raster data

Again we need to get a filename for an example file.

f <- system.file("ex/logo.tif", package="terra")
basename(f)
## [1] "logo.tif"

Now we can do

r <- rast(f)
r
## class       : SpatRaster
## dimensions  : 77, 101, 3  (nrow, ncol, nlyr)
## resolution  : 1, 1  (x, y)
## extent      : 0, 101, 0, 77  (xmin, xmax, ymin, ymax)
## coord. ref. : +proj=merc +lon_0=0 +k=1 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs
## source      : logo.tif
## red-grn-blue: 1, 2, 3
## names       : red, green, blue
## min values  :   0,     0,    0
## max values  : 255,   255,  255

Note that x is a SpatRaster of three layers (“bands”). We can subset it to get a single layer.

r2 <- r[[2]]
r2
## class       : SpatRaster
## dimensions  : 77, 101, 1  (nrow, ncol, nlyr)
## resolution  : 1, 1  (x, y)
## extent      : 0, 101, 0, 77  (xmin, xmax, ymin, ymax)
## coord. ref. : +proj=merc +lon_0=0 +k=1 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs
## source      : logo.tif
## name        : green
## min value   :     0
## max value   :   255

The same approach holds for other raster file formats, including GeoTiff, NetCDF, Imagine, and ESRI Grid formats.

Writing raster data

Use writeRaster to write raster data. You must provide a SpatRaster and a filename. The file format will be guessed from the filename extension. If that does not work you can provide an argument like format=GTiff. Note the argument overwrite=TRUE and see ?writeRaster for more arguments, such as datatype= to set the a specific datatype (e.g., integer).

x <- writeRaster(r, "test_output.tif", overwrite=TRUE)
x
## class       : SpatRaster
## dimensions  : 77, 101, 3  (nrow, ncol, nlyr)
## resolution  : 1, 1  (x, y)
## extent      : 0, 101, 0, 77  (xmin, xmax, ymin, ymax)
## coord. ref. : +proj=merc +lon_0=0 +k=1 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs
## source      : test_output.tif
## red-grn-blue: 1, 2, 3
## names       : red, green, blue
## min values  :   0,     0,    0
## max values  : 255,   255,  255