writeRaster: changed datatype to INT4S prevents writing (categorical) SpatRaster to GeoPackage
I noticed a little hiccup with writeRaster(). Not sure this is entirely a "bug," but it did throw me for a little bit of a loop so perhaps it can be smoothed out or documented, at least.
Basically, the issue is that if you are writing a categorical SpatRaster to file, writeRaster() will change datatype the most efficient integer storage type--which makes perfect sense but can lead to some unexpected behavior.
So, heres an example that requires at least a 32bit integer datatype:
library(terra)
#> terra 1.6.4
x <- rast(matrix(c(0,0,0,112345,112345,112345,21123453,21123453,21123453), byrow = TRUE, ncol = 3))
Say I need to write this data to a GeoPackage as a 32-bit floating point TIFF (because its too big to fit in UInt16), the following works:
# works as expected
writeRaster(x, "test.tif", datatype = "FLT4S", overwrite=TRUE)
But, if there are categories set... e.g:
levels(x)[[1]] <- data.frame(value=c(0,112345,21123453), class=LETTERS[1:3])
Then writeRaster forces datatype, in this case to INT4S:
writeRaster(x, "test.tif", datatype = "FLT4S", overwrite=TRUE)
#> Warning: [writeRaster] changed datatype to INT4S
Which normally would be "fine" and most efficient, but it leads to a stack of warnings/errors resulting in failed write when destination is .gpkg file:
writeRaster(x, "test.gpkg", datatype = "FLT4S", overwrite=TRUE)
#> Warning: Only Byte, Int16, UInt16 or Float32 supported (GDAL error 6)
#> Warning: [writeRaster] changed datatype to INT4S
#> Error: [writeRaster] failed writing GPKG file
This can be resolved by dropping the levels before write:
levels(x) <- NULL
# these work
writeRaster(x, "test.tif", datatype = "FLT4S", overwrite=TRUE)
writeRaster(x, "test.gpkg", datatype = "FLT4S", overwrite=TRUE)
Is this expected behavior? I can see perhaps limiting the types of data that can be written to GeoPackage, as they are quite limited in terms of storing "categorical" information associated with a raster layer. Perhaps a more specific message when trying to write categorical data to GPKG is warranted? Should the conversion of categorical data to numeric data types depend on the capabilities of output driver? Could we at least override this behavior by letting a set datatype avoid the automatic conversion of categoricals?