LCOV - code coverage report
Current view: top level - apps - gdalalg_vector_pipeline.h (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 33 39 84.6 %
Date: 2025-10-01 17:07:58 Functions: 69 76 90.8 %

          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        2129 : 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         316 :     int GetInputType() const override
      54             :     {
      55         316 :         return GDAL_OF_VECTOR;
      56             :     }
      57             : 
      58         303 :     int GetOutputType() const override
      59             :     {
      60         303 :         return GDAL_OF_VECTOR;
      61             :     }
      62             : };
      63             : 
      64             : /************************************************************************/
      65             : /*                      GDALVectorAlgorithmStepRegistry                 */
      66             : /************************************************************************/
      67             : 
      68         281 : class GDALVectorAlgorithmStepRegistry : public virtual GDALAlgorithmRegistry
      69             : {
      70             :   public:
      71         281 :     GDALVectorAlgorithmStepRegistry() = default;
      72             :     ~GDALVectorAlgorithmStepRegistry() override;
      73             : 
      74             :     /** Register the algorithm of type MyAlgorithm.
      75             :      */
      76             :     template <class MyAlgorithm>
      77        7306 :     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       14612 :         AlgInfo info;
      84        7306 :         info.m_name = name.empty() ? MyAlgorithm::NAME : name;
      85        7306 :         info.m_aliases = MyAlgorithm::GetAliasesStatic();
      86        8477 :         info.m_creationFunc = []() -> std::unique_ptr<GDALAlgorithm>
      87        1171 :         { return std::make_unique<MyAlgorithm>(); };
      88       14612 :         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         687 :     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        2748 :         };
     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          94 :     int GetInputType() const override
     125             :     {
     126          94 :         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         152 :     GDALAlgorithmRegistry &GetStepRegistry() override
     138             :     {
     139         152 :         return m_stepRegistry;
     140             :     }
     141             : 
     142         618 :     const GDALAlgorithmRegistry &GetStepRegistry() const override
     143             :     {
     144         618 :         return m_stepRegistry;
     145             :     }
     146             : 
     147             :   private:
     148             :     std::unique_ptr<GDALAbstractPipelineAlgorithm>
     149           0 :     CreateNestedPipeline() const override
     150             :     {
     151           0 :         auto pipeline = std::make_unique<GDALVectorPipelineAlgorithm>();
     152           0 :         pipeline->m_bInnerPipeline = true;
     153           0 :         return pipeline;
     154             :     }
     155             : };
     156             : 
     157             : /************************************************************************/
     158             : /*                  GDALVectorPipelineOutputLayer                       */
     159             : /************************************************************************/
     160             : 
     161             : /** Class that implements GetNextFeature() by forwarding to
     162             :  * OGRLayerWithTranslateFeature::TranslateFeature() implementation, which
     163             :  * might return several features.
     164             :  */
     165         167 : class GDALVectorPipelineOutputLayer /* non final */
     166             :     : public OGRLayerWithTranslateFeature,
     167             :       public OGRGetNextFeatureThroughRaw<GDALVectorPipelineOutputLayer>
     168             : {
     169             :   protected:
     170             :     explicit GDALVectorPipelineOutputLayer(OGRLayer &oSrcLayer);
     171             :     ~GDALVectorPipelineOutputLayer() override;
     172             : 
     173        1622 :     DEFINE_GET_NEXT_FEATURE_THROUGH_RAW(GDALVectorPipelineOutputLayer)
     174             : 
     175             :     OGRLayer &m_srcLayer;
     176             : 
     177             :   public:
     178             :     void ResetReading() override;
     179             :     OGRFeature *GetNextRawFeature();
     180             : 
     181             :   private:
     182             :     std::vector<std::unique_ptr<OGRFeature>> m_pendingFeatures{};
     183             :     size_t m_idxInPendingFeatures = 0;
     184             : };
     185             : 
     186             : /************************************************************************/
     187             : /*                  GDALVectorPipelinePassthroughLayer                  */
     188             : /************************************************************************/
     189             : 
     190             : /** Class that forwards GetNextFeature() calls to the source layer and
     191             :  * can be added to GDALVectorPipelineOutputDataset::AddLayer()
     192             :  */
     193             : class GDALVectorPipelinePassthroughLayer /* non final */
     194             :     : public GDALVectorPipelineOutputLayer
     195             : {
     196             :   public:
     197          12 :     explicit GDALVectorPipelinePassthroughLayer(OGRLayer &oSrcLayer)
     198          12 :         : GDALVectorPipelineOutputLayer(oSrcLayer)
     199             :     {
     200          12 :     }
     201             : 
     202             :     const OGRFeatureDefn *GetLayerDefn() const override;
     203             : 
     204           4 :     int TestCapability(const char *pszCap) const override
     205             :     {
     206           4 :         return m_srcLayer.TestCapability(pszCap);
     207             :     }
     208             : 
     209          28 :     void TranslateFeature(
     210             :         std::unique_ptr<OGRFeature> poSrcFeature,
     211             :         std::vector<std::unique_ptr<OGRFeature>> &apoOutFeatures) override
     212             :     {
     213          28 :         apoOutFeatures.push_back(std::move(poSrcFeature));
     214          28 :     }
     215             : };
     216             : 
     217             : /************************************************************************/
     218             : /*                 GDALVectorNonStreamingAlgorithmDataset               */
     219             : /************************************************************************/
     220             : 
     221             : class MEMDataset;
     222             : 
     223             : /**
     224             :  * Dataset used to read all input features into memory and perform some
     225             :  * processing.
     226             :  */
     227          30 : class GDALVectorNonStreamingAlgorithmDataset /* non final */
     228             :     : public GDALDataset
     229             : {
     230             :   public:
     231             :     GDALVectorNonStreamingAlgorithmDataset();
     232             :     ~GDALVectorNonStreamingAlgorithmDataset() override;
     233             : 
     234             :     virtual bool Process(OGRLayer &srcLayer, OGRLayer &dstLayer) = 0;
     235             : 
     236             :     bool AddProcessedLayer(OGRLayer &srcLayer);
     237             :     bool AddProcessedLayer(OGRLayer &srcLayer, OGRFeatureDefn &dstDefn);
     238             :     void AddPassThroughLayer(OGRLayer &oLayer);
     239             :     int GetLayerCount() const final override;
     240             :     OGRLayer *GetLayer(int idx) const final override;
     241             :     int TestCapability(const char *pszCap) const override;
     242             : 
     243             :   private:
     244             :     std::vector<std::unique_ptr<OGRLayer>> m_passthrough_layers{};
     245             :     std::vector<OGRLayer *> m_layers{};
     246             :     std::unique_ptr<MEMDataset> m_ds{};
     247             : };
     248             : 
     249             : /************************************************************************/
     250             : /*                 GDALVectorPipelineOutputDataset                      */
     251             : /************************************************************************/
     252             : 
     253             : /** Class used by vector pipeline steps to create an output on-the-fly
     254             :  * dataset where they can store on-the-fly layers.
     255             :  */
     256             : class GDALVectorPipelineOutputDataset final : public GDALDataset
     257             : {
     258             :     GDALDataset &m_srcDS;
     259             :     std::map<OGRLayer *, OGRLayerWithTranslateFeature *>
     260             :         m_mapSrcLayerToNewLayer{};
     261             :     std::vector<std::unique_ptr<OGRLayerWithTranslateFeature>>
     262             :         m_layersToDestroy{};
     263             :     std::vector<OGRLayerWithTranslateFeature *> m_layers{};
     264             : 
     265             :     OGRLayerWithTranslateFeature *m_belongingLayer = nullptr;
     266             :     std::vector<std::unique_ptr<OGRFeature>> m_pendingFeatures{};
     267             :     size_t m_idxInPendingFeatures = 0;
     268             : 
     269             :     CPL_DISALLOW_COPY_ASSIGN(GDALVectorPipelineOutputDataset)
     270             : 
     271             :   public:
     272             :     explicit GDALVectorPipelineOutputDataset(GDALDataset &oSrcDS);
     273             : 
     274             :     void AddLayer(OGRLayer &oSrcLayer,
     275             :                   std::unique_ptr<OGRLayerWithTranslateFeature> poNewLayer);
     276             : 
     277             :     int GetLayerCount() const override;
     278             : 
     279             :     OGRLayer *GetLayer(int idx) const override;
     280             : 
     281             :     int TestCapability(const char *pszCap) const override;
     282             : 
     283             :     void ResetReading() override;
     284             : 
     285             :     OGRFeature *GetNextFeature(OGRLayer **ppoBelongingLayer,
     286             :                                double *pdfProgressPct,
     287             :                                GDALProgressFunc pfnProgress,
     288             :                                void *pProgressData) override;
     289             : };
     290             : 
     291             : //! @endcond
     292             : 
     293             : #endif

Generated by: LCOV version 1.14