Line data Source code
1 : /****************************************************************************** 2 : * 3 : * Project: GDAL 4 : * Purpose: "write" step of "mdim pipeline" 5 : * Author: Even Rouault <even dot rouault at spatialys.com> 6 : * 7 : ****************************************************************************** 8 : * Copyright (c) 2026, Even Rouault <even dot rouault at spatialys.com> 9 : * 10 : * SPDX-License-Identifier: MIT 11 : ****************************************************************************/ 12 : 13 : #include "gdalalg_mdim_write.h" 14 : 15 : #include "cpl_string.h" 16 : #include "gdal_utils.h" 17 : #include "gdal_priv.h" 18 : 19 : //! @cond Doxygen_Suppress 20 : 21 : /************************************************************************/ 22 : /* GDALMdimWriteAlgorithm::GDALMdimWriteAlgorithm() */ 23 : /************************************************************************/ 24 : 25 11 : GDALMdimWriteAlgorithm::GDALMdimWriteAlgorithm() 26 : : GDALMdimPipelineStepAlgorithm( 27 : NAME, DESCRIPTION, HELP_URL, 28 11 : ConstructorOptions().SetMdimOutputAcceptsClassicRaster(true)) 29 : { 30 11 : AddMdimOutputArgs(/* hiddenForCLI = */ false); 31 11 : } 32 : 33 : /************************************************************************/ 34 : /* GDALMdimWriteAlgorithm::RunStep() */ 35 : /************************************************************************/ 36 : 37 10 : bool GDALMdimWriteAlgorithm::RunStep(GDALPipelineStepRunContext &ctxt) 38 : { 39 10 : auto pfnProgress = ctxt.m_pfnProgress; 40 10 : auto pProgressData = ctxt.m_pProgressData; 41 10 : auto poSrcDS = m_inputDataset[0].GetDatasetRef(); 42 10 : CPLAssert(poSrcDS); 43 10 : CPLAssert(!m_outputDataset.GetDatasetRef()); 44 : 45 10 : if (m_format == "stream") 46 : { 47 3 : m_outputDataset.Set(poSrcDS); 48 3 : return true; 49 : } 50 : 51 14 : CPLStringList aosOptions; 52 7 : if (!m_overwrite) 53 : { 54 7 : aosOptions.AddString("--no-overwrite"); 55 : } 56 7 : if (!m_format.empty()) 57 : { 58 2 : aosOptions.AddString("-of"); 59 2 : aosOptions.AddString(m_format.c_str()); 60 : } 61 7 : for (const auto &co : m_creationOptions) 62 : { 63 0 : aosOptions.AddString("-co"); 64 0 : aosOptions.AddString(co.c_str()); 65 : } 66 : 67 : GDALMultiDimTranslateOptions *psOptions = 68 7 : GDALMultiDimTranslateOptionsNew(aosOptions.List(), nullptr); 69 7 : GDALMultiDimTranslateOptionsSetProgress(psOptions, pfnProgress, 70 : pProgressData); 71 : 72 : // Backup error state since GDALMultiDimTranslate() resets it multiple times 73 7 : const auto nLastErrorNum = CPLGetLastErrorNo(); 74 7 : const auto nLastErrorType = CPLGetLastErrorType(); 75 14 : const std::string osLastErrorMsg = CPLGetLastErrorMsg(); 76 7 : const auto nLastErrorCounter = CPLGetErrorCounter(); 77 : 78 7 : GDALDatasetH hSrcDS = GDALDataset::ToHandle(poSrcDS); 79 7 : auto poRetDS = GDALDataset::FromHandle( 80 7 : GDALMultiDimTranslate(m_outputDataset.GetName().c_str(), nullptr, 1, 81 : &hSrcDS, psOptions, nullptr)); 82 7 : GDALMultiDimTranslateOptionsFree(psOptions); 83 : 84 7 : if (nLastErrorCounter > 0 && CPLGetErrorCounter() == 0) 85 : { 86 0 : CPLErrorSetState(nLastErrorType, nLastErrorNum, osLastErrorMsg.c_str(), 87 : &nLastErrorCounter); 88 : } 89 : 90 7 : if (!poRetDS) 91 2 : return false; 92 : 93 5 : m_outputDataset.Set(std::unique_ptr<GDALDataset>(poRetDS)); 94 : 95 5 : return true; 96 : } 97 : 98 : //! @endcond