LCOV - code coverage report
Current view: top level - apps - gdalalg_vector_pipeline.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 244 245 99.6 %
Date: 2025-09-18 11:40:35 Functions: 24 25 96.0 %

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

Generated by: LCOV version 1.14