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 GDALPipelineStepAlgorithm /* non final */ : public GDALAlgorithm 27 : { 28 : public: 29 173 : std::vector<GDALArgDatasetValue> &GetInputDatasets() 30 : { 31 173 : return m_inputDataset; 32 : } 33 : 34 : const std::vector<GDALArgDatasetValue> &GetInputDatasets() const 35 : { 36 : return m_inputDataset; 37 : } 38 : 39 131 : GDALArgDatasetValue &GetOutputDataset() 40 : { 41 131 : return m_outputDataset; 42 : } 43 : 44 : const GDALArgDatasetValue &GetOutputDataset() const 45 : { 46 : return m_outputDataset; 47 : } 48 : 49 649 : const std::string &GetOutputString() const 50 : { 51 649 : return m_output; 52 : } 53 : 54 26 : const std::string &GetOutputLayerName() const 55 : { 56 26 : return m_outputLayerName; 57 : } 58 : 59 200 : const std::string &GetOutputFormat() const 60 : { 61 200 : return m_format; 62 : } 63 : 64 80 : const std::vector<std::string> &GetCreationOptions() const 65 : { 66 80 : return m_creationOptions; 67 : } 68 : 69 59 : const std::vector<std::string> &GetLayerCreationOptions() const 70 : { 71 59 : return m_layerCreationOptions; 72 : } 73 : 74 63 : bool GetOverwriteLayer() const 75 : { 76 63 : return m_overwriteLayer; 77 : } 78 : 79 25 : bool GetAppendLayer() const 80 : { 81 25 : return m_appendLayer; 82 : } 83 : 84 : virtual int GetInputType() const = 0; 85 : 86 : virtual int GetOutputType() const = 0; 87 : 88 : bool Finalize() override; 89 : 90 : // Used by GDALDispatcherAlgorithm for vector info/convert 91 41 : GDALDataset *GetInputDatasetRef() 92 : { 93 41 : return m_inputDataset.empty() ? nullptr 94 41 : : m_inputDataset[0].GetDatasetRef(); 95 : } 96 : 97 : // Used by GDALDispatcherAlgorithm for vector info/convert 98 : void SetInputDataset(GDALDataset *poDS); 99 : 100 : protected: 101 : struct ConstructorOptions 102 : { 103 : bool standaloneStep = false; 104 : bool addDefaultArguments = true; 105 : bool autoOpenInputDatasets = true; 106 : bool inputDatasetRequired = true; 107 : bool inputDatasetPositional = true; 108 : bool outputDatasetRequired = true; 109 : bool addInputLayerNameArgument = true; // only for vector input 110 : bool addUpdateArgument = true; // only for vector output 111 : bool addAppendLayerArgument = true; // only for vector output 112 : bool addNoCreateEmptyLayersArgument = false; // only for vector output 113 : bool addOverwriteLayerArgument = true; // only for vector output 114 : bool addUpsertArgument = true; // only for vector output 115 : bool addSkipErrorsArgument = true; // only for vector output 116 : bool addOutputLayerNameArgument = true; // only for vector output 117 : bool outputLayerNameAvailableInPipelineStep = false; 118 : int inputDatasetMaxCount = 1; 119 : int inputDatasetInputFlags = GADV_NAME | GADV_OBJECT; 120 : std::string inputDatasetHelpMsg{}; 121 : std::string inputDatasetAlias{}; 122 : std::string inputDatasetMetaVar = "INPUT"; 123 : std::string outputDatasetHelpMsg{}; 124 : std::string outputFormatCreateCapability = GDAL_DCAP_CREATECOPY; 125 : 126 11248 : inline ConstructorOptions &SetStandaloneStep(bool b) 127 : { 128 11248 : standaloneStep = b; 129 11248 : return *this; 130 : } 131 : 132 5403 : inline ConstructorOptions &SetAddDefaultArguments(bool b) 133 : { 134 5403 : addDefaultArguments = b; 135 5403 : return *this; 136 : } 137 : 138 420 : inline ConstructorOptions &SetAddInputLayerNameArgument(bool b) 139 : { 140 420 : addInputLayerNameArgument = b; 141 420 : return *this; 142 : } 143 : 144 462 : inline ConstructorOptions &SetInputDatasetRequired(bool b) 145 : { 146 462 : inputDatasetRequired = b; 147 462 : return *this; 148 : } 149 : 150 462 : inline ConstructorOptions &SetInputDatasetPositional(bool b) 151 : { 152 462 : inputDatasetPositional = b; 153 462 : return *this; 154 : } 155 : 156 2650 : inline ConstructorOptions &SetInputDatasetMaxCount(int maxCount) 157 : { 158 2650 : inputDatasetMaxCount = maxCount; 159 2650 : return *this; 160 : } 161 : 162 176 : inline ConstructorOptions &SetInputDatasetInputFlags(int flags) 163 : { 164 176 : inputDatasetInputFlags = flags; 165 176 : return *this; 166 : } 167 : 168 1388 : inline ConstructorOptions &SetInputDatasetHelpMsg(const std::string &s) 169 : { 170 1388 : inputDatasetHelpMsg = s; 171 1388 : return *this; 172 : } 173 : 174 1301 : inline ConstructorOptions &SetInputDatasetAlias(const std::string &s) 175 : { 176 1301 : inputDatasetAlias = s; 177 1301 : return *this; 178 : } 179 : 180 1053 : inline ConstructorOptions &SetInputDatasetMetaVar(const std::string &s) 181 : { 182 1053 : inputDatasetMetaVar = s; 183 1053 : return *this; 184 : } 185 : 186 270 : inline ConstructorOptions &SetOutputDatasetHelpMsg(const std::string &s) 187 : { 188 270 : outputDatasetHelpMsg = s; 189 270 : return *this; 190 : } 191 : 192 1465 : inline ConstructorOptions &SetAutoOpenInputDatasets(bool b) 193 : { 194 1465 : autoOpenInputDatasets = b; 195 1465 : return *this; 196 : } 197 : 198 98 : inline ConstructorOptions &SetOutputDatasetRequired(bool b) 199 : { 200 98 : outputDatasetRequired = b; 201 98 : return *this; 202 : } 203 : 204 : inline ConstructorOptions & 205 1681 : SetOutputFormatCreateCapability(const std::string &capability) 206 : { 207 1681 : outputFormatCreateCapability = capability; 208 1681 : return *this; 209 : } 210 : 211 334 : inline ConstructorOptions &SetAddAppendLayerArgument(bool b) 212 : { 213 334 : addAppendLayerArgument = b; 214 334 : return *this; 215 : } 216 : 217 203 : inline ConstructorOptions &SetAddOverwriteLayerArgument(bool b) 218 : { 219 203 : addOverwriteLayerArgument = b; 220 203 : return *this; 221 : } 222 : 223 203 : inline ConstructorOptions &SetAddUpdateArgument(bool b) 224 : { 225 203 : addUpdateArgument = b; 226 203 : return *this; 227 : } 228 : 229 506 : inline ConstructorOptions &SetAddUpsertArgument(bool b) 230 : { 231 506 : addUpsertArgument = b; 232 506 : return *this; 233 : } 234 : 235 1150 : inline ConstructorOptions &SetNoCreateEmptyLayersArgument(bool b) 236 : { 237 1150 : addNoCreateEmptyLayersArgument = b; 238 1150 : return *this; 239 : } 240 : 241 506 : inline ConstructorOptions &SetAddSkipErrorsArgument(bool b) 242 : { 243 506 : addSkipErrorsArgument = b; 244 506 : return *this; 245 : } 246 : 247 206 : inline ConstructorOptions &SetAddOutputLayerNameArgument(bool b) 248 : { 249 206 : addOutputLayerNameArgument = b; 250 206 : return *this; 251 : } 252 : 253 : inline ConstructorOptions & 254 473 : SetOutputLayerNameAvailableInPipelineStep(bool b) 255 : { 256 473 : outputLayerNameAvailableInPipelineStep = b; 257 473 : return *this; 258 : } 259 : }; 260 : 261 : GDALPipelineStepAlgorithm(const std::string &name, 262 : const std::string &description, 263 : const std::string &helpURL, 264 : const ConstructorOptions &); 265 : 266 : friend class GDALPipelineAlgorithm; 267 : friend class GDALRasterPipelineAlgorithm; 268 : friend class GDALVectorPipelineAlgorithm; 269 : friend class GDALAbstractPipelineAlgorithm; 270 : 271 2019 : virtual bool CanBeFirstStep() const 272 : { 273 2019 : return false; 274 : } 275 : 276 505 : virtual bool CanBeMiddleStep() const 277 : { 278 505 : return !CanBeFirstStep() && !CanBeLastStep(); 279 : } 280 : 281 854 : virtual bool CanBeLastStep() const 282 : { 283 854 : return false; 284 : } 285 : 286 : //! Whether a user parameter can cause a file to be written at a specified location 287 49 : virtual bool GeneratesFilesFromUserInput() const 288 : { 289 49 : return false; 290 : } 291 : 292 725 : virtual bool IsNativelyStreamingCompatible() const 293 : { 294 725 : return true; 295 : } 296 : 297 252 : virtual bool SupportsInputMultiThreading() const 298 : { 299 252 : return false; 300 : } 301 : 302 1362 : virtual bool CanHandleNextStep(GDALPipelineStepAlgorithm *) const 303 : { 304 1362 : return false; 305 : } 306 : 307 0 : virtual bool OutputDatasetAllowedBeforeRunningStep() const 308 : { 309 0 : return false; 310 : } 311 : 312 249 : virtual CPLJSONObject Get_OGR_SCHEMA_OpenOption_Layer() const 313 : { 314 249 : CPLJSONObject obj; 315 249 : obj.Deinit(); 316 249 : return obj; 317 : } 318 : 319 : virtual bool RunStep(GDALPipelineStepRunContext &ctxt) = 0; 320 : 321 : bool m_standaloneStep = false; 322 : const ConstructorOptions m_constructorOptions; 323 : bool m_outputVRTCompatible = true; 324 : std::string m_helpDocCategory{}; 325 : 326 : // Input arguments 327 : std::vector<GDALArgDatasetValue> m_inputDataset{}; 328 : std::vector<std::string> m_openOptions{}; 329 : std::vector<std::string> m_inputFormats{}; 330 : std::vector<std::string> m_inputLayerNames{}; 331 : 332 : // Output arguments 333 : bool m_stdout = false; 334 : std::string m_output{}; 335 : GDALArgDatasetValue m_outputDataset{}; 336 : std::string m_format{}; 337 : std::vector<std::string> m_outputOpenOptions{}; 338 : std::vector<std::string> m_creationOptions{}; 339 : bool m_overwrite = false; 340 : std::string m_outputLayerName{}; 341 : GDALInConstructionAlgorithmArg *m_outputFormatArg = nullptr; 342 : bool m_appendRaster = false; 343 : 344 : // Output arguments (vector specific) 345 : std::vector<std::string> m_layerCreationOptions{}; 346 : bool m_update = false; 347 : bool m_overwriteLayer = false; 348 : bool m_appendLayer = false; 349 : bool m_upsert = false; 350 : bool m_skipErrors = false; 351 : bool m_noCreateEmptyLayers = false; 352 : 353 : void AddRasterInputArgs(bool openForMixedRasterVector, bool hiddenForCLI); 354 : void AddRasterOutputArgs(bool hiddenForCLI); 355 : void AddRasterHiddenInputDatasetArg(); 356 : 357 : void AddVectorInputArgs(bool hiddenForCLI); 358 : void AddVectorHiddenInputDatasetArg(); 359 : void AddVectorOutputArgs(bool hiddenForCLI, 360 : bool shortNameOutputLayerAllowed); 361 : using GDALAlgorithm::AddOutputLayerNameArg; 362 : void AddOutputLayerNameArg(bool hiddenForCLI, 363 : bool shortNameOutputLayerAllowed); 364 : 365 : private: 366 : bool RunImpl(GDALProgressFunc pfnProgress, void *pProgressData) override; 367 : GDALAlgorithm::ProcessGDALGOutputRet ProcessGDALGOutput() override; 368 : bool CheckSafeForStreamOutput() override; 369 : 370 : CPL_DISALLOW_COPY_ASSIGN(GDALPipelineStepAlgorithm) 371 : }; 372 : 373 : //! @endcond 374 : 375 : #endif