Line data Source code
1 : /****************************************************************************** 2 : * 3 : * Project: GDAL 4 : * Purpose: gdal "external" subcommand (always in 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 : #ifndef GDALALG_EXTERNAL_INCLUDED 14 : #define GDALALG_EXTERNAL_INCLUDED 15 : 16 : //! @cond Doxygen_Suppress 17 : 18 : #include "gdalalg_abstract_pipeline.h" 19 : #include "gdalalg_raster_pipeline.h" 20 : #include "gdalalg_vector_pipeline.h" 21 : 22 : #ifndef _ 23 : #define _(x) (x) 24 : #endif 25 : 26 : /************************************************************************/ 27 : /* GDALExternalAlgorithmBase */ 28 : /************************************************************************/ 29 : 30 : class GDALExternalAlgorithmBase /* non final */ 31 : { 32 : protected: 33 58 : GDALExternalAlgorithmBase() = default; 34 : virtual ~GDALExternalAlgorithmBase(); 35 : 36 : CPLString m_command{}; 37 : 38 : std::string m_osTempInputFilename{}; 39 : std::string m_osTempOutputFilename{}; 40 : 41 : bool Run(const std::vector<std::string> &inputFormats, 42 : std::vector<GDALArgDatasetValue> &inputDataset, 43 : const std::string &outputFormat, 44 : GDALArgDatasetValue &outputDataset); 45 : }; 46 : 47 : /************************************************************************/ 48 : /* GDALExternalAlgorithm */ 49 : /************************************************************************/ 50 : 51 : template <class BaseStepAlgorithm, int nDatasetType> 52 : class GDALExternalAlgorithm /* non final */ : public BaseStepAlgorithm, 53 : public GDALExternalAlgorithmBase 54 : { 55 : public: 56 : static constexpr const char *NAME = "external"; 57 : static constexpr const char *DESCRIPTION = 58 : "Execute an external program as a step of a pipeline"; 59 : static constexpr const char *HELP_URL = "/programs/gdal_external.html"; 60 : 61 58 : GDALExternalAlgorithm() 62 : : BaseStepAlgorithm(NAME, DESCRIPTION, HELP_URL, 63 : GDALPipelineStepAlgorithm::ConstructorOptions() 64 58 : .SetAddDefaultArguments(false)) 65 : { 66 58 : this->AddArg("command", 0, 67 : _("External command, optionally with <INPUT> and/or " 68 : "<OUTPUT> or <INPUT-OUTPUT> placeholders"), 69 : &m_command) 70 116 : .SetRequired() 71 58 : .SetPositional() 72 58 : .SetMinCharCount(1); 73 : 74 116 : this->AddInputFormatsArg(&this->m_inputFormats) 75 58 : .SetMaxCount(1) 76 58 : .AddMetadataItem(GAAMDI_EXCLUDED_FORMATS, {"MEM"}); 77 116 : this->AddOutputFormatArg(&this->m_format, /* bStreamAllowed = */ false, 78 : /* bGDALGAllowed = */ false) 79 58 : .AddMetadataItem(GAAMDI_EXCLUDED_FORMATS, {"MEM"}); 80 : 81 : // Hidden 82 58 : this->AddInputDatasetArg(&this->m_inputDataset, nDatasetType, false) 83 58 : .SetMinCount(0) 84 58 : .SetMaxCount(1) 85 58 : .SetDatasetInputFlags(GADV_OBJECT) 86 58 : .SetHidden(); 87 58 : this->AddOutputDatasetArg(&this->m_outputDataset, nDatasetType, false) 88 58 : .SetDatasetInputFlags(GADV_OBJECT) 89 58 : .SetHidden(); 90 58 : } 91 : 92 2 : int GetInputType() const override 93 : { 94 2 : return nDatasetType; 95 : } 96 : 97 0 : int GetOutputType() const override 98 : { 99 0 : return nDatasetType; 100 : } 101 : 102 27 : bool CanBeFirstStep() const override 103 : { 104 27 : return true; 105 : } 106 : 107 21 : bool CanBeMiddleStep() const override 108 : { 109 21 : return true; 110 : } 111 : 112 7 : bool CanBeLastStep() const override 113 : { 114 7 : return true; 115 : } 116 : 117 0 : bool IsNativelyStreamingCompatible() const override 118 : { 119 0 : return false; 120 : } 121 : 122 : private: 123 0 : bool RunStep(GDALPipelineStepRunContext &) override 124 : { 125 : return GDALExternalAlgorithmBase::Run( 126 0 : this->m_inputFormats, this->m_inputDataset, this->m_format, 127 0 : this->m_outputDataset); 128 : } 129 : }; 130 : 131 : /************************************************************************/ 132 : /* GDALExternalRasterOrVectorAlgorithm */ 133 : /************************************************************************/ 134 : 135 26 : class GDALExternalRasterOrVectorAlgorithm final 136 : : public GDALExternalAlgorithm<GDALPipelineStepAlgorithm, 0> 137 : { 138 : public: 139 13 : GDALExternalRasterOrVectorAlgorithm() = default; 140 : 141 : ~GDALExternalRasterOrVectorAlgorithm() override; 142 : }; 143 : 144 : /************************************************************************/ 145 : /* GDALExternalRasterAlgorithm */ 146 : /************************************************************************/ 147 : 148 46 : class GDALExternalRasterAlgorithm final 149 : : public GDALExternalAlgorithm<GDALRasterPipelineStepAlgorithm, 150 : GDAL_OF_RASTER> 151 : { 152 : public: 153 23 : GDALExternalRasterAlgorithm() = default; 154 : 155 : ~GDALExternalRasterAlgorithm() override; 156 : }; 157 : 158 : /************************************************************************/ 159 : /* GDALExternalVectorAlgorithm */ 160 : /************************************************************************/ 161 : 162 44 : class GDALExternalVectorAlgorithm final 163 : : public GDALExternalAlgorithm<GDALVectorPipelineStepAlgorithm, 164 : GDAL_OF_VECTOR> 165 : { 166 : public: 167 22 : GDALExternalVectorAlgorithm() = default; 168 : 169 : ~GDALExternalVectorAlgorithm() override; 170 : }; 171 : 172 : //! @endcond 173 : 174 : #endif