--- title: "GDAL Interoperability" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{GDAL Interoperability} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r, include = FALSE} knitr::opts_chunk$set( collapse = TRUE, comment = "#>" ) ``` ```{r setup} library(vaster) ``` ## Introduction GDAL (Geospatial Data Abstraction Library) is the foundation of most geospatial software. It uses specific conventions for representing raster grids that differ from R's typical approach. The **vaster** package provides functions to convert between vaster's `dimension`/`extent` representation and GDAL's conventions, enabling seamless integration with GDAL-based tools. ## GDAL GeoTransform GDAL represents raster georeferencing using a 6-element *GeoTransform* array: ``` GT[0]: x-coordinate of the upper-left corner GT[1]: pixel width (x resolution) GT[2]: row rotation (typically 0) GT[3]: y-coordinate of the upper-left corner GT[4]: column rotation (typically 0) GT[5]: pixel height (negative for north-up images) ``` For a typical north-up raster, only elements 0, 1, 3, and 5 are non-zero. ### Converting to GeoTransform The `geo_transform0()` function converts vaster's dimension/extent to a GDAL GeoTransform: ```{r} dimension <- c(10, 5) extent <- c(0, 100, 0, 50) gt <- geo_transform0(dimension, extent) gt ``` The GeoTransform tells us: - Upper-left corner is at `(0, 50)` — note y is at the top - Pixel width is `10` units - Pixel height is `-10` units (negative because y decreases downward) ### Converting from GeoTransform Given a GeoTransform and dimensions, `gt_dim_to_extent()` recovers the extent: ```{r} gt <- c(0, 10, 0, 50, 0, -10) dimension <- c(10, 5) gt_dim_to_extent(gt, dimension) ``` And `extent_dim_to_gt()` does the reverse: ```{r} extent_dim_to_gt(c(0, 100, 0, 50), c(10, 5)) ``` ## World Files World files (`.tfw`, `.pgw`, `.jgw`, etc.) are a simpler georeferencing format used by many applications. They contain 6 lines: ``` Line 1: pixel width Line 2: row rotation Line 3: column rotation Line 4: pixel height (negative for north-up) Line 5: x-coordinate of centre of upper-left pixel Line 6: y-coordinate of centre of upper-left pixel ``` ### Converting to World File Format ```{r} dimension <- c(10, 5) extent <- c(0, 100, 0, 50) wf <- geo_world0(dimension, extent) wf ``` Note the difference from GeoTransform: the world file specifies the **centre** of the upper-left pixel, not its corner. ## GDAL RasterIO GDAL's `RasterIO` function is the core mechanism for reading/writing raster data. It uses a window specification: ``` (xoff, yoff, xsize, ysize) ``` Where: - `xoff`: column offset (0-based, from left) - `yoff`: row offset (0-based, from top) - `xsize`: number of columns to read - `ysize`: number of rows to read ### Converting Extent to RasterIO Window The `rasterio0()` function converts an extent to RasterIO parameters: ```{r} ## Full grid dimension <- c(360, 180) extent <- c(-180, 180, -90, 90) ## Subregion to read (Australia) subextent <- c(110, 155, -45, -10) rio <- rasterio0(dimension, extent, subextent) rio ``` This tells you: - Start at column `r rio[1]` (0-based offset) - Start at row `r rio[2]` (0-based offset) - Read `r rio[3]` columns - Read `r rio[4]` rows ### Using with vapour or stars These parameters can be passed directly to GDAL-based R packages: ```{r, eval = FALSE} ## With vapour package library(vapour) data <- vapour_read_raster( "my_raster.tif", window = rasterio0(dimension, extent, subextent) ) ## With stars package library(stars) rio <- rasterio0(dimension, extent, subextent) data <- stars::read_stars( "my_raster.tif", RasterIO = list( nXOff = rio[1] + 1, # stars uses 1-based nYOff = rio[2] + 1, nXSize = rio[3], nYSize = rio[4] ) ) ``` ### Converting to sf-style RasterIO The `rasterio_to_sfio()` function converts to the 1-based format used by sf/stars: ```{r} rio <- rasterio0(dimension, extent, subextent) sfio <- rasterio_to_sfio(rio) sfio ``` ## VRT Files GDAL Virtual Format (VRT) files are XML descriptions of raster datasets. They're useful for creating virtual mosaics and defining subsets without copying data. ### Extracting Extent from VRT The `extent_vrt()` function parses a VRT file to extract its extent: ```{r, eval = FALSE} ## Parse VRT and get extent vrt_file <- "path/to/mosaic.vrt" ext <- extent_vrt(vrt_file) ext ``` This is useful for understanding the coverage of a virtual mosaic before reading data. ## Practical Example: Pre-computing Read Parameters A common workflow is to pre-compute read parameters for efficient data access: ```{r} ## Known raster properties (e.g., from gdalinfo) full_dimension <- c(43200, 21600) # global 30 arc-second grid full_extent <- c(-180, 180, -90, 90) ## Regions of interest regions <- list( europe = c(-10, 40, 35, 70), australia = c(110, 155, -45, -10), amazon = c(-80, -45, -20, 5) ) ## Pre-compute RasterIO parameters for each region read_params <- lapply(regions, function(roi) { aligned <- align_extent(roi, full_dimension, full_extent) crop_dim <- extent_dimension(aligned, full_dimension, full_extent) list( rasterio = rasterio0(full_dimension, full_extent, aligned), dimension = crop_dim, extent = aligned ) }) ## Check Amazon parameters read_params$amazon ``` This lets you plan I/O operations before touching the data. ## Practical Example: Creating Aligned Grids When creating output grids compatible with GDAL tools: ```{r} ## Design a 1-degree global grid target_res <- 1 # 1 degree cells global_extent <- c(-180, 180, -90, 90) ## Compute dimensions from extent and resolution dimension <- c( diff(global_extent[1:2]) / target_res, diff(global_extent[3:4]) / target_res ) dimension ## Generate GeoTransform for GDAL gt <- geo_transform0(dimension, global_extent) gt ## Generate world file content wf <- geo_world0(dimension, global_extent) cat(wf, sep = "\n") ``` ## Summary | Function | Purpose | |----------|---------| | `geo_transform0()` | Convert to GDAL GeoTransform (6-element) | | `geo_world0()` | Convert to world file format (6-element) | | `gt_dim_to_extent()` | GeoTransform + dimension → extent | | `extent_dim_to_gt()` | Extent + dimension → GeoTransform | | `rasterio0()` | Compute GDAL RasterIO window parameters | | `rasterio_to_sfio()` | Convert to sf/stars 1-based RasterIO | | `extent_vrt()` | Extract extent from VRT file | These functions bridge vaster's abstract grid logic with GDAL's concrete representations, enabling you to plan operations and generate parameters for GDAL-based tools.