Line data Source code
1 : /****************************************************************************** 2 : * 3 : * Project: GDAL 4 : * Purpose: "resize" step of "raster pipeline" 5 : * Author: Even Rouault <even dot rouault at spatialys.com> 6 : * 7 : ****************************************************************************** 8 : * Copyright (c) 2025, Even Rouault <even dot rouault at spatialys.com> 9 : * 10 : * SPDX-License-Identifier: MIT 11 : ****************************************************************************/ 12 : 13 : #include "gdalalg_raster_resize.h" 14 : 15 : #include "gdal_priv.h" 16 : #include "gdal_utils.h" 17 : 18 : //! @cond Doxygen_Suppress 19 : 20 : #ifndef _ 21 : #define _(x) (x) 22 : #endif 23 : 24 : /************************************************************************/ 25 : /* GDALRasterResizeAlgorithm::GDALRasterResizeAlgorithm() */ 26 : /************************************************************************/ 27 : 28 86 : GDALRasterResizeAlgorithm::GDALRasterResizeAlgorithm(bool standaloneStep) 29 : : GDALRasterPipelineStepAlgorithm(NAME, DESCRIPTION, HELP_URL, 30 86 : standaloneStep) 31 : { 32 : AddArg("resolution", 0, _("Target resolution (in destination CRS units)"), 33 172 : &m_resolution) 34 86 : .SetMinCount(2) 35 86 : .SetMaxCount(2) 36 86 : .SetMinValueExcluded(0) 37 86 : .SetRepeatedArgAllowed(false) 38 86 : .SetDisplayHintAboutRepetition(false) 39 172 : .SetMetaVar("<xres>,<yres>") 40 86 : .SetMutualExclusionGroup("resolution-size"); 41 : 42 : // The same logic is applied in gdalalg_raster_create.cpp 43 : AddArg("size", 0, 44 : _("Target size in pixels (or percentage if using '%' suffix)"), 45 172 : &m_size) 46 86 : .SetMinCount(2) 47 86 : .SetMaxCount(2) 48 86 : .SetRequired() 49 86 : .SetMinValueIncluded(0) 50 86 : .SetRepeatedArgAllowed(false) 51 86 : .SetDisplayHintAboutRepetition(false) 52 172 : .SetMetaVar("<width[%]>,<height[%]>") 53 172 : .SetMutualExclusionGroup("resolution-size") 54 : .AddValidationAction( 55 22 : [this]() 56 : { 57 41 : for (const auto &s : m_size) 58 : { 59 29 : auto trimmed = cpl::trim(s); 60 29 : if (!trimmed.empty() && trimmed.back() == '%') 61 : { 62 6 : trimmed = trimmed.substr(0, trimmed.size() - 1); 63 : } 64 : 65 29 : if (cpl::strict_parse<int>(trimmed).value_or(-1) < 0) 66 : { 67 5 : ReportError(CE_Failure, CPLE_IllegalArg, 68 : "Invalid size value: %s'", s.c_str()); 69 5 : return false; 70 : } 71 : } 72 12 : return true; 73 86 : }); 74 172 : AddArg("resampling", 'r', _("Resampling method"), &m_resampling) 75 : .SetChoices("nearest", "bilinear", "cubic", "cubicspline", "lanczos", 76 86 : "average", "mode") 77 86 : .SetDefault("nearest") 78 86 : .SetHiddenChoices("near"); 79 86 : } 80 : 81 : /************************************************************************/ 82 : /* GDALRasterResizeAlgorithm::RunStep() */ 83 : /************************************************************************/ 84 : 85 5 : bool GDALRasterResizeAlgorithm::RunStep(GDALPipelineStepRunContext &) 86 : { 87 5 : const auto poSrcDS = m_inputDataset[0].GetDatasetRef(); 88 5 : CPLAssert(poSrcDS); 89 5 : CPLAssert(m_outputDataset.GetName().empty()); 90 5 : CPLAssert(!m_outputDataset.GetDatasetRef()); 91 : 92 10 : CPLStringList aosOptions; 93 5 : aosOptions.AddString("-of"); 94 5 : aosOptions.AddString("VRT"); 95 5 : if (!m_size.empty()) 96 : { 97 4 : aosOptions.AddString("-outsize"); 98 4 : aosOptions.AddString(m_size[0]); 99 4 : aosOptions.AddString(m_size[1]); 100 : } 101 5 : if (!m_resolution.empty()) 102 : { 103 1 : aosOptions.AddString("-tr"); 104 1 : aosOptions.AddString(CPLSPrintf("%.17g", m_resolution[0])); 105 1 : aosOptions.AddString(CPLSPrintf("%.17g", m_resolution[1])); 106 : } 107 5 : if (!m_resampling.empty()) 108 : { 109 5 : aosOptions.AddString("-r"); 110 5 : aosOptions.AddString(m_resampling.c_str()); 111 : } 112 : 113 : GDALTranslateOptions *psOptions = 114 5 : GDALTranslateOptionsNew(aosOptions.List(), nullptr); 115 : 116 : auto poOutDS = std::unique_ptr<GDALDataset>(GDALDataset::FromHandle( 117 5 : GDALTranslate("", GDALDataset::ToHandle(poSrcDS), psOptions, nullptr))); 118 5 : GDALTranslateOptionsFree(psOptions); 119 5 : const bool bRet = poOutDS != nullptr; 120 5 : if (poOutDS) 121 : { 122 5 : m_outputDataset.Set(std::move(poOutDS)); 123 : } 124 : 125 10 : return bRet; 126 : } 127 : 128 : GDALRasterResizeAlgorithmStandalone::~GDALRasterResizeAlgorithmStandalone() = 129 : default; 130 : 131 : //! @endcond