Skip to content

Commit

Permalink
fixes #1549
Browse files Browse the repository at this point in the history
  • Loading branch information
rhijmans committed Dec 23, 2024
1 parent 4dc88b7 commit 6932311
Show file tree
Hide file tree
Showing 2 changed files with 107 additions and 7 deletions.
25 changes: 19 additions & 6 deletions R/ncdf.R
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,14 @@
}


write_tags <- function(tags, nc, varid, prefix="TAG_") {
if (length(tags) > 0) {
nms <- paste0(prefix, names(tags))
for(i in 1:length(nms)) {
ncdf4::ncatt_put(nc, varid, nms[i], tags[i], prec="text")
}
}
}

.write_cdf <- function(x, filename, overwrite=FALSE, zname="time", atts="", gridmap="", prec="float", compression=NA, missval, force_v4=TRUE, verbose=FALSE, ...) {

Expand Down Expand Up @@ -140,6 +148,7 @@
ncobj <- ncdf4::nc_create(filename, ncvars, force_v4=force_v4, verbose=verbose)
on.exit(ncdf4::nc_close(ncobj))


haveprj <- FALSE
prj <- crs(x[1])
prj <- gsub("\n", "", prj)
Expand All @@ -150,11 +159,12 @@
ncdf4::ncatt_put(ncobj, ncvars[[n+1]], "spatial_ref", prj, prec="text")
prj <- .proj4(x[1])
if (prj != "") {
ncdf4::ncatt_put(ncobj, ncvars[[n+1]], "proj4", prj, prec='text')
ncdf4::ncatt_put(ncobj, ncvars[[n+1]], "proj4", prj, prec="text")
}
prj <- crs(x[1], describe=TRUE)[1,3]
if (!is.na(prj)) {
ncdf4::ncatt_put(ncobj, ncvars[[n+1]], "epsg_code", prj, prec='text')
prj <- crs(x[1], describe=TRUE)[1,2:3]
if (!any(is.na(prj))) {
prj <- paste0(prj, collapse=":")
ncdf4::ncatt_put(ncobj, ncvars[[n+1]], "code", prj, prec="text")
}
}
gridmap <- grep("=", gridmap, value=TRUE)
Expand Down Expand Up @@ -187,7 +197,7 @@
y <- x[i]
b <- blocks(y, 4)
readStart(y)
if (length(ncvars[[1]]$dim) == 3) {
if (length(ncvars[[i]]$dim) == 3) {
for (j in 1:b$n) {
if (progress) { setTxtProgressBar(pb, pcnt); pcnt <- pcnt + 1 }
d <- readValues(y, b$row[j], b$nrows[j], 1, nc, FALSE, FALSE)
Expand All @@ -208,14 +218,17 @@
if (haveprj) {
ncdf4::ncatt_put(ncobj, ncvars[[i]], "grid_mapping", "crs", prec="text")
}
write_tags(metags(y), ncobj, ncvars[[i]], "")
}
if (progress) close(pb)

ncdf4::ncatt_put(ncobj, 0, "Conventions", "CF-1.4", prec="text")
pkgversion <- drop(read.dcf(file=system.file("DESCRIPTION", package="terra"), fields=c("Version")))
ncdf4::ncatt_put(ncobj, 0, "created_by", paste("R packages ncdf4 and terra (version ", pkgversion, ")", sep=""), prec="text")
ncdf4::ncatt_put(ncobj, 0, "date", format(Sys.time(), "%Y-%m-%d %H:%M:%S"), prec="text")
ncdf4::ncatt_put(ncobj, 0, "created_date", format(Sys.time(), "%Y-%m-%d %H:%M:%S"), prec="text")

write_tags(metags(x), ncobj, 0, "")

atts <- grep("=", atts, value=TRUE)
if (length(atts) > 0) {
atts <- strsplit(atts, "=")
Expand Down
89 changes: 88 additions & 1 deletion src/read_gdal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -580,6 +580,41 @@ inline std::string dtypename(const std::string &d) {
}


void get_tags(std::vector<std::string> meta, std::string prefix, std::vector<std::string> &name, std::vector<std::string> &value) {
if (!meta.empty()) {
for (size_t i=0; i<meta.size(); i++) {
size_t tagpos = meta[i].find(prefix);
if (tagpos != std::string::npos) {
size_t pos = meta[i].find("=");
if (pos != std::string::npos) {
std::string mn = meta[i].substr(prefix.size(), pos-tagpos-prefix.size());
if (!((mn == "_FillValue") || (mn == "grid_mapping") || (mn == "Conventions") || (mn == "created_by") || (mn == "created_date"))) {
name.push_back(mn);
value.push_back(meta[i].substr(pos+1, meta[i].length()));
}
}
}
}
}

}

std::vector<std::string> get_metadata(std::string filename, std::vector<std::string> options) {
std::vector<std::string> metadata;
GDALDataset *poDataset = openGDAL(filename, GDAL_OF_RASTER | GDAL_OF_READONLY | GDAL_OF_VERBOSE_ERROR, {}, options);
if( poDataset == NULL ) {
return metadata;
}
char **m = poDataset->GetMetadata();
if (m) {
while (*m != nullptr) {
metadata.push_back(*m++);
}
}
GDALClose( (GDALDatasetH) poDataset );
return metadata;
}


SpatRasterStack::SpatRasterStack(std::string fname, std::vector<int> ids, bool useids, std::vector<std::string> options) {

Expand Down Expand Up @@ -637,7 +672,20 @@ SpatRasterStack::SpatRasterStack(std::string fname, std::vector<int> ids, bool u
}
}
}
meta.resize(0);
char **m = poDataset->GetMetadata();
if (m) {
while (*m != nullptr) {
meta.push_back(*m++);
}
}
GDALClose( (GDALDatasetH) poDataset );

std::vector<std::string> tagnames, tagvalues;
// get_tags(meta, "NC_GLOBAL#TAG_", tagnames, tagvalues);
get_tags(meta, "NC_GLOBAL#", tagnames, tagvalues);
for (size_t i=0; i<tagnames.size(); i++) addTag(tagnames[i], tagvalues[i]);

}


Expand Down Expand Up @@ -695,7 +743,20 @@ SpatRasterCollection::SpatRasterCollection(std::string fname, std::vector<int> i
}
}
}
meta.resize(0);
char **m = poDataset->GetMetadata();
if (m) {
while (*m != nullptr) {
meta.push_back(*m++);
}
}
GDALClose( (GDALDatasetH) poDataset );

