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

Generated by: LCOV version 1.14