LCOV - code coverage report
Current view: top level - apps - gdalalg_vector_pipeline.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 304 306 99.3 %
Date: 2026-02-24 19:16:26 Functions: 31 32 96.9 %

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

Generated by: LCOV version 1.14