std::vector<std::string> tagnames, tagvalues;
// get_tags(meta, "NC_GLOBAL#TAG_", tagnames, tagvalues);
get_tags(meta, "NC_GLOBAL#", tagnames, tagvalues);
for (size_t i=0; i<tagnames.size(); i++) addTag(tagnames[i], tagvalues[i]);

}


Expand Down Expand Up @@ -764,6 +825,7 @@ bool getGCPs(GDALDataset *poDataset, SpatRasterSource &s) {
}



bool SpatRaster::constructFromFile(std::string fname, std::vector<int> subds, std::vector<std::string> subdsname, std::vector<std::string> drivers, std::vector<std::string> options) {

if (fname == "WCS:") {
Expand Down Expand Up @@ -1167,9 +1229,10 @@ bool SpatRaster::constructFromFile(std::string fname, std::vector<int> subds, st
}

msg = "";
std::vector<std::string> metadata;

if ((gdrv=="netCDF") || (gdrv == "HDF5")) {

std::vector<std::string> metadata;
char **m = poDataset->GetMetadata();
if (m) {
while (*m != nullptr) {
Expand Down Expand Up @@ -1207,6 +1270,14 @@ bool SpatRaster::constructFromFile(std::string fname, std::vector<int> subds, st
s.hasValues = true;
setSource(s);

if ((!metadata.empty()) && ((gdrv=="netCDF") || (gdrv == "HDF5"))) {
std::vector<std::string> tagnames, tagvalues;
// std::string stag = s.source_name + "#TAG_";
std::string stag = s.source_name + "#";
get_tags(metadata, stag, tagnames, tagvalues);
for (size_t i=0; i<tagnames.size(); i++) addTag(tagnames[i], tagvalues[i]);

}
if (getCols) {
setRGB(rgb_lyrs[0], rgb_lyrs[1], rgb_lyrs[2], -99, "rgb");
}
Expand Down Expand Up @@ -1899,6 +1970,19 @@ bool SpatRaster::constructFromSDS(std::string filename, std::vector<std::string>
}
}

std::vector<std::string> metadata = get_metadata(filename, options);
if (!metadata.empty()) {
std::vector<std::string> tagnames, tagvalues;
// get_tags(metadata, "NC_GLOBAL#TAG_", tagnames, tagvalues);
get_tags(metadata, "NC_GLOBAL#", tagnames, tagvalues);
for (size_t i=0; i<tagnames.size(); i++) {
std::string mn = tagnames[i];
if (!((mn == "_FillValue") || (mn == "grid_mapping") || (mn == "Conventions") || (mn == "created_by") || (mn == "created_date"))) {
addTag(tagnames[i], tagvalues[i]);
}
}
}

return true;
}

Expand Down Expand Up @@ -2152,6 +2236,9 @@ std::vector<int_64> ncdf_time(const std::vector<std::string> &metadata, std::vec
//NETCDF_DIM_time=0
//NETCDF_VARNAME=NVEL




std::vector<std::vector<std::string>> ncdf_names(const std::vector<std::vector<std::string>> &m) {

std::vector<std::vector<std::string>> out(3);
Expand Down

0 comments on commit 6932311

Please sign in to comment.