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 179 : std::vector<GDALArgDatasetValue> &GetInputDatasets() 32 : { 33 179 : return m_inputDataset; 34 : } 35 : 36 : const std::vector<GDALArgDatasetValue> &GetInputDatasets() const 37 : { 38 : return m_inputDataset; 39 : } 40 : 41 206 : GDALArgDatasetValue &GetOutputDataset() 42 : { 43 206 : return m_outputDataset; 44 : } 45 : 46 : const GDALArgDatasetValue &GetOutputDataset() const 47 : { 48 : return m_outputDataset; 49 : } 50 : 51 737 : const std::string &GetOutputString() const 52 : { 53 737 : return m_output; 54 : } 55 : 56 60 : const std::string &GetOutputLayerName() const 57 : { 58 60 : return m_outputLayerName; 59 : } 60 : 61 222 : const std::string &GetOutputFormat() const 62 : { 63 222 : return m_format; 64 : } 65 : 66 100 : const std::vector<std::string> &GetCreationOptions() const 67 : { 68 100 : return m_creationOptions; 69 : } 70 : 71 79 : const std::vector<std::string> &GetLayerCreationOptions() const 72 : { 73 79 : return m_layerCreationOptions; 74 : } 75 : 76 93 : bool GetOverwriteLayer() const 77 : { 78 93 : return m_overwriteLayer; 79 : } 80 : 81 52 : bool GetAppendLayer() const 82 : { 83 52 : 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 41 : GDALDataset *GetInputDatasetRef() 94 : { 95 41 : return m_inputDataset.empty() ? nullptr 96 41 : : 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 : 128 11992 : inline ConstructorOptions &SetStandaloneStep(bool b) 129 : { 130 11992 : standaloneStep = b; 131 11992 : return *this; 132 : } 133 : 134 6045 : inline ConstructorOptions &SetAddDefaultArguments(bool b) 135 : { 136 6045 : addDefaultArguments = b; 137 6045 : return *this; 138 : } 139 : 140 541 : inline ConstructorOptions &SetAddInputLayerNameArgument(bool b) 141 : { 142 541 : addInputLayerNameArgument = b; 143 541 : return *this; 144 : } 145 : 146 523 : inline ConstructorOptions &SetInputDatasetRequired(bool b) 147 : { 148 523 : inputDatasetRequired = b; 149 523 : return *this; 150 : } 151 : 152 523 : inline ConstructorOptions &SetInputDatasetPositional(bool b) 153 : { 154 523 : inputDatasetPositional = b; 155 523 : return *this; 156 : } 157 : 158 3386 : inline ConstructorOptions &SetInputDatasetMaxCount(int maxCount) 159 : { 160 3386 : inputDatasetMaxCount = maxCount; 161 3386 : return *this; 162 : } 163 : 164 256 : inline ConstructorOptions &SetInputDatasetInputFlags(int flags) 165 : { 166 256 : inputDatasetInputFlags = flags; 167 256 : return *this; 168 : } 169 : 170 654 : inline ConstructorOptions &SetInputDatasetHelpMsg(const std::string &s) 171 : { 172 654 : inputDatasetHelpMsg = s; 173 654 : return *this; 174 : } 175 : 176 1365 : inline ConstructorOptions &SetInputDatasetAlias(const std::string &s) 177 : { 178 1365 : inputDatasetAlias = s; 179 1365 : return *this; 180 : } 181 : 182 1058 : inline ConstructorOptions &SetInputDatasetMetaVar(const std::string &s) 183 : { 184 1058 : inputDatasetMetaVar = s; 185 1058 : return *this; 186 : } 187 : 188 272 : inline ConstructorOptions &SetOutputDatasetHelpMsg(const std::string &s) 189 : { 190 272 : outputDatasetHelpMsg = s; 191 272 : return *this; 192 : } 193 : 194 1628 : inline ConstructorOptions &SetAutoOpenInputDatasets(bool b) 195 : { 196 1628 : autoOpenInputDatasets = b; 197 1628 : return *this; 198 : } 199 : 200 98 : inline ConstructorOptions &SetOutputDatasetRequired(bool b) 201 : { 202 98 : outputDatasetRequired = b; 203 98 : return *this; 204 : } 205 : 206 : inline ConstructorOptions & 207 1904 : SetOutputFormatCreateCapability(const std::string &capability) 208 : { 209 1904 : outputFormatCreateCapability = capability; 210 1904 : return *this; 211 : } 212 : 213 334 : inline ConstructorOptions &SetAddAppendLayerArgument(bool b) 214 : { 215 334 : addAppendLayerArgument = b; 216 334 : return *this; 217 : } 218 : 219 203 : inline ConstructorOptions &SetAddOverwriteLayerArgument(bool b) 220 : { 221 203 : addOverwriteLayerArgument = b; 222 203 : return *this; 223 : } 224 : 225 203 : inline ConstructorOptions &SetAddUpdateArgument(bool b) 226 : { 227 203 : addUpdateArgument = b; 228 203 : return *this; 229 : } 230 : 231 627 : inline ConstructorOptions &SetAddUpsertArgument(bool b) 232 : { 233 627 : addUpsertArgument = b; 234 627 : return *this; 235 : } 236 : 237 1205 : inline ConstructorOptions &SetNoCreateEmptyLayersArgument(bool b) 238 : { 239 1205 : addNoCreateEmptyLayersArgument = b; 240 1205 : return *this; 241 : } 242 : 243 627 : inline ConstructorOptions &SetAddSkipErrorsArgument(bool b) 244 : { 245 627 : addSkipErrorsArgument = b; 246 627 : return *this; 247 : } 248 : 249 206 : inline ConstructorOptions &SetAddOutputLayerNameArgument(bool b) 250 : { 251 206 : addOutputLayerNameArgument = b; 252 206 : return *this; 253 : } 254 : 255 : inline ConstructorOptions & 256 599 : SetOutputLayerNameAvailableInPipelineStep(bool b) 257 : { 258 599 : outputLayerNameAvailableInPipelineStep = b; 259 599 : return *this; 260 : } 261 : }; 262 : 263 : GDALPipelineStepAlgorithm(const std::string &name, 264 : const std::string &description, 265 : const std::string &helpURL, 266 : const ConstructorOptions &); 267 : 268 : friend class GDALPipelineAlgorithm; 269 : friend class GDALRasterPipelineAlgorithm; 270 : friend class GDALVectorPipelineAlgorithm; 271 : friend class GDALMdimPipelineAlgorithm; 272 : friend class GDALAbstractPipelineAlgorithm; 273 : 274 2145 : virtual bool CanBeFirstStep() const 275 : { 276 2145 : return false; 277 : } 278 : 279 544 : virtual bool CanBeMiddleStep() const 280 : { 281 544 : return !CanBeFirstStep() && !CanBeLastStep(); 282 : } 283 : 284 921 : virtual bool CanBeLastStep() const 285 : { 286 921 : return false; 287 : } 288 : 289 : //! Whether a user parameter can cause a file to be written at a specified location 290 54 : virtual bool GeneratesFilesFromUserInput() const 291 : { 292 54 : return false; 293 : } 294 : 295 830 : virtual bool IsNativelyStreamingCompatible() const 296 : { 297 830 : return true; 298 : } 299 : 300 281 : virtual bool SupportsInputMultiThreading() const 301 : { 302 281 : return false; 303 : } 304 : 305 1502 : virtual bool CanHandleNextStep(GDALPipelineStepAlgorithm *) const 306 : { 307 1502 : return false; 308 : } 309 : 310 0 : virtual bool OutputDatasetAllowedBeforeRunningStep() const 311 : { 312 0 : return false; 313 : } 314 : 315 276 : virtual CPLJSONObject Get_OGR_SCHEMA_OpenOption_Layer() const 316 : { 317 276 : CPLJSONObject obj; 318 276 : obj.Deinit(); 319 276 : return obj; 320 : } 321 : 322 : virtual bool RunStep(GDALPipelineStepRunContext &ctxt) = 0; 323 : 324 : bool m_standaloneStep = false; 325 : const ConstructorOptions m_constructorOptions; 326 : bool m_outputVRTCompatible = true; 327 : std::string m_helpDocCategory{}; 328 : 329 : // Input arguments 330 : std::vector<GDALArgDatasetValue> m_inputDataset{}; 331 : std::vector<std::string> m_openOptions{}; 332 : std::vector<std::string> m_inputFormats{}; 333 : std::vector<std::string> m_inputLayerNames{}; 334 : 335 : // Output arguments 336 : bool m_stdout = false; 337 : std::string m_output{}; 338 : GDALArgDatasetValue m_outputDataset{}; 339 : std::string m_format{}; 340 : std::vector<std::string> m_outputOpenOptions{}; 341 : std::vector<std::string> m_creationOptions{}; 342 : bool m_overwrite = false; 343 : std::string m_outputLayerName{}; 344 : GDALInConstructionAlgorithmArg *m_outputFormatArg = nullptr; 345 : bool m_appendRaster = false; 346 : 347 : // Output arguments (vector specific) 348 : std::vector<std::string> m_layerCreationOptions{}; 349 : bool m_update = false; 350 : bool m_overwriteLayer = false; 351 : bool m_appendLayer = false; 352 : bool m_upsert = false; 353 : bool m_skipErrors = false; 354 : bool m_noCreateEmptyLayers = false; 355 : 356 : void AddRasterInputArgs(bool openForMixedRasterVector, bool hiddenForCLI); 357 : void AddRasterOutputArgs(bool hiddenForCLI); 358 : void AddRasterHiddenInputDatasetArg(); 359 : 360 : void AddVectorInputArgs(bool hiddenForCLI); 361 : void AddVectorHiddenInputDatasetArg(); 362 : void AddVectorOutputArgs(bool hiddenForCLI, 363 : bool shortNameOutputLayerAllowed); 364 : using GDALAlgorithm::AddOutputLayerNameArg; 365 : void AddOutputLayerNameArg(bool hiddenForCLI, 366 : bool shortNameOutputLayerAllowed); 367 : 368 : void AddMdimInputArgs(bool openForMixedRasterVector, bool hiddenForCLI, 369 : bool acceptRaster); 370 : void AddMdimOutputArgs(bool hiddenForCLI); 371 : void AddMdimHiddenInputDatasetArg(); 372 : 373 : bool CreateDatasetSingleOutputLayerIfNeeded( 374 : GDALPipelineStepRunContext &ctxt, const std::string &defaultLayerName, 375 : GDALDataset *&poDstDS, bool &bTemporaryFile, 376 : std::unique_ptr<GDALDataset> &poNewRetDS, std::string &outputLayerName, 377 : OGRLayer *&poDstLayer); 378 : 379 : private: 380 : bool RunImpl(GDALProgressFunc pfnProgress, void *pProgressData) override; 381 : GDALAlgorithm::ProcessGDALGOutputRet ProcessGDALGOutput() override; 382 : bool CheckSafeForStreamOutput() override; 383 : 384 : CPL_DISALLOW_COPY_ASSIGN(GDALPipelineStepAlgorithm) 385 : }; 386 : 387 : //! @endcond 388 : 389 : #endif