rspatial / terra

R package for spatial data handling https://rspatial.github.io/terra/reference/terra-package.html
GNU General Public License v3.0
527 stars 87 forks source link

Attributes and Metadata in NetCDF #1549

Open ErikKusch opened 1 week ago

ErikKusch commented 1 week ago

Hiya,

following up on #1304, I am wondering how to assign, save, and load from disk custom metadata/attributes to a SpatRaster in .nc format.

A minimal example:

library(terra)
# Example SpatRaster object
r <- rast(nrows=10, ncols=10, vals=1:100)
# Add custom metadata
metags(r) <- c("meta" = "test")
metags(r)
  meta 
"test" 
# saving the file
writeCDF(r, "trial.nc")
# reading the file
r_loaded <- rast("trial.nc")
# meta data
metags(r_loaded)
named character(0)

I would expect the metags slot to be loaded as assigned. This expected behaviour works out when saving a .tif file, but not with a .nc file. Are there any workarounds for .nc attribute saving/reading?

terra version = 1.7.78

    gdal     proj     geos 
 "3.5.3"  "9.1.0" "3.11.0" 
ErikKusch commented 1 week ago

I have put together a somewhat clunky workaround for this problem. Maybe this could be a step towards resolution of this issue?

See here:

library(terra)
library(ncdf4)

# function for saving and reading metadata
Meta.NC <- function(NC, FName, Attrs, Write = FALSE, Read = FALSE){
    ## Writing metadata
    if(Write){
        writeCDF(x = NC, filename = FName)
        nc <- nc_open(FName, write = TRUE)
        for(name in names(Attrs)) {
            ncatt_put(nc, 0, name, Attrs[[name]])
        }
        nc_close(nc)
    }
    ## Reading metadata
    if(Read){
        nc <- nc_open(FName)
        # Retrieve custom metadata
        Meta <- lapply(names(Attrs), FUN = function(name){
            ncatt_get(nc, 0, name)$value
        })
        # Close the NetCDF file
        nc_close(nc)
        Meta_vec <- unlist(Meta)
        names(Meta_vec) <- names(Attrs)
        terra::metags(NC) <- Meta_vec
    }
    ## return object
    return(NC)
}

# Example SpatRaster object
r <- rast(nrows=10, ncols=10, vals=1:100)
# Add custom metadata
metags(r) <- c("meta" = "test")
# saving the file
r <- Meta.NC(NC = r, FName = "trial.nc", Attrs = terra::metags(r), Write = TRUE)
# reading the file
r_loaded <- Meta.NC(NC = r, FName = "trial.nc", Attrs = terra::metags(r), Read = TRUE)
# checking attributes
metags(r) == metags(r_loaded)
meta 
TRUE