LCOV - code coverage report
Current view: top level - apps - gdalalg_vector_pipeline.h (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 33 37 89.2 %
Date: 2025-09-10 17:48:50 Functions: 67 74 90.5 %

          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             : class GDALRasterAlgorithmStepRegistry;
      32             : 
      33        2224 : class GDALVectorPipelineStepAlgorithm /* non final */
      34             :     : public GDALPipelineStepAlgorithm
      35             : {
      36             :   public:
      37             :     ~GDALVectorPipelineStepAlgorithm() override;
      38             : 
      39             :   protected:
      40             :     GDALVectorPipelineStepAlgorithm(const std::string &name,
      41             :                                     const std::string &description,
      42             :                                     const std::string &helpURL,
      43             :                                     bool standaloneStep);
      44             : 
      45             :     GDALVectorPipelineStepAlgorithm(const std::string &name,
      46             :                                     const std::string &description,
      47             :                                     const std::string &helpURL,
      48             :                                     const ConstructorOptions &options);
      49             : 
      50             :     friend class GDALVectorPipelineAlgorithm;
      51             :     friend class GDALVectorConcatAlgorithm;
      52             : 
      53         279 :     int GetInputType() const override
      54             :     {
      55         279 :         return GDAL_OF_VECTOR;
      56             :     }
      57             : 
      58         263 :     int GetOutputType() const override
      59             :     {
      60         263 :         return GDAL_OF_VECTOR;
      61             :     }
      62             : };
      63             : 
      64             : /************************************************************************/
      65             : /*                      GDALVectorAlgorithmStepRegistry                 */
      66             : /************************************************************************/
      67             : 
      68         274 : class GDALVectorAlgorithmStepRegistry : public virtual GDALAlgorithmRegistry
      69             : {
      70             :   public:
      71         274 :     GDALVectorAlgorithmStepRegistry() = default;
      72             :     ~GDALVectorAlgorithmStepRegistry() override;
      73             : 
      74             :     /** Register the algorithm of type MyAlgorithm.
      75             :      */
      76             :     template <class MyAlgorithm>
      77        6850 :     bool Register(const std::string &name = std::string())
      78             :     {
      79             :         static_assert(
      80             :             std::is_base_of_v<GDALVectorPipelineStepAlgorithm, MyAlgorithm>,
      81             :             "Algorithm is not a GDALVectorPipelineStepAlgorithm");
      82             : 
      83       13700 :         AlgInfo info;
      84        6850 :         info.m_name = name.empty() ? MyAlgorithm::NAME : name;
      85        6850 :         info.m_aliases = MyAlgorithm::GetAliasesStatic();
      86        8219 :         info.m_creationFunc = []() -> std::unique_ptr<GDALAlgorithm>
      87        1369 :         { return std::make_unique<MyAlgorithm>(); };
      88       13700 :         return GDALAlgorithmRegistry::Register(info);
      89             :     }
      90             : };
      91             : 
      92             : /************************************************************************/
      93             : /*                     GDALVectorPipelineAlgorithm                      */
      94             : /************************************************************************/
      95             : 
      96             : class GDALVectorPipelineAlgorithm final : public GDALAbstractPipelineAlgorithm
      97             : {
      98             :   public:
      99             :     static constexpr const char *NAME = "pipeline";
     100             :     static constexpr const char *DESCRIPTION =
     101             :         "Process a vector dataset applying several steps.";
     102             :     static constexpr const char *HELP_URL =
     103             :         "/programs/gdal_vector_pipeline.html";
     104             : 
     105         649 :     static std::vector<std::string> GetAliasesStatic()
     106             :     {
     107             :         return {
     108             : #ifdef GDAL_PIPELINE_PROJ_NOSTALGIA
     109             :             GDALAlgorithmRegistry::HIDDEN_ALIAS_SEPARATOR,
     110             :             "+pipeline",
     111             :             "+gdal=pipeline",
     112             : #endif
     113        2596 :         };
     114             :     }
     115             : 
     116             :     GDALVectorPipelineAlgorithm();
     117             : 
     118             :     std::string GetUsageForCLI(bool shortUsage,
     119             :                                const UsageOptions &usageOptions) const override;
     120             : 
     121             :     static void RegisterAlgorithms(GDALVectorAlgorithmStepRegistry &registry,
     122             :                                    bool forMixedPipeline);
     123             : 
     124          95 :     int GetInputType() const override
     125             :     {
     126          95 :         return GDAL_OF_VECTOR;
     127             :     }
     128             : 
     129           0 :     int GetOutputType() const override
     130             :     {
     131           0 :         return GDAL_OF_VECTOR;
     132             :     }
     133             : 
     134             :   protected:
     135             :     GDALVectorAlgorithmStepRegistry m_stepRegistry{};
     136             : 
     137         146 :     GDALAlgorithmRegistry &GetStepRegistry() override
     138             :     {
     139         146 :         return m_stepRegistry;
     140             :     }
     141             : 
     142         712 :     const GDALAlgorithmRegistry &GetStepRegistry() const override
     143             :     {
     144         712 :         return m_stepRegistry;
     145             :     }
     146             : 
     147             :   private:
     148             :     std::unique_ptr<GDALAbstractPipelineAlgorithm>
     149           0 :     CreateNestedPipeline() const override
     150             :     {
     151           0 :         return std::make_unique<GDALVectorPipelineAlgorithm>();
     152             :     }
     153             : };
     154             : 
     155             : /************************************************************************/
     156             : /*                  GDALVectorPipelineOutputLayer                       */
     157             : /************************************************************************/
     158             : 
     159             : /** Class that implements GetNextFeature() by forwarding to
     160             :  * OGRLayerWithTranslateFeature::TranslateFeature() implementation, which
     161             :  * might return several features.
     162             :  */
     163         129 : class GDALVectorPipelineOutputLayer /* non final */
     164             :     : public OGRLayerWithTranslateFeature,
     165             :       public OGRGetNextFeatureThroughRaw<GDALVectorPipelineOutputLayer>
     166             : {
     167             :   protected:
     168             :     explicit GDALVectorPipelineOutputLayer(OGRLayer &oSrcLayer);
     169             :     ~GDALVectorPipelineOutputLayer() override;
     170             : 
     171        1553 :     DEFINE_GET_NEXT_FEATURE_THROUGH_RAW(GDALVectorPipelineOutputLayer)
     172             : 
     173             :     OGRLayer &m_srcLayer;
     174             : 
     175             :   public:
     176             :     void ResetReading() override;
     177             :     OGRFeature *GetNextRawFeature();
     178             : 
     179             :   private:
     180             :     std::vector<std::unique_ptr<OGRFeature>> m_pendingFeatures{};
     181             :     size_t m_idxInPendingFeatures = 0;
     182             : };
     183             : 
     184             : /************************************************************************/
     185             : /*                  GDALVectorPipelinePassthroughLayer                  */
     186             : /************************************************************************/
     187             : 
     188             : /** Class that forwards GetNextFeature() calls to the source layer and
     189             :  * can be added to GDALVectorPipelineOutputDataset::AddLayer()
     190             :  */
     191             : class GDALVectorPipelinePassthroughLayer /* non final */
     192             :     : public GDALVectorPipelineOutputLayer
     193             : {
     194             :   public:
     195          12 :     explicit GDALVectorPipelinePassthroughLayer(OGRLayer &oSrcLayer)
     196          12 :         : GDALVectorPipelineOutputLayer(oSrcLayer)
     197             :     {
     198          12 :     }
     199             : 
     200             :     const OGRFeatureDefn *GetLayerDefn() const override;
     201             : 
     202           4 :     int TestCapability(const char *pszCap) const override
     203             :     {
     204           4 :         return m_srcLayer.TestCapability(pszCap);
     205             :     }
     206             : 
     207          28 :     void TranslateFeature(
     208             :         std::unique_ptr<OGRFeature> poSrcFeature,
     209             :         std::vector<std::unique_ptr<OGRFeature>> &apoOutFeatures) override
     210             :     {
     211          28 :         apoOutFeatures.push_back(std::move(poSrcFeature));
     212          28 :     }
     213             : };
     214             : 
     215             : /************************************************************************/
     216             : /*                 GDALVectorNonStreamingAlgorithmDataset               */
     217             : /************************************************************************/
     218             : 
     219             : class MEMDataset;
     220             : 
     221             : /**
     222             :  * Dataset used to read all input features into memory and perform some
     223             :  * processing.
     224             :  */
     225          30 : class GDALVectorNonStreamingAlgorithmDataset /* non final */
     226             :     : public GDALDataset
     227             : {
     228             :   public:
     229             :     GDALVectorNonStreamingAlgorithmDataset();
     230             :     ~GDALVectorNonStreamingAlgorithmDataset() override;
     231             : 
     232             :     virtual bool Process(OGRLayer &srcLayer, OGRLayer &dstLayer) = 0;
     233             : 
     234             :     bool AddProcessedLayer(OGRLayer &srcLayer);
     235             :     bool AddProcessedLayer(OGRLayer &srcLayer, OGRFeatureDefn &dstDefn);
     236             :     void AddPassThroughLayer(OGRLayer &oLayer);
     237             :     int GetLayerCount() const final override;
     238             :     OGRLayer *GetLayer(int idx) const final override;
     239             :     int TestCapability(const char *pszCap) const override;
     240             : 
     241             :   private:
     242             :     std::vector<std::unique_ptr<OGRLayer>> m_passthrough_layers{};
     243             :     std::vector<OGRLayer *> m_layers{};
     244             :     std::unique_ptr<MEMDataset> m_ds{};
     245             : };
     246             : 
     247             : /************************************************************************/
     248             : /*                 GDALVectorPipelineOutputDataset                      */
     249             : /************************************************************************/
     250             : 
     251             : /** Class used by vector pipeline steps to create an output on-the-fly
     252             :  * dataset where they can store on-the-fly layers.
     253             :  */
     254             : class GDALVectorPipelineOutputDataset final : public GDALDataset
     255             : {
     256             :     GDALDataset &m_srcDS;
     257             :     std::map<OGRLayer *, OGRLayerWithTranslateFeature *>
     258             :         m_mapSrcLayerToNewLayer{};
     259             :     std::vector<std::unique_ptr<OGRLayerWithTranslateFeature>>
     260             :         m_layersToDestroy{};
     261             :     std::vector<OGRLayerWithTranslateFeature *> m_layers{};
     262             : 
     263             :     OGRLayerWithTranslateFeature *m_belongingLayer = nullptr;
     264             :     std::vector<std::unique_ptr<OGRFeature>> m_pendingFeatures{};
     265             :     size_t m_idxInPendingFeatures = 0;
     266             : 
     267             :     CPL_DISALLOW_COPY_ASSIGN(GDALVectorPipelineOutputDataset)
     268             : 
     269             :   public:
     270             :     explicit GDALVectorPipelineOutputDataset(GDALDataset &oSrcDS);
     271             : 
     272             :     void AddLayer(OGRLayer &oSrcLayer,
     273             :                   std::unique_ptr<OGRLayerWithTranslateFeature> poNewLayer);
     274             : 
     275             :     int GetLayerCount() const override;
     276             : 
     277             :     OGRLayer *GetLayer(int idx) const override;
     278             : 
     279             :     int TestCapability(const char *pszCap) const override;
     280             : 
     281             :     void ResetReading() override;
     282             : 
     283             :     OGRFeature *GetNextFeature(OGRLayer **ppoBelongingLayer,
     284             :                                double *pdfProgressPct,
     285             :                                GDALProgressFunc pfnProgress,
     286             :                                void *pProgressData) override;
     287             : };
     288             : 
     289             : //! @endcond
     290             : 
     291             : #endif

Generated by: LCOV version 1.14