LCOV - code coverage report
Current view: top level - apps - gdalalg_vector_pipeline.h (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 19 19 100.0 %
Date: 2025-06-19 12:30:01 Functions: 12 16 75.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  GDAL
       4             :  * Purpose:  gdal "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 GDALALG_VECTOR_PIPELINE_INCLUDED
      14             : #define GDALALG_VECTOR_PIPELINE_INCLUDED
      15             : 
      16             : #include "gdalalgorithm.h"
      17             : #include "gdalalg_abstract_pipeline.h"
      18             : 
      19             : #include "ogrsf_frmts.h"
      20             : #include "ogrlayerwithtranslatefeature.h"
      21             : 
      22             : #include <map>
      23             : #include <vector>
      24             : 
      25             : //! @cond Doxygen_Suppress
      26             : 
      27             : /************************************************************************/
      28             : /*                GDALVectorPipelineStepAlgorithm                       */
      29             : /************************************************************************/
      30             : 
      31        1051 : class GDALVectorPipelineStepAlgorithm /* non final */
      32             :     : public GDALPipelineStepAlgorithm
      33             : {
      34             :   public:
      35             :     ~GDALVectorPipelineStepAlgorithm() override;
      36             : 
      37             :   protected:
      38             :     GDALVectorPipelineStepAlgorithm(const std::string &name,
      39             :                                     const std::string &description,
      40             :                                     const std::string &helpURL,
      41             :                                     bool standaloneStep);
      42             : 
      43             :     GDALVectorPipelineStepAlgorithm(const std::string &name,
      44             :                                     const std::string &description,
      45             :                                     const std::string &helpURL,
      46             :                                     const ConstructorOptions &options);
      47             : 
      48             :     friend class GDALVectorPipelineAlgorithm;
      49             :     friend class GDALAbstractPipelineAlgorithm<GDALVectorPipelineStepAlgorithm>;
      50             :     friend class GDALVectorConcatAlgorithm;
      51             : 
      52         135 :     int GetInputType() const override
      53             :     {
      54         135 :         return GDAL_OF_VECTOR;
      55             :     }
      56             : 
      57         141 :     int GetOutputType() const override
      58             :     {
      59         141 :         return GDAL_OF_VECTOR;
      60             :     }
      61             : };
      62             : 
      63             : /************************************************************************/
      64             : /*                     GDALVectorPipelineAlgorithm                      */
      65             : /************************************************************************/
      66             : 
      67             : // This is an easter egg to pay tribute to PROJ pipeline syntax
      68             : // We accept "gdal vector +gdal=pipeline +step +gdal=read +input=poly.gpkg +step +gdal=reproject +dst-crs=EPSG:32632 +step +gdal=write +output=out.gpkg +overwrite"
      69             : // as an alternative to (recommended):
      70             : // "gdal vector pipeline ! read poly.gpkg ! reproject--dst-crs=EPSG:32632 ! write out.gpkg --overwrite"
      71             : #define GDAL_PIPELINE_PROJ_NOSTALGIA
      72             : 
      73             : class GDALVectorPipelineAlgorithm final
      74             :     : public GDALAbstractPipelineAlgorithm<GDALVectorPipelineStepAlgorithm>
      75             : {
      76             :   public:
      77             :     static constexpr const char *NAME = "pipeline";
      78             :     static constexpr const char *DESCRIPTION = "Process a vector dataset.";
      79             :     static constexpr const char *HELP_URL =
      80             :         "/programs/gdal_vector_pipeline.html";
      81             : 
      82         526 :     static std::vector<std::string> GetAliasesStatic()
      83             :     {
      84             :         return {
      85             : #ifdef GDAL_PIPELINE_PROJ_NOSTALGIA
      86             :             GDALAlgorithmRegistry::HIDDEN_ALIAS_SEPARATOR,
      87             :             "+pipeline",
      88             :             "+gdal=pipeline",
      89             : #endif
      90        2104 :         };
      91             :     }
      92             : 
      93             :     GDALVectorPipelineAlgorithm();
      94             : 
      95             :     bool
      96             :     ParseCommandLineArguments(const std::vector<std::string> &args) override;
      97             : 
      98             :     std::string GetUsageForCLI(bool shortUsage,
      99             :                                const UsageOptions &usageOptions) const override;
     100             : 
     101             :     static void RegisterAlgorithms(GDALAlgorithmRegistry &registry,
     102             :                                    bool forMixedPipeline);
     103             : };
     104             : 
     105             : /************************************************************************/
     106             : /*                  GDALVectorPipelineOutputLayer                       */
     107             : /************************************************************************/
     108             : 
     109             : /** Class that implements GetNextFeature() by forwarding to
     110             :  * OGRLayerWithTranslateFeature::TranslateFeature() implementation, which
     111             :  * might return several features.
     112             :  */
     113         106 : class GDALVectorPipelineOutputLayer /* non final */
     114             :     : public OGRLayerWithTranslateFeature,
     115             :       public OGRGetNextFeatureThroughRaw<GDALVectorPipelineOutputLayer>
     116             : {
     117             :   protected:
     118             :     explicit GDALVectorPipelineOutputLayer(OGRLayer &oSrcLayer);
     119             :     ~GDALVectorPipelineOutputLayer();
     120             : 
     121        1426 :     DEFINE_GET_NEXT_FEATURE_THROUGH_RAW(GDALVectorPipelineOutputLayer)
     122             : 
     123             :     OGRLayer &m_srcLayer;
     124             : 
     125             :   public:
     126             :     void ResetReading() override;
     127             :     OGRFeature *GetNextRawFeature();
     128             : 
     129             :   private:
     130             :     std::vector<std::unique_ptr<OGRFeature>> m_pendingFeatures{};
     131             :     size_t m_idxInPendingFeatures = 0;
     132             : };
     133             : 
     134             : /************************************************************************/
     135             : /*                  GDALVectorPipelinePassthroughLayer                  */
     136             : /************************************************************************/
     137             : 
     138             : /** Class that forwards GetNextFeature() calls to the source layer and
     139             :  * can be added to GDALVectorPipelineOutputDataset::AddLayer()
     140             :  */
     141             : class GDALVectorPipelinePassthroughLayer /* non final */
     142             :     : public GDALVectorPipelineOutputLayer
     143             : {
     144             :   public:
     145           9 :     explicit GDALVectorPipelinePassthroughLayer(OGRLayer &oSrcLayer)
     146           9 :         : GDALVectorPipelineOutputLayer(oSrcLayer)
     147             :     {
     148           9 :     }
     149             : 
     150             :     OGRFeatureDefn *GetLayerDefn() override;
     151             : 
     152           4 :     int TestCapability(const char *pszCap) override
     153             :     {
     154           4 :         return m_srcLayer.TestCapability(pszCap);
     155             :     }
     156             : 
     157          25 :     void TranslateFeature(
     158             :         std::unique_ptr<OGRFeature> poSrcFeature,
     159             :         std::vector<std::unique_ptr<OGRFeature>> &apoOutFeatures) override
     160             :     {
     161          25 :         apoOutFeatures.push_back(std::move(poSrcFeature));
     162          25 :     }
     163             : };
     164             : 
     165             : /************************************************************************/
     166             : /*                 GDALVectorNonStreamingAlgorithmDataset               */
     167             : /************************************************************************/
     168             : 
     169             : class MEMDataset;
     170             : 
     171             : /**
     172             :  * Dataset used to read all input features into memory and perform some
     173             :  * processing.
     174             :  */
     175           8 : class GDALVectorNonStreamingAlgorithmDataset /* non final */
     176             :     : public GDALDataset
     177             : {
     178             :   public:
     179             :     GDALVectorNonStreamingAlgorithmDataset();
     180             :     ~GDALVectorNonStreamingAlgorithmDataset();
     181             : 
     182             :     virtual bool Process(OGRLayer &srcLayer, OGRLayer &dstLayer) = 0;
     183             : 
     184             :     bool AddProcessedLayer(OGRLayer &srcLayer);
     185             :     void AddPassThroughLayer(OGRLayer &oLayer);
     186             :     int GetLayerCount() final override;
     187             :     OGRLayer *GetLayer(int idx) final override;
     188             :     int TestCapability(const char *pszCap) override;
     189             : 
     190             :   private:
     191             :     std::vector<std::unique_ptr<OGRLayer>> m_passthrough_layers{};
     192             :     std::vector<OGRLayer *> m_layers{};
     193             :     std::unique_ptr<MEMDataset> m_ds{};
     194             : };
     195             : 
     196             : /************************************************************************/
     197             : /*                 GDALVectorPipelineOutputDataset                      */
     198             : /************************************************************************/
     199             : 
     200             : /** Class used by vector pipeline steps to create an output on-the-fly
     201             :  * dataset where they can store on-the-fly layers.
     202             :  */
     203         198 : class GDALVectorPipelineOutputDataset final : public GDALDataset
     204             : {
     205             :     GDALDataset &m_srcDS;
     206             :     std::map<OGRLayer *, OGRLayerWithTranslateFeature *>
     207             :         m_mapSrcLayerToNewLayer{};
     208             :     std::vector<std::unique_ptr<OGRLayerWithTranslateFeature>>
     209             :         m_layersToDestroy{};
     210             :     std::vector<OGRLayerWithTranslateFeature *> m_layers{};
     211             : 
     212             :     OGRLayerWithTranslateFeature *m_belongingLayer = nullptr;
     213             :     std::vector<std::unique_ptr<OGRFeature>> m_pendingFeatures{};
     214             :     size_t m_idxInPendingFeatures = 0;
     215             : 
     216             :     CPL_DISALLOW_COPY_ASSIGN(GDALVectorPipelineOutputDataset)
     217             : 
     218             :   public:
     219             :     explicit GDALVectorPipelineOutputDataset(GDALDataset &oSrcDS);
     220             :     ~GDALVectorPipelineOutputDataset();
     221             : 
     222             :     void AddLayer(OGRLayer &oSrcLayer,
     223             :                   std::unique_ptr<OGRLayerWithTranslateFeature> poNewLayer);
     224             : 
     225             :     int GetLayerCount() override;
     226             : 
     227             :     OGRLayer *GetLayer(int idx) override;
     228             : 
     229             :     int TestCapability(const char *pszCap) override;
     230             : 
     231             :     void ResetReading() override;
     232             : 
     233             :     OGRFeature *GetNextFeature(OGRLayer **ppoBelongingLayer,
     234             :                                double *pdfProgressPct,
     235             :                                GDALProgressFunc pfnProgress,
     236             :                                void *pProgressData) override;
     237             : };
     238             : 
     239             : //! @endcond
     240             : 
     241             : #endif

Generated by: LCOV version 1.14