LCOV - code coverage report
Current view: top level - apps - gdalpipelinestepalgorithm.h (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 108 110 98.2 %
Date: 2026-09-11 05:09:32 Functions: 41 42 97.6 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  GDAL
       4             :  * Purpose:  gdal "raster/vector pipeline" subcommand
       5             :  * Author:   Even Rouault <even dot rouault at spatialys.com>
       6             :  *
       7             :  ******************************************************************************
       8             :  * Copyright (c) 2024, Even Rouault <even dot rouault at spatialys.com>
       9             :  *
      10             :  * SPDX-License-Identifier: MIT
      11             :  ****************************************************************************/
      12             : 
      13             : #ifndef GDALPIPELINESTEPALGORITHM_INCLUDED
      14             : #define GDALPIPELINESTEPALGORITHM_INCLUDED
      15             : 
      16             : //! @cond Doxygen_Suppress
      17             : 
      18             : #include "gdalalgorithm.h"
      19             : 
      20             : #include "gdalpipelinestepruncontext.h"
      21             : 
      22             : /************************************************************************/
      23             : /*                      GDALPipelineStepAlgorithm                       */
      24             : /************************************************************************/
      25             : 
      26             : class OGRLayer;
      27             : 
      28             : class GDALPipelineStepAlgorithm /* non final */ : public GDALAlgorithm
      29             : {
      30             :   public:
      31         180 :     std::vector<GDALArgDatasetValue> &GetInputDatasets()
      32             :     {
      33         180 :         return m_inputDataset;
      34             :     }
      35             : 
      36             :     const std::vector<GDALArgDatasetValue> &GetInputDatasets() const
      37             :     {
      38             :         return m_inputDataset;
      39             :     }
      40             : 
      41         214 :     GDALArgDatasetValue &GetOutputDataset()
      42             :     {
      43         214 :         return m_outputDataset;
      44             :     }
      45             : 
      46             :     const GDALArgDatasetValue &GetOutputDataset() const
      47             :     {
      48             :         return m_outputDataset;
      49             :     }
      50             : 
      51         759 :     const std::string &GetOutputString() const
      52             :     {
      53         759 :         return m_output;
      54             :     }
      55             : 
      56          64 :     const std::string &GetOutputLayerName() const
      57             :     {
      58          64 :         return m_outputLayerName;
      59             :     }
      60             : 
      61         226 :     const std::string &GetOutputFormat() const
      62             :     {
      63         226 :         return m_format;
      64             :     }
      65             : 
      66         104 :     const std::vector<std::string> &GetCreationOptions() const
      67             :     {
      68         104 :         return m_creationOptions;
      69             :     }
      70             : 
      71          83 :     const std::vector<std::string> &GetLayerCreationOptions() const
      72             :     {
      73          83 :         return m_layerCreationOptions;
      74             :     }
      75             : 
      76          97 :     bool GetOverwriteLayer() const
      77             :     {
      78          97 :         return m_overwriteLayer;
      79             :     }
      80             : 
      81          56 :     bool GetAppendLayer() const
      82             :     {
      83          56 :         return m_appendLayer;
      84             :     }
      85             : 
      86             :     virtual int GetInputType() const = 0;
      87             : 
      88             :     virtual int GetOutputType() const = 0;
      89             : 
      90             :     bool Finalize() override;
      91             : 
      92             :     // Used by GDALDispatcherAlgorithm for vector info/convert
      93          42 :     GDALDataset *GetInputDatasetRef()
      94             :     {
      95          42 :         return m_inputDataset.empty() ? nullptr
      96          42 :                                       : m_inputDataset[0].GetDatasetRef();
      97             :     }
      98             : 
      99             :     // Used by GDALDispatcherAlgorithm for vector info/convert
     100             :     void SetInputDataset(GDALDataset *poDS);
     101             : 
     102             :   protected:
     103             :     struct ConstructorOptions
     104             :     {
     105             :         bool standaloneStep = false;
     106             :         bool addDefaultArguments = true;
     107             :         bool autoOpenInputDatasets = true;
     108             :         bool inputDatasetRequired = true;
     109             :         bool inputDatasetPositional = true;
     110             :         bool outputDatasetRequired = true;
     111             :         bool addInputLayerNameArgument = true;        // only for vector input
     112             :         bool addUpdateArgument = true;                // only for vector output
     113             :         bool addAppendLayerArgument = true;           // only for vector output
     114             :         bool addNoCreateEmptyLayersArgument = false;  // only for vector output
     115             :         bool addOverwriteLayerArgument = true;        // only for vector output
     116             :         bool addUpsertArgument = true;                // only for vector output
     117             :         bool addSkipErrorsArgument = true;            // only for vector output
     118             :         bool addOutputLayerNameArgument = true;       // only for vector output
     119             :         bool outputLayerNameAvailableInPipelineStep = false;
     120             :         int inputDatasetMaxCount = 1;
     121             :         int inputDatasetInputFlags = GADV_NAME | GADV_OBJECT;
     122             :         std::string inputDatasetHelpMsg{};
     123             :         std::string inputDatasetAlias{};
     124             :         std::string inputDatasetMetaVar = "INPUT";
     125             :         std::string outputDatasetHelpMsg{};
     126             :         std::string outputFormatCreateCapability = GDAL_DCAP_CREATECOPY;
     127             :         bool mdimOutputAcceptsClassicRaster = false;  // only for mdim output
     128             : 
     129       12686 :         inline ConstructorOptions &SetStandaloneStep(bool b)
     130             :         {
     131       12686 :             standaloneStep = b;
     132       12686 :             return *this;
     133             :         }
     134             : 
     135        6480 :         inline ConstructorOptions &SetAddDefaultArguments(bool b)
     136             :         {
     137        6480 :             addDefaultArguments = b;
     138        6480 :             return *this;
     139             :         }
     140             : 
     141         552 :         inline ConstructorOptions &SetAddInputLayerNameArgument(bool b)
     142             :         {
     143         552 :             addInputLayerNameArgument = b;
     144         552 :             return *this;
     145             :         }
     146             : 
     147         577 :         inline ConstructorOptions &SetInputDatasetRequired(bool b)
     148             :         {
     149         577 :             inputDatasetRequired = b;
     150         577 :             return *this;
     151             :         }
     152             : 
     153         577 :         inline ConstructorOptions &SetInputDatasetPositional(bool b)
     154             :         {
     155         577 :             inputDatasetPositional = b;
     156         577 :             return *this;
     157             :         }
     158             : 
     159        3639 :         inline ConstructorOptions &SetInputDatasetMaxCount(int maxCount)
     160             :         {
     161        3639 :             inputDatasetMaxCount = maxCount;
     162        3639 :             return *this;
     163             :         }
     164             : 
     165          82 :         inline ConstructorOptions &SetInputDatasetInputFlags(int flags)
     166             :         {
     167          82 :             inputDatasetInputFlags = flags;
     168          82 :             return *this;
     169             :         }
     170             : 
     171         716 :         inline ConstructorOptions &SetInputDatasetHelpMsg(const std::string &s)
     172             :         {
     173         716 :             inputDatasetHelpMsg = s;
     174         716 :             return *this;
     175             :         }
     176             : 
     177        1436 :         inline ConstructorOptions &SetInputDatasetAlias(const std::string &s)
     178             :         {
     179        1436 :             inputDatasetAlias = s;
     180        1436 :             return *this;
     181             :         }
     182             : 
     183        1117 :         inline ConstructorOptions &SetInputDatasetMetaVar(const std::string &s)
     184             :         {
     185        1117 :             inputDatasetMetaVar = s;
     186        1117 :             return *this;
     187             :         }
     188             : 
     189         273 :         inline ConstructorOptions &SetOutputDatasetHelpMsg(const std::string &s)
     190             :         {
     191         273 :             outputDatasetHelpMsg = s;
     192         273 :             return *this;
     193             :         }
     194             : 
     195        1702 :         inline ConstructorOptions &SetAutoOpenInputDatasets(bool b)
     196             :         {
     197        1702 :             autoOpenInputDatasets = b;
     198        1702 :             return *this;
     199             :         }
     200             : 
     201         100 :         inline ConstructorOptions &SetOutputDatasetRequired(bool b)
     202             :         {
     203         100 :             outputDatasetRequired = b;
     204         100 :             return *this;
     205             :         }
     206             : 
     207             :         inline ConstructorOptions &
     208        1933 :         SetOutputFormatCreateCapability(const std::string &capability)
     209             :         {
     210        1933 :             outputFormatCreateCapability = capability;
     211        1933 :             return *this;
     212             :         }
     213             : 
     214             :         /** Whether the output format of a multidimensional algorithm may also
     215             :          * be a classic raster driver, which is the case of algorithms whose
     216             :          * output is written by GDALMultiDimTranslate(). */
     217         127 :         inline ConstructorOptions &SetMdimOutputAcceptsClassicRaster(bool b)
     218             :         {
     219         127 :             mdimOutputAcceptsClassicRaster = b;
     220         127 :             return *this;
     221             :         }
     222             : 
     223         337 :         inline ConstructorOptions &SetAddAppendLayerArgument(bool b)
     224             :         {
     225         337 :             addAppendLayerArgument = b;
     226         337 :             return *this;
     227             :         }
     228             : 
     229         205 :         inline ConstructorOptions &SetAddOverwriteLayerArgument(bool b)
     230             :         {
     231         205 :             addOverwriteLayerArgument = b;
     232         205 :             return *this;
     233             :         }
     234             : 
     235         205 :         inline ConstructorOptions &SetAddUpdateArgument(bool b)
     236             :         {
     237         205 :             addUpdateArgument = b;
     238         205 :             return *this;
     239             :         }
     240             : 
     241         638 :         inline ConstructorOptions &SetAddUpsertArgument(bool b)
     242             :         {
     243         638 :             addUpsertArgument = b;
     244         638 :             return *this;
     245             :         }
     246             : 
     247        1322 :         inline ConstructorOptions &SetNoCreateEmptyLayersArgument(bool b)
     248             :         {
     249        1322 :             addNoCreateEmptyLayersArgument = b;
     250        1322 :             return *this;
     251             :         }
     252             : 
     253         638 :         inline ConstructorOptions &SetAddSkipErrorsArgument(bool b)
     254             :         {
     255         638 :             addSkipErrorsArgument = b;
     256         638 :             return *this;
     257             :         }
     258             : 
     259         212 :         inline ConstructorOptions &SetAddOutputLayerNameArgument(bool b)
     260             :         {
     261         212 :             addOutputLayerNameArgument = b;
     262         212 :             return *this;
     263             :         }
     264             : 
     265             :         inline ConstructorOptions &
     266         621 :         SetOutputLayerNameAvailableInPipelineStep(bool b)
     267             :         {
     268         621 :             outputLayerNameAvailableInPipelineStep = b;
     269         621 :             return *this;
     270             :         }
     271             :     };
     272             : 
     273             :     GDALPipelineStepAlgorithm(const std::string &name,
     274             :                               const std::string &description,
     275             :                               const std::string &helpURL,
     276             :                               const ConstructorOptions &);
     277             : 
     278             :     friend class GDALPipelineAlgorithm;
     279             :     friend class GDALRasterPipelineAlgorithm;
     280             :     friend class GDALVectorPipelineAlgorithm;
     281             :     friend class GDALMdimPipelineAlgorithm;
     282             :     friend class GDALAbstractPipelineAlgorithm;
     283             : 
     284        2206 :     virtual bool CanBeFirstStep() const
     285             :     {
     286        2206 :         return false;
     287             :     }
     288             : 
     289         554 :     virtual bool CanBeMiddleStep() const
     290             :     {
     291         554 :         return !CanBeFirstStep() && !CanBeLastStep();
     292             :     }
     293             : 
     294         936 :     virtual bool CanBeLastStep() const
     295             :     {
     296         936 :         return false;
     297             :     }
     298             : 
     299             :     //! Whether a user parameter can cause a file to be written at a specified location
     300          54 :     virtual bool GeneratesFilesFromUserInput() const
     301             :     {
     302          54 :         return false;
     303             :     }
     304             : 
     305         863 :     virtual bool IsNativelyStreamingCompatible() const
     306             :     {
     307         863 :         return true;
     308             :     }
     309             : 
     310         290 :     virtual bool SupportsInputMultiThreading() const
     311             :     {
     312         290 :         return false;
     313             :     }
     314             : 
     315        1678 :     virtual bool CanHandleNextStep(GDALPipelineStepAlgorithm *) const
     316             :     {
     317        1678 :         return false;
     318             :     }
     319             : 
     320           0 :     virtual bool OutputDatasetAllowedBeforeRunningStep() const
     321             :     {
     322           0 :         return false;
     323             :     }
     324             : 
     325         283 :     virtual CPLJSONObject Get_OGR_SCHEMA_OpenOption_Layer() const
     326             :     {
     327         283 :         CPLJSONObject obj;
     328         283 :         obj.Deinit();
     329         283 :         return obj;
     330             :     }
     331             : 
     332             :     virtual bool RunStep(GDALPipelineStepRunContext &ctxt) = 0;
     333             : 
     334             :     bool m_standaloneStep = false;
     335             :     const ConstructorOptions m_constructorOptions;
     336             :     bool m_outputVRTCompatible = true;
     337             :     std::string m_helpDocCategory{};
     338             : 
     339             :     // Input arguments
     340             :     std::vector<GDALArgDatasetValue> m_inputDataset{};
     341             :     std::vector<std::string> m_openOptions{};
     342             :     std::vector<std::string> m_inputFormats{};
     343             :     std::vector<std::string> m_inputLayerNames{};
     344             : 
     345             :     // Output arguments
     346             :     bool m_stdout = false;
     347             :     std::string m_output{};
     348             :     GDALArgDatasetValue m_outputDataset{};
     349             :     std::string m_format{};
     350             :     std::vector<std::string> m_outputOpenOptions{};
     351             :     std::vector<std::string> m_creationOptions{};
     352             :     bool m_overwrite = false;
     353             :     std::string m_outputLayerName{};
     354             :     GDALInConstructionAlgorithmArg *m_outputFormatArg = nullptr;
     355             :     bool m_appendRaster = false;
     356             : 
     357             :     // Output arguments (vector specific)
     358             :     std::vector<std::string> m_layerCreationOptions{};
     359             :     bool m_update = false;
     360             :     bool m_overwriteLayer = false;
     361             :     bool m_appendLayer = false;
     362             :     bool m_upsert = false;
     363             :     bool m_skipErrors = false;
     364             :     bool m_noCreateEmptyLayers = false;
     365             : 
     366             :     void AddRasterInputArgs(bool openForMixedRasterVector, bool hiddenForCLI);
     367             :     void AddRasterOutputArgs(bool hiddenForCLI);
     368             :     void AddRasterHiddenInputDatasetArg();
     369             : 
     370             :     void AddVectorInputArgs(bool hiddenForCLI);
     371             :     void AddVectorHiddenInputDatasetArg();
     372             :     void AddVectorOutputArgs(bool hiddenForCLI,
     373             :                              bool shortNameOutputLayerAllowed);
     374             :     using GDALAlgorithm::AddOutputLayerNameArg;
     375             :     void AddOutputLayerNameArg(bool hiddenForCLI,
     376             :                                bool shortNameOutputLayerAllowed);
     377             : 
     378             :     void AddMdimInputArgs(bool openForMixedRasterVector, bool hiddenForCLI,
     379             :                           bool acceptRaster);
     380             :     void AddMdimOutputArgs(bool hiddenForCLI);
     381             :     void AddMdimHiddenInputDatasetArg();
     382             : 
     383             :     bool CreateDatasetSingleOutputLayerIfNeeded(
     384             :         GDALPipelineStepRunContext &ctxt, const std::string &defaultLayerName,
     385             :         GDALDataset *&poDstDS, bool &bTemporaryFile,
     386             :         std::unique_ptr<GDALDataset> &poNewRetDS, std::string &outputLayerName,
     387             :         OGRLayer *&poDstLayer);
     388             : 
     389             :   private:
     390             :     bool RunImpl(GDALProgressFunc pfnProgress, void *pProgressData) override;
     391             :     GDALAlgorithm::ProcessGDALGOutputRet ProcessGDALGOutput() override;
     392             :     bool CheckSafeForStreamOutput() override;
     393             : 
     394             :     CPL_DISALLOW_COPY_ASSIGN(GDALPipelineStepAlgorithm)
     395             : };
     396             : 
     397             : //! @endcond
     398             : 
     399             : #endif

Generated by: LCOV version 1.14