LCOV - code coverage report
Current view: top level - apps - gdalalg_vector_pipeline.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 319 321 99.4 %
Date: 2026-03-24 21:18:54 Functions: 34 35 97.1 %

          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             : #include "gdalalg_vector_pipeline.h"
      14             : #include "gdalalg_external.h"
      15             : #include "gdalalg_materialize.h"
      16             : #include "gdalalg_vector_read.h"
      17             : #include "gdalalg_vector_buffer.h"
      18             : #include "gdalalg_vector_check_coverage.h"
      19             : #include "gdalalg_vector_check_geometry.h"
      20             : #include "gdalalg_vector_clean_coverage.h"
      21             : #include "gdalalg_vector_clip.h"
      22             : #include "gdalalg_vector_combine.h"
      23             : #include "gdalalg_vector_concat.h"
      24             : #include "gdalalg_vector_concave_hull.h"
      25             : #include "gdalalg_vector_convex_hull.h"
      26             : #include "gdalalg_vector_dissolve.h"
      27             : #include "gdalalg_vector_edit.h"
      28             : #include "gdalalg_vector_explode_collections.h"
      29             : #include "gdalalg_vector_export_schema.h"
      30             : #include "gdalalg_vector_filter.h"
      31             : #include "gdalalg_vector_info.h"
      32             : #include "gdalalg_vector_limit.h"
      33             : #include "gdalalg_vector_make_point.h"
      34             : #include "gdalalg_vector_make_valid.h"
      35             : #include "gdalalg_vector_partition.h"
      36             : #include "gdalalg_vector_rename_layer.h"
      37             : #include "gdalalg_vector_reproject.h"
      38             : #include "gdalalg_vector_segmentize.h"
      39             : #include "gdalalg_vector_select.h"
      40             : #include "gdalalg_vector_set_field_type.h"
      41             : #include "gdalalg_vector_set_geom_type.h"
      42             : #include "gdalalg_vector_simplify.h"
      43             : #include "gdalalg_vector_simplify_coverage.h"
      44             : #include "gdalalg_vector_sort.h"
      45             : #include "gdalalg_vector_sql.h"
      46             : #include "gdalalg_vector_swap_xy.h"
      47             : #include "gdalalg_vector_update.h"
      48             : #include "gdalalg_vector_write.h"
      49             : #include "gdalalg_tee.h"
      50             : 
      51             : #include "../frmts/mem/memdataset.h"
      52             : 
      53             : #include "cpl_conv.h"
      54             : #include "cpl_string.h"
      55             : 
      56             : #include <algorithm>
      57             : #include <cassert>
      58             : 
      59             : //! @cond Doxygen_Suppress
      60             : 
      61             : #ifndef _
      62             : #define _(x) (x)
      63             : #endif
      64             : 
      65             : GDALVectorAlgorithmStepRegistry::~GDALVectorAlgorithmStepRegistry() = default;
      66             : 
      67             : /************************************************************************/
      68             : /*  GDALVectorPipelineStepAlgorithm::GDALVectorPipelineStepAlgorithm()  */
      69             : /************************************************************************/
      70             : 
      71        1977 : GDALVectorPipelineStepAlgorithm::GDALVectorPipelineStepAlgorithm(
      72             :     const std::string &name, const std::string &description,
      73        1977 :     const std::string &helpURL, bool standaloneStep)
      74             :     : GDALVectorPipelineStepAlgorithm(
      75             :           name, description, helpURL,
      76        1977 :           ConstructorOptions().SetStandaloneStep(standaloneStep))
      77             : {
      78        1977 : }
      79             : 
      80             : /************************************************************************/
      81             : /*  GDALVectorPipelineStepAlgorithm::GDALVectorPipelineStepAlgorithm()  */
      82             : /************************************************************************/
      83             : 
      84        4480 : GDALVectorPipelineStepAlgorithm::GDALVectorPipelineStepAlgorithm(
      85             :     const std::string &name, const std::string &description,
      86        4480 :     const std::string &helpURL, const ConstructorOptions &options)
      87        4480 :     : GDALPipelineStepAlgorithm(name, description, helpURL, options)
      88             : {
      89        4480 :     if (m_standaloneStep)
      90             :     {
      91        1933 :         m_supportsStreamedOutput = true;
      92             : 
      93        1933 :         if (m_constructorOptions.addDefaultArguments)
      94             :         {
      95        1595 :             AddVectorInputArgs(false);
      96        1595 :             AddProgressArg();
      97        1595 :             AddVectorOutputArgs(false, false);
      98             :         }
      99             :     }
     100             :     else
     101             :     {
     102        2547 :         if (m_constructorOptions.addDefaultArguments)
     103             :         {
     104        1709 :             AddVectorHiddenInputDatasetArg();
     105             :         }
     106             :     }
     107        4480 : }
     108             : 
     109             : GDALVectorPipelineStepAlgorithm::~GDALVectorPipelineStepAlgorithm() = default;
     110             : 
     111             : /************************************************************************/
     112             : /*      GDALVectorPipelineAlgorithm::GDALVectorPipelineAlgorithm()      */
     113             : /************************************************************************/
     114             : 
     115         145 : GDALVectorPipelineAlgorithm::GDALVectorPipelineAlgorithm()
     116             :     : GDALAbstractPipelineAlgorithm(
     117             :           NAME, DESCRIPTION, HELP_URL,
     118         145 :           ConstructorOptions().SetInputDatasetMaxCount(INT_MAX))
     119             : {
     120         145 :     m_supportsStreamedOutput = true;
     121             : 
     122         145 :     AddVectorInputArgs(/* hiddenForCLI = */ true);
     123         145 :     AddProgressArg();
     124         290 :     AddArg("pipeline", 0, _("Pipeline string"), &m_pipeline)
     125         145 :         .SetHiddenForCLI()
     126         145 :         .SetPositional();
     127         145 :     AddVectorOutputArgs(/* hiddenForCLI = */ true,
     128             :                         /* shortNameOutputLayerAllowed=*/false);
     129             : 
     130         145 :     AddOutputStringArg(&m_output).SetHiddenForCLI();
     131         145 :     AddStdoutArg(&m_stdout);
     132             : 
     133         145 :     RegisterAlgorithms(m_stepRegistry, false);
     134         145 : }
     135             : 
     136             : /************************************************************************/
     137             : /*          GDALVectorPipelineAlgorithm::RegisterAlgorithms()           */
     138             : /************************************************************************/
     139             : 
     140             : /* static */
     141         410 : void GDALVectorPipelineAlgorithm::RegisterAlgorithms(
     142             :     GDALVectorAlgorithmStepRegistry &registry, bool forMixedPipeline)
     143             : {
     144         820 :     GDALAlgorithmRegistry::AlgInfo algInfo;
     145             : 
     146             :     const auto addSuffixIfNeeded =
     147        4100 :         [forMixedPipeline](const char *name) -> std::string
     148             :     {
     149        6750 :         return forMixedPipeline ? std::string(name).append(VECTOR_SUFFIX)
     150       10850 :                                 : std::string(name);
     151         410 :     };
     152             : 
     153         410 :     registry.Register<GDALVectorReadAlgorithm>(
     154         820 :         addSuffixIfNeeded(GDALVectorReadAlgorithm::NAME));
     155             : 
     156         410 :     registry.Register<GDALVectorWriteAlgorithm>(
     157         820 :         addSuffixIfNeeded(GDALVectorWriteAlgorithm::NAME));
     158             : 
     159         410 :     registry.Register<GDALVectorInfoAlgorithm>(
     160         820 :         addSuffixIfNeeded(GDALVectorInfoAlgorithm::NAME));
     161             : 
     162         410 :     registry.Register<GDALVectorBufferAlgorithm>();
     163         410 :     registry.Register<GDALVectorCheckCoverageAlgorithm>();
     164         410 :     registry.Register<GDALVectorCheckGeometryAlgorithm>();
     165         410 :     registry.Register<GDALVectorCombineAlgorithm>();
     166         410 :     registry.Register<GDALVectorConcatAlgorithm>();
     167         410 :     registry.Register<GDALVectorConcaveHullAlgorithm>();
     168         410 :     registry.Register<GDALVectorConvexHullAlgorithm>();
     169         410 :     registry.Register<GDALVectorCleanCoverageAlgorithm>();
     170             : 
     171         410 :     registry.Register<GDALVectorClipAlgorithm>(
     172         820 :         addSuffixIfNeeded(GDALVectorClipAlgorithm::NAME));
     173         410 :     registry.Register<GDALVectorDissolveAlgorithm>();
     174             : 
     175         410 :     registry.Register<GDALVectorEditAlgorithm>(
     176         820 :         addSuffixIfNeeded(GDALVectorEditAlgorithm::NAME));
     177             : 
     178         410 :     registry.Register<GDALVectorExplodeCollectionsAlgorithm>();
     179         410 :     registry.Register<GDALVectorExportSchemaAlgorithm>();
     180             : 
     181         410 :     registry.Register<GDALMaterializeVectorAlgorithm>(
     182         820 :         addSuffixIfNeeded(GDALMaterializeVectorAlgorithm::NAME));
     183             : 
     184         410 :     registry.Register<GDALVectorReprojectAlgorithm>(
     185         820 :         addSuffixIfNeeded(GDALVectorReprojectAlgorithm::NAME));
     186             : 
     187         410 :     registry.Register<GDALVectorFilterAlgorithm>();
     188         410 :     registry.Register<GDALVectorLimitAlgorithm>();
     189         410 :     registry.Register<GDALVectorMakePointAlgorithm>();
     190         410 :     registry.Register<GDALVectorMakeValidAlgorithm>();
     191         410 :     registry.Register<GDALVectorPartitionAlgorithm>();
     192         410 :     registry.Register<GDALVectorRenameLayerAlgorithm>();
     193         410 :     registry.Register<GDALVectorSegmentizeAlgorithm>();
     194             : 
     195         410 :     registry.Register<GDALVectorSelectAlgorithm>(
     196         820 :         addSuffixIfNeeded(GDALVectorSelectAlgorithm::NAME));
     197             : 
     198         410 :     registry.Register<GDALVectorSetFieldTypeAlgorithm>();
     199         410 :     registry.Register<GDALVectorSetGeomTypeAlgorithm>();
     200         410 :     registry.Register<GDALVectorSimplifyAlgorithm>();
     201         410 :     registry.Register<GDALVectorSimplifyCoverageAlgorithm>();
     202         410 :     registry.Register<GDALVectorSortAlgorithm>();
     203         410 :     registry.Register<GDALVectorSQLAlgorithm>();
     204         410 :     registry.Register<GDALVectorUpdateAlgorithm>(
     205         820 :         addSuffixIfNeeded(GDALVectorUpdateAlgorithm::NAME));
     206         410 :     registry.Register<GDALVectorSwapXYAlgorithm>();
     207             : 
     208         410 :     registry.Register<GDALTeeVectorAlgorithm>(
     209         820 :         addSuffixIfNeeded(GDALTeeVectorAlgorithm::NAME));
     210             : 
     211         410 :     if (!forMixedPipeline)
     212             :     {
     213         145 :         registry.Register<GDALExternalVectorAlgorithm>();
     214             :     }
     215         410 : }
     216             : 
     217             : /************************************************************************/
     218             : /*            GDALVectorPipelineAlgorithm::GetUsageForCLI()             */
     219             : /************************************************************************/
     220             : 
     221           8 : std::string GDALVectorPipelineAlgorithm::GetUsageForCLI(
     222             :     bool shortUsage, const UsageOptions &usageOptions) const
     223             : {
     224           8 :     UsageOptions stepUsageOptions;
     225           8 :     stepUsageOptions.isPipelineStep = true;
     226             : 
     227           8 :     if (!m_helpDocCategory.empty() && m_helpDocCategory != "main")
     228             :     {
     229           4 :         auto alg = GetStepAlg(m_helpDocCategory);
     230           2 :         if (alg)
     231             :         {
     232           2 :             alg->SetCallPath({m_helpDocCategory});
     233           1 :             alg->GetArg("help-doc")->Set(true);
     234           1 :             return alg->GetUsageForCLI(shortUsage, stepUsageOptions);
     235             :         }
     236             :         else
     237             :         {
     238           1 :             fprintf(stderr, "ERROR: unknown pipeline step '%s'\n",
     239             :                     m_helpDocCategory.c_str());
     240             :             return CPLSPrintf("ERROR: unknown pipeline step '%s'\n",
     241           1 :                               m_helpDocCategory.c_str());
     242             :         }
     243             :     }
     244             : 
     245           6 :     UsageOptions usageOptionsMain(usageOptions);
     246           6 :     usageOptionsMain.isPipelineMain = true;
     247             :     std::string ret =
     248          12 :         GDALAlgorithm::GetUsageForCLI(shortUsage, usageOptionsMain);
     249           6 :     if (shortUsage)
     250           2 :         return ret;
     251             : 
     252             :     ret += "\n<PIPELINE> is of the form: read|concat [READ-OPTIONS] "
     253           4 :            "( ! <STEP-NAME> [STEP-OPTIONS] )* ! write|info [WRITE-OPTIONS]\n";
     254             : 
     255           4 :     if (m_helpDocCategory == "main")
     256             :     {
     257           1 :         return ret;
     258             :     }
     259             : 
     260           3 :     ret += '\n';
     261           3 :     ret += "Example: 'gdal vector pipeline --progress ! read in.gpkg ! \\\n";
     262           3 :     ret += "               reproject --dst-crs=EPSG:32632 ! ";
     263           3 :     ret += "write out.gpkg --overwrite'\n";
     264           3 :     ret += '\n';
     265           3 :     ret += "Potential steps are:\n";
     266             : 
     267         111 :     for (const std::string &name : m_stepRegistry.GetNames())
     268             :     {
     269         216 :         auto alg = GetStepAlg(name);
     270         108 :         assert(alg);
     271         108 :         auto [options, maxOptLen] = alg->GetArgNamesForCLI();
     272         108 :         stepUsageOptions.maxOptLen =
     273         108 :             std::max(stepUsageOptions.maxOptLen, maxOptLen);
     274             :     }
     275             : 
     276             :     {
     277           3 :         const auto name = GDALVectorReadAlgorithm::NAME;
     278           3 :         ret += '\n';
     279           6 :         auto alg = GetStepAlg(name);
     280           6 :         alg->SetCallPath({name});
     281           3 :         ret += alg->GetUsageForCLI(shortUsage, stepUsageOptions);
     282             :     }
     283         111 :     for (const std::string &name : m_stepRegistry.GetNames())
     284             :     {
     285         216 :         auto alg = GetStepAlg(name);
     286         108 :         assert(alg);
     287         117 :         if (alg->CanBeFirstStep() && !alg->CanBeMiddleStep() &&
     288         117 :             !alg->IsHidden() && name != GDALVectorReadAlgorithm::NAME)
     289             :         {
     290           3 :             ret += '\n';
     291           6 :             alg->SetCallPath({name});
     292           3 :             ret += alg->GetUsageForCLI(shortUsage, stepUsageOptions);
     293             :         }
     294             :     }
     295         111 :     for (const std::string &name : m_stepRegistry.GetNames())
     296             :     {
     297         216 :         auto alg = GetStepAlg(name);
     298         108 :         assert(alg);
     299         108 :         if (alg->CanBeMiddleStep() && !alg->IsHidden())
     300             :         {
     301          90 :             ret += '\n';
     302         180 :             alg->SetCallPath({name});
     303          90 :             ret += alg->GetUsageForCLI(shortUsage, stepUsageOptions);
     304             :         }
     305             :     }
     306         111 :     for (const std::string &name : m_stepRegistry.GetNames())
     307             :     {
     308         216 :         auto alg = GetStepAlg(name);
     309         108 :         assert(alg);
     310         126 :         if (alg->CanBeLastStep() && !alg->CanBeMiddleStep() &&
     311         126 :             !alg->IsHidden() && name != GDALVectorWriteAlgorithm::NAME)
     312             :         {
     313           9 :             ret += '\n';
     314          18 :             alg->SetCallPath({name});
     315           9 :             ret += alg->GetUsageForCLI(shortUsage, stepUsageOptions);
     316             :         }
     317             :     }
     318             :     {
     319           3 :         const auto name = GDALVectorWriteAlgorithm::NAME;
     320           3 :         ret += '\n';
     321           6 :         auto alg = GetStepAlg(name);
     322           6 :         alg->SetCallPath({name});
     323           3 :         ret += alg->GetUsageForCLI(shortUsage, stepUsageOptions);
     324             :     }
     325             : 
     326           3 :     ret += GetUsageForCLIEnd();
     327             : 
     328           3 :     return ret;
     329             : }
     330             : 
     331             : /************************************************************************/
     332             : /*                      GDALVectorDecoratedDataset                      */
     333             : /************************************************************************/
     334             : 
     335             : namespace
     336             : {
     337             : class DummyDataset final : public GDALDataset
     338             : {
     339             :   public:
     340          15 :     DummyDataset() = default;
     341             : };
     342             : }  // namespace
     343             : 
     344             : /************************************************************************/
     345             : /*                     GDALVectorDecoratedDataset()                     */
     346             : /************************************************************************/
     347             : 
     348         311 : GDALVectorDecoratedDataset::GDALVectorDecoratedDataset(GDALDataset *poSrcDS)
     349         622 :     : m_dummySrcDS(poSrcDS ? nullptr : std::make_unique<DummyDataset>()),
     350         933 :       m_srcDS(poSrcDS ? *poSrcDS : *(m_dummySrcDS.get()))
     351             : {
     352         311 :     SetDescription(m_srcDS.GetDescription());
     353         311 : }
     354             : 
     355             : /************************************************************************/
     356             : /*                    ~GDALVectorDecoratedDataset()                     */
     357             : /************************************************************************/
     358             : 
     359             : GDALVectorDecoratedDataset::~GDALVectorDecoratedDataset() = default;
     360             : 
     361             : /************************************************************************/
     362             : /*                    GDALVectorPipelineOutputLayer                     */
     363             : /************************************************************************/
     364             : 
     365             : /************************************************************************/
     366             : /*                   GDALVectorPipelineOutputLayer()                    */
     367             : /************************************************************************/
     368             : 
     369         249 : GDALVectorPipelineOutputLayer::GDALVectorPipelineOutputLayer(OGRLayer &srcLayer)
     370         249 :     : m_srcLayer(srcLayer)
     371             : {
     372         249 : }
     373             : 
     374             : /************************************************************************/
     375             : /*                   ~GDALVectorPipelineOutputLayer()                   */
     376             : /************************************************************************/
     377             : 
     378             : GDALVectorPipelineOutputLayer::~GDALVectorPipelineOutputLayer() = default;
     379             : 
     380             : /************************************************************************/
     381             : /*            GDALVectorPipelineOutputLayer::ResetReading()             */
     382             : /************************************************************************/
     383             : 
     384         796 : void GDALVectorPipelineOutputLayer::ResetReading()
     385             : {
     386         796 :     m_srcLayer.ResetReading();
     387         796 :     m_pendingFeatures.clear();
     388         796 :     m_idxInPendingFeatures = 0;
     389         796 : }
     390             : 
     391             : /************************************************************************/
     392             : /*          GDALVectorPipelineOutputLayer::GetNextRawFeature()          */
     393             : /************************************************************************/
     394             : 
     395        3019 : OGRFeature *GDALVectorPipelineOutputLayer::GetNextRawFeature()
     396             : {
     397        3019 :     if (m_idxInPendingFeatures < m_pendingFeatures.size())
     398             :     {
     399             :         OGRFeature *poFeature =
     400          14 :             m_pendingFeatures[m_idxInPendingFeatures].release();
     401          14 :         ++m_idxInPendingFeatures;
     402          14 :         return poFeature;
     403             :     }
     404        3005 :     m_pendingFeatures.clear();
     405        3005 :     m_idxInPendingFeatures = 0;
     406             :     while (true)
     407             :     {
     408             :         auto poSrcFeature =
     409        3152 :             std::unique_ptr<OGRFeature>(m_srcLayer.GetNextFeature());
     410        3152 :         if (!poSrcFeature)
     411         397 :             return nullptr;
     412        2755 :         TranslateFeature(std::move(poSrcFeature), m_pendingFeatures);
     413        2755 :         if (m_translateError)
     414             :         {
     415           7 :             return nullptr;
     416             :         }
     417        2748 :         if (!m_pendingFeatures.empty())
     418        2601 :             break;
     419         147 :     }
     420        2601 :     OGRFeature *poFeature = m_pendingFeatures[0].release();
     421        2601 :     m_idxInPendingFeatures = 1;
     422        2601 :     return poFeature;
     423             : }
     424             : 
     425             : /************************************************************************/
     426             : /*                       GDALVectorOutputDataset                        */
     427             : /************************************************************************/
     428             : 
     429             : /************************************************************************/
     430             : /*                      GDALVectorOutputDataset()                       */
     431             : /************************************************************************/
     432             : 
     433          17 : GDALVectorOutputDataset::GDALVectorOutputDataset(GDALDataset *poSrcDS)
     434          17 :     : GDALVectorDecoratedDataset(poSrcDS)
     435             : {
     436          17 : }
     437             : 
     438             : /************************************************************************/
     439             : /*                           TestCapability()                           */
     440             : /************************************************************************/
     441             : 
     442          14 : int GDALVectorOutputDataset::TestCapability(const char *) const
     443             : {
     444          14 :     return 0;
     445             : }
     446             : 
     447             : /************************************************************************/
     448             : /*                   GDALVectorPipelineOutputDataset                    */
     449             : /************************************************************************/
     450             : 
     451             : /************************************************************************/
     452             : /*                  GDALVectorPipelineOutputDataset()                   */
     453             : /************************************************************************/
     454             : 
     455         220 : GDALVectorPipelineOutputDataset::GDALVectorPipelineOutputDataset(
     456         220 :     GDALDataset &srcDS)
     457         220 :     : GDALVectorDecoratedDataset(&srcDS)
     458             : {
     459         220 : }
     460             : 
     461             : /************************************************************************/
     462             : /*             GDALVectorPipelineOutputDataset::AddLayer()              */
     463             : /************************************************************************/
     464             : 
     465         253 : void GDALVectorPipelineOutputDataset::AddLayer(
     466             :     OGRLayer &oSrcLayer,
     467             :     std::unique_ptr<OGRLayerWithTranslateFeature> poNewLayer)
     468             : {
     469         253 :     m_layersToDestroy.push_back(std::move(poNewLayer));
     470             :     OGRLayerWithTranslateFeature *poNewLayerRaw =
     471         253 :         m_layersToDestroy.back().get();
     472         253 :     m_layers.push_back(poNewLayerRaw);
     473         253 :     m_mapSrcLayerToNewLayer[&oSrcLayer] = poNewLayerRaw;
     474         253 : }
     475             : 
     476             : /************************************************************************/
     477             : /*           GDALVectorPipelineOutputDataset::GetLayerCount()           */
     478             : /************************************************************************/
     479             : 
     480         814 : int GDALVectorPipelineOutputDataset::GetLayerCount() const
     481             : {
     482         814 :     return static_cast<int>(m_layers.size());
     483             : }
     484             : 
     485             : /************************************************************************/
     486             : /*             GDALVectorPipelineOutputDataset::GetLayer()              */
     487             : /************************************************************************/
     488             : 
     489         337 : OGRLayer *GDALVectorPipelineOutputDataset::GetLayer(int idx) const
     490             : {
     491         337 :     return idx >= 0 && idx < GetLayerCount() ? m_layers[idx] : nullptr;
     492             : }
     493             : 
     494             : /************************************************************************/
     495             : /*          GDALVectorPipelineOutputDataset::TestCapability()           */
     496             : /************************************************************************/
     497             : 
     498         149 : int GDALVectorPipelineOutputDataset::TestCapability(const char *pszCap) const
     499             : {
     500         149 :     if (EQUAL(pszCap, ODsCRandomLayerRead) ||
     501          39 :         EQUAL(pszCap, ODsCMeasuredGeometries) || EQUAL(pszCap, ODsCZGeometries))
     502             :     {
     503         129 :         return m_srcDS.TestCapability(pszCap);
     504             :     }
     505          20 :     return false;
     506             : }
     507             : 
     508             : /************************************************************************/
     509             : /*           GDALVectorPipelineOutputDataset::ResetReading()            */
     510             : /************************************************************************/
     511             : 
     512           3 : void GDALVectorPipelineOutputDataset::ResetReading()
     513             : {
     514           3 :     m_srcDS.ResetReading();
     515           3 :     m_pendingFeatures.clear();
     516           3 :     m_idxInPendingFeatures = 0;
     517           3 : }
     518             : 
     519             : /************************************************************************/
     520             : /*          GDALVectorPipelineOutputDataset::GetNextFeature()           */
     521             : /************************************************************************/
     522             : 
     523          23 : OGRFeature *GDALVectorPipelineOutputDataset::GetNextFeature(
     524             :     OGRLayer **ppoBelongingLayer, double *pdfProgressPct,
     525             :     GDALProgressFunc pfnProgress, void *pProgressData)
     526             : {
     527          23 :     if (m_idxInPendingFeatures < m_pendingFeatures.size())
     528             :     {
     529             :         OGRFeature *poFeature =
     530           3 :             m_pendingFeatures[m_idxInPendingFeatures].release();
     531           3 :         if (ppoBelongingLayer)
     532           3 :             *ppoBelongingLayer = m_belongingLayer;
     533           3 :         ++m_idxInPendingFeatures;
     534           3 :         return poFeature;
     535             :     }
     536             : 
     537          20 :     m_pendingFeatures.clear();
     538          20 :     m_idxInPendingFeatures = 0;
     539             : 
     540             :     while (true)
     541             :     {
     542          20 :         OGRLayer *poSrcBelongingLayer = nullptr;
     543          20 :         auto poSrcFeature = std::unique_ptr<OGRFeature>(m_srcDS.GetNextFeature(
     544          20 :             &poSrcBelongingLayer, pdfProgressPct, pfnProgress, pProgressData));
     545          20 :         if (!poSrcFeature)
     546           3 :             return nullptr;
     547          17 :         auto iterToDstLayer = m_mapSrcLayerToNewLayer.find(poSrcBelongingLayer);
     548          17 :         if (iterToDstLayer != m_mapSrcLayerToNewLayer.end())
     549             :         {
     550          17 :             m_belongingLayer = iterToDstLayer->second;
     551          17 :             m_belongingLayer->TranslateFeature(std::move(poSrcFeature),
     552          17 :                                                m_pendingFeatures);
     553             : 
     554          17 :             if (!m_pendingFeatures.empty())
     555          17 :                 break;
     556             :         }
     557           0 :     }
     558          17 :     OGRFeature *poFeature = m_pendingFeatures[0].release();
     559          17 :     if (ppoBelongingLayer)
     560          17 :         *ppoBelongingLayer = m_belongingLayer;
     561          17 :     m_idxInPendingFeatures = 1;
     562          17 :     return poFeature;
     563             : }
     564             : 
     565             : /************************************************************************/
     566             : /*          GDALVectorPipelinePassthroughLayer::GetLayerDefn()          */
     567             : /************************************************************************/
     568             : 
     569          44 : const OGRFeatureDefn *GDALVectorPipelinePassthroughLayer::GetLayerDefn() const
     570             : {
     571          44 :     return m_srcLayer.GetLayerDefn();
     572             : }
     573             : 
     574             : /************************************************************************/
     575             : /*               GDALVectorNonStreamingAlgorithmDataset()               */
     576             : /************************************************************************/
     577             : 
     578          74 : GDALVectorNonStreamingAlgorithmDataset::GDALVectorNonStreamingAlgorithmDataset(
     579          74 :     GDALDataset &oSrcDS)
     580          74 :     : GDALVectorDecoratedDataset(&oSrcDS)
     581             : {
     582          74 : }
     583             : 
     584             : /************************************************************************/
     585             : /*              ~GDALVectorNonStreamingAlgorithmDataset()               */
     586             : /************************************************************************/
     587             : 
     588             : GDALVectorNonStreamingAlgorithmDataset::
     589             :     ~GDALVectorNonStreamingAlgorithmDataset() = default;
     590             : 
     591             : /************************************************************************/
     592             : /*     GDALVectorNonStreamingAlgorithmDataset::AddProcessedLayer()      */
     593             : /************************************************************************/
     594             : 
     595          67 : bool GDALVectorNonStreamingAlgorithmDataset::AddProcessedLayer(
     596             :     std::unique_ptr<GDALVectorNonStreamingAlgorithmLayer> layer,
     597             :     GDALProgressFunc progressFn, void *progressData)
     598             : {
     599          67 :     if (!layer->Process(progressFn, progressData))
     600             :     {
     601           6 :         return false;
     602             :     }
     603             : 
     604          61 :     m_owned_layers.emplace_back(std::move(layer));
     605          61 :     m_layers.push_back(m_owned_layers.back().get());
     606             : 
     607          61 :     return true;
     608             : }
     609             : 
     610             : /************************************************************************/
     611             : /*    GDALVectorNonStreamingAlgorithmDataset::AddPassThroughLayer()     */
     612             : /************************************************************************/
     613             : 
     614           6 : void GDALVectorNonStreamingAlgorithmDataset::AddPassThroughLayer(
     615             :     OGRLayer &oLayer)
     616             : {
     617           6 :     m_owned_layers.push_back(
     618          12 :         std::make_unique<GDALVectorPipelinePassthroughLayer>(oLayer));
     619           6 :     m_layers.push_back(m_owned_layers.back().get());
     620           6 : }
     621             : 
     622             : /************************************************************************/
     623             : /*       GDALVectorNonStreamingAlgorithmDataset::GetLayerCount()        */
     624             : /************************************************************************/
     625             : 
     626         188 : int GDALVectorNonStreamingAlgorithmDataset::GetLayerCount() const
     627             : {
     628         188 :     return static_cast<int>(m_layers.size());
     629             : }
     630             : 
     631             : /************************************************************************/
     632             : /*          GDALVectorNonStreamingAlgorithmDataset::GetLayer()          */
     633             : /************************************************************************/
     634             : 
     635         142 : OGRLayer *GDALVectorNonStreamingAlgorithmDataset::GetLayer(int idx) const
     636             : {
     637         142 :     if (idx < 0 || idx >= static_cast<int>(m_layers.size()))
     638             :     {
     639           6 :         return nullptr;
     640             :     }
     641         136 :     return m_layers[idx];
     642             : }
     643             : 
     644             : /************************************************************************/
     645             : /*       GDALVectorNonStreamingAlgorithmDataset::TestCapability()       */
     646             : /************************************************************************/
     647             : 
     648          23 : int GDALVectorNonStreamingAlgorithmDataset::TestCapability(
     649             :     const char *pszCap) const
     650             : {
     651          23 :     if (EQUAL(pszCap, ODsCCurveGeometries) ||
     652          20 :         EQUAL(pszCap, ODsCMeasuredGeometries) || EQUAL(pszCap, ODsCZGeometries))
     653             :     {
     654          11 :         return true;
     655             :     }
     656             : 
     657          12 :     return false;
     658             : }
     659             : 
     660             : /************************************************************************/
     661             : /*               GDALVectorAlgorithmLayerProgressHelper()               */
     662             : /************************************************************************/
     663             : 
     664          74 : GDALVectorAlgorithmLayerProgressHelper::GDALVectorAlgorithmLayerProgressHelper(
     665          74 :     GDALProgressFunc pfnProgress, void *pProgressData)
     666          74 :     : m_pfnProgress(pfnProgress), m_pProgressData(pProgressData)
     667             : {
     668          74 : }
     669             : 
     670             : /************************************************************************/
     671             : /*               GDALVectorAlgorithmLayerProgressHelper()               */
     672             : /************************************************************************/
     673             : 
     674          74 : GDALVectorAlgorithmLayerProgressHelper::GDALVectorAlgorithmLayerProgressHelper(
     675          74 :     const GDALPipelineStepRunContext &ctxt)
     676          74 :     : GDALVectorAlgorithmLayerProgressHelper(ctxt.m_pfnProgress,
     677          74 :                                              ctxt.m_pProgressData)
     678             : {
     679          74 : }
     680             : 
     681             : /************************************************************************/
     682             : /*     GDALVectorAlgorithmLayerProgressHelper::AddProcessedLayer()      */
     683             : /************************************************************************/
     684             : 
     685          70 : void GDALVectorAlgorithmLayerProgressHelper::AddProcessedLayer(
     686             :     OGRLayer &srcLayer)
     687             : {
     688          70 :     m_apoSrcLayers.emplace_back(&srcLayer, true);
     689          78 :     if (m_pfnProgress && m_nTotalFeatures >= 0 &&
     690           8 :         srcLayer.TestCapability(OLCFastFeatureCount))
     691             :     {
     692           8 :         const auto nLayerFeatures = srcLayer.GetFeatureCount(false);
     693           8 :         if (nLayerFeatures < 0)
     694           0 :             m_nTotalFeatures = -1;
     695             :         else
     696           8 :             m_nTotalFeatures += nLayerFeatures;
     697           8 :         m_anFeatures.push_back(nLayerFeatures);
     698             :     }
     699             :     else
     700             :     {
     701          62 :         m_anFeatures.push_back(-1);
     702          62 :         m_nTotalFeatures = -1;
     703             :     }
     704          70 : }
     705             : 
     706             : /************************************************************************/
     707             : /*    GDALVectorAlgorithmLayerProgressHelper::AddPassThroughLayer()     */
     708             : /************************************************************************/
     709             : 
     710          10 : void GDALVectorAlgorithmLayerProgressHelper::AddPassThroughLayer(
     711             :     OGRLayer &srcLayer)
     712             : {
     713          10 :     m_apoSrcLayers.emplace_back(&srcLayer, false);
     714          10 : }
     715             : 
     716             : /************************************************************************/
     717             : /*                GDALVectorNonStreamingAlgorithmLayer()                */
     718             : /************************************************************************/
     719             : 
     720          67 : GDALVectorNonStreamingAlgorithmLayer::GDALVectorNonStreamingAlgorithmLayer(
     721          67 :     OGRLayer &srcLayer, int geomFieldIndex)
     722          67 :     : m_srcLayer(srcLayer), m_geomFieldIndex(geomFieldIndex)
     723             : {
     724          67 : }
     725             : 
     726             : /************************************************************************/
     727             : /*               ~GDALVectorNonStreamingAlgorithmLayer()                */
     728             : /************************************************************************/
     729             : 
     730             : GDALVectorNonStreamingAlgorithmLayer::~GDALVectorNonStreamingAlgorithmLayer() =
     731             :     default;
     732             : 
     733             : /************************************************************************/
     734             : /*      GDALVectorNonStreamingAlgorithmLayer::GetNextRawFeature()       */
     735             : /************************************************************************/
     736             : 
     737        2123 : OGRFeature *GDALVectorNonStreamingAlgorithmLayer::GetNextRawFeature()
     738             : {
     739        2123 :     return GetNextProcessedFeature().release();
     740             : }
     741             : 
     742             : /************************************************************************/
     743             : /*    GDALVectorAlgorithmLayerProgressHelper::iterator::operator*()     */
     744             : /************************************************************************/
     745             : 
     746             : GDALVectorAlgorithmLayerProgressHelper::iterator::value_type
     747          76 : GDALVectorAlgorithmLayerProgressHelper::iterator::operator*() const
     748             : {
     749             :     const double dfProgressStart =
     750         148 :         m_helper.m_anFeatures.empty() ? 0
     751          72 :         : m_helper.m_nTotalFeatures > 0
     752          72 :             ? static_cast<double>(m_nFeatureIdx) /
     753           8 :                   static_cast<double>(m_helper.m_nTotalFeatures)
     754          64 :             : static_cast<double>(m_nProcessedLayerIdx) /
     755          64 :                   std::max(1.0,
     756          64 :                            static_cast<double>(m_helper.m_anFeatures.size()));
     757             :     const double dfProgressEnd =
     758         148 :         m_helper.m_anFeatures.empty() ? 0
     759          72 :         : m_helper.m_nTotalFeatures > 0
     760          72 :             ? static_cast<double>(m_nFeatureIdx +
     761           8 :                                   m_helper.m_anFeatures[m_nProcessedLayerIdx]) /
     762           8 :                   static_cast<double>(m_helper.m_nTotalFeatures)
     763          64 :             : static_cast<double>(m_nProcessedLayerIdx + 1) /
     764          64 :                   std::max(1.0,
     765          64 :                            static_cast<double>(m_helper.m_anFeatures.size()));
     766             : 
     767             :     progress_data_unique_ptr pScaledProgressData(nullptr,
     768          76 :                                                  GDALDestroyScaledProgress);
     769          76 :     if (m_helper.m_pfnProgress && m_helper.m_apoSrcLayers[m_nLayerIdx].second)
     770             :     {
     771           8 :         pScaledProgressData.reset(GDALCreateScaledProgress(
     772           8 :             dfProgressStart, dfProgressEnd, m_helper.m_pfnProgress,
     773           8 :             m_helper.m_pProgressData));
     774             :     }
     775             : 
     776         152 :     return value_type(m_helper.m_apoSrcLayers[m_nLayerIdx].first,
     777          76 :                       m_helper.m_apoSrcLayers[m_nLayerIdx].second,
     778         152 :                       m_helper.m_pfnProgress ? GDALScaledProgress : nullptr,
     779         228 :                       std::move(pScaledProgressData));
     780             : }
     781             : 
     782             : //! @endcond

Generated by: LCOV version 1.14