LCOV - code coverage report
Current view: top level - apps - gdalalg_vector_pipeline.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 249 250 99.6 %
Date: 2025-10-21 22:35:35 Functions: 25 26 96.2 %

          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_geom.h"
      26             : #include "gdalalg_vector_info.h"
      27             : #include "gdalalg_vector_limit.h"
      28             : #include "gdalalg_vector_make_point.h"
      29             : #include "gdalalg_vector_make_valid.h"
      30             : #include "gdalalg_vector_partition.h"
      31             : #include "gdalalg_vector_reproject.h"
      32             : #include "gdalalg_vector_segmentize.h"
      33             : #include "gdalalg_vector_select.h"
      34             : #include "gdalalg_vector_set_field_type.h"
      35             : #include "gdalalg_vector_set_geom_type.h"
      36             : #include "gdalalg_vector_simplify.h"
      37             : #include "gdalalg_vector_simplify_coverage.h"
      38             : #include "gdalalg_vector_sql.h"
      39             : #include "gdalalg_vector_swap_xy.h"
      40             : #include "gdalalg_vector_write.h"
      41             : #include "gdalalg_tee.h"
      42             : 
      43             : #include "../frmts/mem/memdataset.h"
      44             : 
      45             : #include "cpl_conv.h"
      46             : #include "cpl_string.h"
      47             : 
      48             : #include <algorithm>
      49             : #include <cassert>
      50             : 
      51             : //! @cond Doxygen_Suppress
      52             : 
      53             : #ifndef _
      54             : #define _(x) (x)
      55             : #endif
      56             : 
      57             : GDALVectorAlgorithmStepRegistry::~GDALVectorAlgorithmStepRegistry() = default;
      58             : 
      59             : /************************************************************************/
      60             : /*  GDALVectorPipelineStepAlgorithm::GDALVectorPipelineStepAlgorithm()  */
      61             : /************************************************************************/
      62             : 
      63        1859 : GDALVectorPipelineStepAlgorithm::GDALVectorPipelineStepAlgorithm(
      64             :     const std::string &name, const std::string &description,
      65        1859 :     const std::string &helpURL, bool standaloneStep)
      66             :     : GDALVectorPipelineStepAlgorithm(
      67             :           name, description, helpURL,
      68        1859 :           ConstructorOptions().SetStandaloneStep(standaloneStep))
      69             : {
      70        1859 : }
      71             : 
      72             : /************************************************************************/
      73             : /*  GDALVectorPipelineStepAlgorithm::GDALVectorPipelineStepAlgorithm()  */
      74             : /************************************************************************/
      75             : 
      76        2268 : GDALVectorPipelineStepAlgorithm::GDALVectorPipelineStepAlgorithm(
      77             :     const std::string &name, const std::string &description,
      78        2268 :     const std::string &helpURL, const ConstructorOptions &options)
      79        2268 :     : GDALPipelineStepAlgorithm(name, description, helpURL, options)
      80             : {
      81        2268 :     if (m_standaloneStep)
      82             :     {
      83         437 :         m_supportsStreamedOutput = true;
      84             : 
      85         437 :         if (m_constructorOptions.addDefaultArguments)
      86             :         {
      87         328 :             AddVectorInputArgs(false);
      88         328 :             AddProgressArg();
      89         328 :             AddVectorOutputArgs(false, false);
      90             :         }
      91             :     }
      92        2268 : }
      93             : 
      94             : GDALVectorPipelineStepAlgorithm::~GDALVectorPipelineStepAlgorithm() = default;
      95             : 
      96             : /************************************************************************/
      97             : /*        GDALVectorPipelineAlgorithm::GDALVectorPipelineAlgorithm()    */
      98             : /************************************************************************/
      99             : 
     100          94 : GDALVectorPipelineAlgorithm::GDALVectorPipelineAlgorithm()
     101             :     : GDALAbstractPipelineAlgorithm(
     102             :           NAME, DESCRIPTION, HELP_URL,
     103          94 :           ConstructorOptions().SetInputDatasetMaxCount(INT_MAX))
     104             : {
     105          94 :     m_supportsStreamedOutput = true;
     106             : 
     107          94 :     AddVectorInputArgs(/* hiddenForCLI = */ true);
     108          94 :     AddProgressArg();
     109         188 :     AddArg("pipeline", 0, _("Pipeline string"), &m_pipeline)
     110          94 :         .SetHiddenForCLI()
     111          94 :         .SetPositional();
     112          94 :     AddVectorOutputArgs(/* hiddenForCLI = */ true,
     113             :                         /* shortNameOutputLayerAllowed=*/false);
     114             : 
     115          94 :     AddOutputStringArg(&m_output).SetHiddenForCLI();
     116          94 :     AddStdoutArg(&m_stdout);
     117             : 
     118          94 :     RegisterAlgorithms(m_stepRegistry, false);
     119          94 : }
     120             : 
     121             : /************************************************************************/
     122             : /*       GDALVectorPipelineAlgorithm::RegisterAlgorithms()              */
     123             : /************************************************************************/
     124             : 
     125             : /* static */
     126         285 : void GDALVectorPipelineAlgorithm::RegisterAlgorithms(
     127             :     GDALVectorAlgorithmStepRegistry &registry, bool forMixedPipeline)
     128             : {
     129         285 :     GDALAlgorithmRegistry::AlgInfo algInfo;
     130             : 
     131             :     const auto addSuffixIfNeeded =
     132        2565 :         [forMixedPipeline](const char *name) -> std::string
     133             :     {
     134        4284 :         return forMixedPipeline ? std::string(name).append(VECTOR_SUFFIX)
     135        6849 :                                 : std::string(name);
     136         285 :     };
     137             : 
     138         285 :     registry.Register<GDALVectorReadAlgorithm>(
     139         570 :         addSuffixIfNeeded(GDALVectorReadAlgorithm::NAME));
     140             : 
     141         285 :     registry.Register<GDALVectorWriteAlgorithm>(
     142         570 :         addSuffixIfNeeded(GDALVectorWriteAlgorithm::NAME));
     143             : 
     144         285 :     registry.Register<GDALVectorInfoAlgorithm>(
     145         570 :         addSuffixIfNeeded(GDALVectorInfoAlgorithm::NAME));
     146             : 
     147         285 :     registry.Register<GDALVectorBufferAlgorithm>();
     148         285 :     registry.Register<GDALVectorCheckCoverageAlgorithm>();
     149         285 :     registry.Register<GDALVectorCheckGeometryAlgorithm>();
     150         285 :     registry.Register<GDALVectorConcatAlgorithm>();
     151         285 :     registry.Register<GDALVectorCleanCoverageAlgorithm>();
     152             : 
     153         285 :     registry.Register<GDALVectorClipAlgorithm>(
     154         570 :         addSuffixIfNeeded(GDALVectorClipAlgorithm::NAME));
     155             : 
     156         285 :     registry.Register<GDALVectorEditAlgorithm>(
     157         570 :         addSuffixIfNeeded(GDALVectorEditAlgorithm::NAME));
     158             : 
     159         285 :     registry.Register<GDALVectorExplodeCollectionsAlgorithm>();
     160             : 
     161         285 :     registry.Register<GDALMaterializeVectorAlgorithm>(
     162         570 :         addSuffixIfNeeded(GDALMaterializeVectorAlgorithm::NAME));
     163             : 
     164         285 :     registry.Register<GDALVectorReprojectAlgorithm>(
     165         570 :         addSuffixIfNeeded(GDALVectorReprojectAlgorithm::NAME));
     166             : 
     167         285 :     registry.Register<GDALVectorFilterAlgorithm>();
     168         285 :     registry.Register<GDALVectorGeomAlgorithm>();
     169         285 :     registry.Register<GDALVectorLimitAlgorithm>();
     170         285 :     registry.Register<GDALVectorMakePointAlgorithm>();
     171         285 :     registry.Register<GDALVectorMakeValidAlgorithm>();
     172         285 :     registry.Register<GDALVectorPartitionAlgorithm>();
     173         285 :     registry.Register<GDALVectorSegmentizeAlgorithm>();
     174             : 
     175         285 :     registry.Register<GDALVectorSelectAlgorithm>(
     176         570 :         addSuffixIfNeeded(GDALVectorSelectAlgorithm::NAME));
     177             : 
     178         285 :     registry.Register<GDALVectorSetFieldTypeAlgorithm>();
     179         285 :     registry.Register<GDALVectorSetGeomTypeAlgorithm>();
     180         285 :     registry.Register<GDALVectorSimplifyAlgorithm>();
     181         285 :     registry.Register<GDALVectorSimplifyCoverageAlgorithm>();
     182         285 :     registry.Register<GDALVectorSQLAlgorithm>();
     183         285 :     registry.Register<GDALVectorSwapXYAlgorithm>();
     184             : 
     185         285 :     registry.Register<GDALTeeVectorAlgorithm>(
     186         570 :         addSuffixIfNeeded(GDALTeeVectorAlgorithm::NAME));
     187         285 : }
     188             : 
     189             : /************************************************************************/
     190             : /*            GDALVectorPipelineAlgorithm::GetUsageForCLI()             */
     191             : /************************************************************************/
     192             : 
     193           8 : std::string GDALVectorPipelineAlgorithm::GetUsageForCLI(
     194             :     bool shortUsage, const UsageOptions &usageOptions) const
     195             : {
     196           8 :     UsageOptions stepUsageOptions;
     197           8 :     stepUsageOptions.isPipelineStep = true;
     198             : 
     199           8 :     if (!m_helpDocCategory.empty() && m_helpDocCategory != "main")
     200             :     {
     201           4 :         auto alg = GetStepAlg(m_helpDocCategory);
     202           2 :         if (alg)
     203             :         {
     204           2 :             alg->SetCallPath({m_helpDocCategory});
     205           1 :             alg->GetArg("help-doc")->Set(true);
     206           1 :             return alg->GetUsageForCLI(shortUsage, stepUsageOptions);
     207             :         }
     208             :         else
     209             :         {
     210           1 :             fprintf(stderr, "ERROR: unknown pipeline step '%s'\n",
     211             :                     m_helpDocCategory.c_str());
     212             :             return CPLSPrintf("ERROR: unknown pipeline step '%s'\n",
     213           1 :                               m_helpDocCategory.c_str());
     214             :         }
     215             :     }
     216             : 
     217           6 :     UsageOptions usageOptionsMain(usageOptions);
     218           6 :     usageOptionsMain.isPipelineMain = true;
     219             :     std::string ret =
     220          12 :         GDALAlgorithm::GetUsageForCLI(shortUsage, usageOptionsMain);
     221           6 :     if (shortUsage)
     222           2 :         return ret;
     223             : 
     224             :     ret += "\n<PIPELINE> is of the form: read|concat [READ-OPTIONS] "
     225           4 :            "( ! <STEP-NAME> [STEP-OPTIONS] )* ! write|info [WRITE-OPTIONS]\n";
     226             : 
     227           4 :     if (m_helpDocCategory == "main")
     228             :     {
     229           1 :         return ret;
     230             :     }
     231             : 
     232           3 :     ret += '\n';
     233           3 :     ret += "Example: 'gdal vector pipeline --progress ! read in.gpkg ! \\\n";
     234           3 :     ret += "               reproject --dst-crs=EPSG:32632 ! ";
     235           3 :     ret += "write out.gpkg --overwrite'\n";
     236           3 :     ret += '\n';
     237           3 :     ret += "Potential steps are:\n";
     238             : 
     239          87 :     for (const std::string &name : m_stepRegistry.GetNames())
     240             :     {
     241         168 :         auto alg = GetStepAlg(name);
     242          84 :         assert(alg);
     243          84 :         auto [options, maxOptLen] = alg->GetArgNamesForCLI();
     244          84 :         stepUsageOptions.maxOptLen =
     245          84 :             std::max(stepUsageOptions.maxOptLen, maxOptLen);
     246             :     }
     247             : 
     248             :     {
     249           3 :         const auto name = GDALVectorReadAlgorithm::NAME;
     250           3 :         ret += '\n';
     251           6 :         auto alg = GetStepAlg(name);
     252           6 :         alg->SetCallPath({name});
     253           3 :         ret += alg->GetUsageForCLI(shortUsage, stepUsageOptions);
     254             :     }
     255          87 :     for (const std::string &name : m_stepRegistry.GetNames())
     256             :     {
     257         168 :         auto alg = GetStepAlg(name);
     258          84 :         assert(alg);
     259          90 :         if (alg->CanBeFirstStep() && !alg->CanBeMiddleStep() &&
     260          90 :             !alg->IsHidden() && name != GDALVectorReadAlgorithm::NAME)
     261             :         {
     262           3 :             ret += '\n';
     263           6 :             alg->SetCallPath({name});
     264           3 :             ret += alg->GetUsageForCLI(shortUsage, stepUsageOptions);
     265             :         }
     266             :     }
     267          87 :     for (const std::string &name : m_stepRegistry.GetNames())
     268             :     {
     269         168 :         auto alg = GetStepAlg(name);
     270          84 :         assert(alg);
     271          84 :         if (alg->CanBeMiddleStep() && !alg->IsHidden())
     272             :         {
     273          66 :             ret += '\n';
     274         132 :             alg->SetCallPath({name});
     275          66 :             ret += alg->GetUsageForCLI(shortUsage, stepUsageOptions);
     276             :         }
     277             :     }
     278          87 :     for (const std::string &name : m_stepRegistry.GetNames())
     279             :     {
     280         168 :         auto alg = GetStepAlg(name);
     281          84 :         assert(alg);
     282          96 :         if (alg->CanBeLastStep() && !alg->CanBeMiddleStep() &&
     283          96 :             !alg->IsHidden() && name != GDALVectorWriteAlgorithm::NAME)
     284             :         {
     285           6 :             ret += '\n';
     286          12 :             alg->SetCallPath({name});
     287           6 :             ret += alg->GetUsageForCLI(shortUsage, stepUsageOptions);
     288             :         }
     289             :     }
     290             :     {
     291           3 :         const auto name = GDALVectorWriteAlgorithm::NAME;
     292           3 :         ret += '\n';
     293           6 :         auto alg = GetStepAlg(name);
     294           6 :         alg->SetCallPath({name});
     295           3 :         ret += alg->GetUsageForCLI(shortUsage, stepUsageOptions);
     296             :     }
     297             : 
     298           3 :     ret += GetUsageForCLIEnd();
     299             : 
     300           3 :     return ret;
     301             : }
     302             : 
     303             : /************************************************************************/
     304             : /*                  GDALVectorPipelineOutputLayer                       */
     305             : /************************************************************************/
     306             : 
     307             : /************************************************************************/
     308             : /*                  GDALVectorPipelineOutputLayer()                     */
     309             : /************************************************************************/
     310             : 
     311         180 : GDALVectorPipelineOutputLayer::GDALVectorPipelineOutputLayer(OGRLayer &srcLayer)
     312         180 :     : m_srcLayer(srcLayer)
     313             : {
     314         180 : }
     315             : 
     316             : /************************************************************************/
     317             : /*                 ~GDALVectorPipelineOutputLayer()                     */
     318             : /************************************************************************/
     319             : 
     320             : GDALVectorPipelineOutputLayer::~GDALVectorPipelineOutputLayer() = default;
     321             : 
     322             : /************************************************************************/
     323             : /*             GDALVectorPipelineOutputLayer::ResetReading()            */
     324             : /************************************************************************/
     325             : 
     326         578 : void GDALVectorPipelineOutputLayer::ResetReading()
     327             : {
     328         578 :     m_srcLayer.ResetReading();
     329         578 :     m_pendingFeatures.clear();
     330         578 :     m_idxInPendingFeatures = 0;
     331         578 : }
     332             : 
     333             : /************************************************************************/
     334             : /*           GDALVectorPipelineOutputLayer::GetNextRawFeature()         */
     335             : /************************************************************************/
     336             : 
     337        2334 : OGRFeature *GDALVectorPipelineOutputLayer::GetNextRawFeature()
     338             : {
     339        2334 :     if (m_idxInPendingFeatures < m_pendingFeatures.size())
     340             :     {
     341             :         OGRFeature *poFeature =
     342          14 :             m_pendingFeatures[m_idxInPendingFeatures].release();
     343          14 :         ++m_idxInPendingFeatures;
     344          14 :         return poFeature;
     345             :     }
     346        2320 :     m_pendingFeatures.clear();
     347        2320 :     m_idxInPendingFeatures = 0;
     348             :     while (true)
     349             :     {
     350             :         auto poSrcFeature =
     351        2329 :             std::unique_ptr<OGRFeature>(m_srcLayer.GetNextFeature());
     352        2329 :         if (!poSrcFeature)
     353         263 :             return nullptr;
     354        2066 :         TranslateFeature(std::move(poSrcFeature), m_pendingFeatures);
     355        2066 :         if (m_translateError)
     356             :         {
     357           7 :             return nullptr;
     358             :         }
     359        2059 :         if (!m_pendingFeatures.empty())
     360        2050 :             break;
     361           9 :     }
     362        2050 :     OGRFeature *poFeature = m_pendingFeatures[0].release();
     363        2050 :     m_idxInPendingFeatures = 1;
     364        2050 :     return poFeature;
     365             : }
     366             : 
     367             : /************************************************************************/
     368             : /*                         GDALVectorOutputDataset                      */
     369             : /************************************************************************/
     370             : 
     371          15 : int GDALVectorOutputDataset::TestCapability(const char *) const
     372             : {
     373          15 :     return 0;
     374             : }
     375             : 
     376             : /************************************************************************/
     377             : /*                 GDALVectorPipelineOutputDataset                      */
     378             : /************************************************************************/
     379             : 
     380             : /************************************************************************/
     381             : /*                 GDALVectorPipelineOutputDataset()                    */
     382             : /************************************************************************/
     383             : 
     384         171 : GDALVectorPipelineOutputDataset::GDALVectorPipelineOutputDataset(
     385         171 :     GDALDataset &srcDS)
     386         171 :     : m_srcDS(srcDS)
     387             : {
     388         171 :     SetDescription(m_srcDS.GetDescription());
     389         171 :     SetMetadata(m_srcDS.GetMetadata());
     390         171 : }
     391             : 
     392             : /************************************************************************/
     393             : /*            GDALVectorPipelineOutputDataset::AddLayer()               */
     394             : /************************************************************************/
     395             : 
     396         182 : void GDALVectorPipelineOutputDataset::AddLayer(
     397             :     OGRLayer &oSrcLayer,
     398             :     std::unique_ptr<OGRLayerWithTranslateFeature> poNewLayer)
     399             : {
     400         182 :     m_layersToDestroy.push_back(std::move(poNewLayer));
     401             :     OGRLayerWithTranslateFeature *poNewLayerRaw =
     402         182 :         m_layersToDestroy.back().get();
     403         182 :     m_layers.push_back(poNewLayerRaw);
     404         182 :     m_mapSrcLayerToNewLayer[&oSrcLayer] = poNewLayerRaw;
     405         182 : }
     406             : 
     407             : /************************************************************************/
     408             : /*          GDALVectorPipelineOutputDataset::GetLayerCount()            */
     409             : /************************************************************************/
     410             : 
     411         569 : int GDALVectorPipelineOutputDataset::GetLayerCount() const
     412             : {
     413         569 :     return static_cast<int>(m_layers.size());
     414             : }
     415             : 
     416             : /************************************************************************/
     417             : /*             GDALVectorPipelineOutputDataset::GetLayer()              */
     418             : /************************************************************************/
     419             : 
     420         264 : OGRLayer *GDALVectorPipelineOutputDataset::GetLayer(int idx) const
     421             : {
     422         264 :     return idx >= 0 && idx < GetLayerCount() ? m_layers[idx] : nullptr;
     423             : }
     424             : 
     425             : /************************************************************************/
     426             : /*           GDALVectorPipelineOutputDataset::TestCapability()          */
     427             : /************************************************************************/
     428             : 
     429         125 : int GDALVectorPipelineOutputDataset::TestCapability(const char *pszCap) const
     430             : {
     431         125 :     if (EQUAL(pszCap, ODsCRandomLayerRead) ||
     432          31 :         EQUAL(pszCap, ODsCMeasuredGeometries) || EQUAL(pszCap, ODsCZGeometries))
     433             :     {
     434         109 :         return m_srcDS.TestCapability(pszCap);
     435             :     }
     436          16 :     return false;
     437             : }
     438             : 
     439             : /************************************************************************/
     440             : /*             GDALVectorPipelineOutputDataset::ResetReading()          */
     441             : /************************************************************************/
     442             : 
     443           3 : void GDALVectorPipelineOutputDataset::ResetReading()
     444             : {
     445           3 :     m_srcDS.ResetReading();
     446           3 :     m_pendingFeatures.clear();
     447           3 :     m_idxInPendingFeatures = 0;
     448           3 : }
     449             : 
     450             : /************************************************************************/
     451             : /*            GDALVectorPipelineOutputDataset::GetNextFeature()         */
     452             : /************************************************************************/
     453             : 
     454          23 : OGRFeature *GDALVectorPipelineOutputDataset::GetNextFeature(
     455             :     OGRLayer **ppoBelongingLayer, double *pdfProgressPct,
     456             :     GDALProgressFunc pfnProgress, void *pProgressData)
     457             : {
     458          23 :     if (m_idxInPendingFeatures < m_pendingFeatures.size())
     459             :     {
     460             :         OGRFeature *poFeature =
     461           3 :             m_pendingFeatures[m_idxInPendingFeatures].release();
     462           3 :         if (ppoBelongingLayer)
     463           3 :             *ppoBelongingLayer = m_belongingLayer;
     464           3 :         ++m_idxInPendingFeatures;
     465           3 :         return poFeature;
     466             :     }
     467             : 
     468          20 :     m_pendingFeatures.clear();
     469          20 :     m_idxInPendingFeatures = 0;
     470             : 
     471             :     while (true)
     472             :     {
     473          20 :         OGRLayer *poSrcBelongingLayer = nullptr;
     474          20 :         auto poSrcFeature = std::unique_ptr<OGRFeature>(m_srcDS.GetNextFeature(
     475          20 :             &poSrcBelongingLayer, pdfProgressPct, pfnProgress, pProgressData));
     476          20 :         if (!poSrcFeature)
     477           3 :             return nullptr;
     478          17 :         auto iterToDstLayer = m_mapSrcLayerToNewLayer.find(poSrcBelongingLayer);
     479          17 :         if (iterToDstLayer != m_mapSrcLayerToNewLayer.end())
     480             :         {
     481          17 :             m_belongingLayer = iterToDstLayer->second;
     482          17 :             m_belongingLayer->TranslateFeature(std::move(poSrcFeature),
     483          17 :                                                m_pendingFeatures);
     484             : 
     485          17 :             if (!m_pendingFeatures.empty())
     486          17 :                 break;
     487             :         }
     488           0 :     }
     489          17 :     OGRFeature *poFeature = m_pendingFeatures[0].release();
     490          17 :     if (ppoBelongingLayer)
     491          17 :         *ppoBelongingLayer = m_belongingLayer;
     492          17 :     m_idxInPendingFeatures = 1;
     493          17 :     return poFeature;
     494             : }
     495             : 
     496             : /************************************************************************/
     497             : /*            GDALVectorPipelinePassthroughLayer::GetLayerDefn()        */
     498             : /************************************************************************/
     499             : 
     500          33 : const OGRFeatureDefn *GDALVectorPipelinePassthroughLayer::GetLayerDefn() const
     501             : {
     502          33 :     return m_srcLayer.GetLayerDefn();
     503             : }
     504             : 
     505             : /************************************************************************/
     506             : /*                 GDALVectorNonStreamingAlgorithmDataset()             */
     507             : /************************************************************************/
     508             : 
     509          30 : GDALVectorNonStreamingAlgorithmDataset::GDALVectorNonStreamingAlgorithmDataset()
     510          30 :     : m_ds(MEMDataset::Create("", 0, 0, 0, GDT_Unknown, nullptr))
     511             : {
     512          30 : }
     513             : 
     514             : /************************************************************************/
     515             : /*                ~GDALVectorNonStreamingAlgorithmDataset()             */
     516             : /************************************************************************/
     517             : 
     518             : GDALVectorNonStreamingAlgorithmDataset::
     519             :     ~GDALVectorNonStreamingAlgorithmDataset() = default;
     520             : 
     521             : /************************************************************************/
     522             : /*    GDALVectorNonStreamingAlgorithmDataset::AddProcessedLayer()       */
     523             : /************************************************************************/
     524             : 
     525          26 : bool GDALVectorNonStreamingAlgorithmDataset::AddProcessedLayer(
     526             :     OGRLayer &srcLayer, OGRFeatureDefn &dstDefn)
     527             : {
     528          26 :     CPLStringList aosOptions;
     529          26 :     if (srcLayer.TestCapability(OLCStringsAsUTF8))
     530             :     {
     531           1 :         aosOptions.AddNameValue("ADVERTIZE_UTF8", "TRUE");
     532             :     }
     533             : 
     534          26 :     OGRMemLayer *poDstLayer = m_ds->CreateLayer(dstDefn, aosOptions.List());
     535          26 :     m_layers.push_back(poDstLayer);
     536             : 
     537          26 :     const bool bRet = Process(srcLayer, *poDstLayer);
     538          26 :     poDstLayer->SetUpdatable(false);
     539          52 :     return bRet;
     540             : }
     541             : 
     542          20 : bool GDALVectorNonStreamingAlgorithmDataset::AddProcessedLayer(
     543             :     OGRLayer &srcLayer)
     544             : {
     545          20 :     return AddProcessedLayer(srcLayer, *srcLayer.GetLayerDefn());
     546             : }
     547             : 
     548             : /************************************************************************/
     549             : /*    GDALVectorNonStreamingAlgorithmDataset::AddPassThroughLayer()     */
     550             : /************************************************************************/
     551             : 
     552           6 : void GDALVectorNonStreamingAlgorithmDataset::AddPassThroughLayer(
     553             :     OGRLayer &oLayer)
     554             : {
     555           6 :     m_passthrough_layers.push_back(
     556          12 :         std::make_unique<GDALVectorPipelinePassthroughLayer>(oLayer));
     557           6 :     m_layers.push_back(m_passthrough_layers.back().get());
     558           6 : }
     559             : 
     560             : /************************************************************************/
     561             : /*       GDALVectorNonStreamingAlgorithmDataset::GetLayerCount()        */
     562             : /************************************************************************/
     563             : 
     564          74 : int GDALVectorNonStreamingAlgorithmDataset::GetLayerCount() const
     565             : {
     566          74 :     return static_cast<int>(m_layers.size());
     567             : }
     568             : 
     569             : /************************************************************************/
     570             : /*       GDALVectorNonStreamingAlgorithmDataset::GetLayer()             */
     571             : /************************************************************************/
     572             : 
     573          73 : OGRLayer *GDALVectorNonStreamingAlgorithmDataset::GetLayer(int idx) const
     574             : {
     575          73 :     if (idx < 0 || idx >= static_cast<int>(m_layers.size()))
     576             :     {
     577           4 :         return nullptr;
     578             :     }
     579          69 :     return m_layers[idx];
     580             : }
     581             : 
     582             : /************************************************************************/
     583             : /*    GDALVectorNonStreamingAlgorithmDataset::TestCapability()          */
     584             : /************************************************************************/
     585             : 
     586          18 : int GDALVectorNonStreamingAlgorithmDataset::TestCapability(
     587             :     const char *pszCap) const
     588             : {
     589          18 :     if (EQUAL(pszCap, ODsCCreateLayer) || EQUAL(pszCap, ODsCDeleteLayer))
     590             :     {
     591           4 :         return false;
     592             :     }
     593             : 
     594          14 :     return m_ds->TestCapability(pszCap);
     595             : }
     596             : 
     597             : //! @endcond

Generated by: LCOV version 1.14