From f8d85a45ed314cf6cf561fbf6602c220a1da1726 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Mon, 26 Aug 2024 12:27:36 +0200 Subject: [PATCH] netCDF: honour BAND_NAMES creation option in CreateCopy() Fixes #10646 --- autotest/gdrivers/netcdf.py | 26 ++++++++++++++++++++++++++ frmts/netcdf/netcdfdataset.cpp | 25 ++++++++++++++++++++++++- 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/autotest/gdrivers/netcdf.py b/autotest/gdrivers/netcdf.py index ac9dd2c9961b..90f907ccb4e8 100755 --- a/autotest/gdrivers/netcdf.py +++ b/autotest/gdrivers/netcdf.py @@ -6510,6 +6510,32 @@ def test_band_names_creation_option(tmp_path): assert gdal.GetSubdatasetInfo(sds_names[1]).GetSubdatasetComponent() == "prate" +@gdaltest.enable_exceptions() +def test_band_names_creation_option_createcopy(tmp_path): + + fname = tmp_path / "out.nc" + + # 1 band, 2 names + with pytest.raises(Exception, match="but 2 names provided"): + src_ds = gdal.GetDriverByName("MEM").Create("", 1, 1) + gdal.GetDriverByName("NetCDF").CreateCopy( + fname, src_ds, options={"BAND_NAMES": "t2m,prate"} + ) + + # 2 bands, 2 names + src_ds = gdal.GetDriverByName("MEM").Create("", 1, 1, 2) + with gdal.GetDriverByName("NetCDF").CreateCopy( + fname, src_ds, options={"BAND_NAMES": "t2m,prate"} + ): + pass + + with gdal.Open(fname) as ds: + sds_names = [sds[0] for sds in ds.GetSubDatasets()] + + assert gdal.GetSubdatasetInfo(sds_names[0]).GetSubdatasetComponent() == "t2m" + assert gdal.GetSubdatasetInfo(sds_names[1]).GetSubdatasetComponent() == "prate" + + @gdaltest.enable_exceptions() def test_netcdf_create_metadata_with_equal_sign(tmp_path): diff --git a/frmts/netcdf/netcdfdataset.cpp b/frmts/netcdf/netcdfdataset.cpp index 5e5ce8d0cbe4..aa2ab535501b 100644 --- a/frmts/netcdf/netcdfdataset.cpp +++ b/frmts/netcdf/netcdfdataset.cpp @@ -9483,6 +9483,24 @@ netCDFDataset::CreateCopy(const char *pszFilename, GDALDataset *poSrcDS, } } + CPLStringList aosBandNames; + if (const char *pszBandNames = + CSLFetchNameValue(papszOptions, "BAND_NAMES")) + { + aosBandNames = + CSLTokenizeString2(pszBandNames, ",", CSLT_HONOURSTRINGS); + + if (aosBandNames.Count() != nBands) + { + CPLError(CE_Failure, CPLE_OpenFailed, + "Attempted to create netCDF with %d bands but %d names " + "provided in BAND_NAMES.", + nBands, aosBandNames.Count()); + + return nullptr; + } + } + if (!pfnProgress(0.0, nullptr, pProgressData)) return nullptr; @@ -9692,7 +9710,12 @@ netCDFDataset::CreateCopy(const char *pszFilename, GDALDataset *poSrcDS, const char *pszNETCDF_VARNAME = poSrcBand->GetMetadataItem("NETCDF_VARNAME"); char szBandName[NC_MAX_NAME + 1]; - if (pszNETCDF_VARNAME) + if (!aosBandNames.empty()) + { + snprintf(szBandName, sizeof(szBandName), "%s", + aosBandNames[iBand - 1]); + } + else if (pszNETCDF_VARNAME) { if (nBands > 1 && papszExtraDimNames == nullptr) snprintf(szBandName, sizeof(szBandName), "%s%d",