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