r-spatial / stars

Spatiotemporal Arrays, Raster and Vector Data Cubes
https://r-spatial.github.io/stars/
Apache License 2.0
563 stars 94 forks source link

`st_rasterize` does not save column names as raster bands #705

Closed CristianICS closed 2 months ago

CristianICS commented 2 months ago

I use the following code to export a raster from a simple vector object, passing the file and options parameters.

# Create a reproducible polygon
coords <- matrix(c(0, 0, 0, 1, 1, 1, 1, 0, 0, 0), ncol = 2, byrow = TRUE)
polygon_list <- list(st_polygon(list(coords))
# Convert the list into an `sfc` object (simple feature geometry list-column)
polygon_sfc <- st_sfc(polygon_list, crs = 4326)

# Create a data frame with attributes (the column names are the raster future band names)
polygon_data <- data.frame(col1 = 1, col2=2)
polygon_sf <- st_sf(polygon_data, geometry = polygon_sfc)

# Save raster
out_path <- ""
st_rasterize(polygon_sf, file = out_path, driver="GTiff", options = c('COMPRESS=DEFLATE', 'PREDICTOR=2'))

The resulted band names are values and values.1. Is it possible to write the custom column names as the band names with this approach?

Thanks, Cristian

edzer commented 2 months ago

I changed your script slightly:

# Create a reproducible polygon
coords <- matrix(c(0, 0, 0, 1, 1, 1, 1, 0, 0, 0), ncol = 2, byrow = TRUE)
polygon_list <- list(st_polygon(list(coords))) # added )
# Convert the list into an `sfc` object (simple feature geometry list-column)
polygon_sfc <- st_sfc(polygon_list, crs = 4326)

# Create a data frame with attributes (the column names are the raster future band names)
polygon_data <- data.frame(col1 = 1, col2=2)
polygon_sf <- st_sf(polygon_data, geometry = polygon_sfc)

# Save raster
out_path <- "x.tif" # add name
o = st_rasterize(polygon_sf, file = out_path, driver="GTiff", options = c('COMPRESS=DEFLATE', 'PREDICTOR=2'))

Then, o contains two attributes with the column names of polygon_sf. Reading x.tif will not give you those, as tif files do not have named bands.

CristianICS commented 2 months ago

Thank you very much for the response @edzer. To clarify my point, I wanted to know if there is any approach to update the band description metadata tag directly from st_rasterize options and produce an image in tif format with the following metadata:

Band 1 Block=250x4 Type=Float32, ColorInterp=Gray
  Description = col1
Band 2 Block=250x4 Type=Float32, ColorInterp=Undefined
  Description = col2

To date, I save custom band names transforming the rasterized image into a raster stack object and using the following (clearly inefficient) code:

library(raster)
o <- stack("o.tif") # the ancient "o" object saved with st_rasterize in GTiff
names(o) <- c("col1", "col2")
write_stars(st_as_stars(o), "o_bandnames.tif")
edzer commented 2 months ago

Oh yes, I missed that tiffs actually have band descriptors; this fix has them written by st_rasterize().