Line data Source code
1 : /****************************************************************************** 2 : * 3 : * Project: GDAL 4 : * Purpose: "read" step of "vector pipeline" 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_read.h" 14 : 15 : #include "gdal_priv.h" 16 : #include "ogrsf_frmts.h" 17 : 18 : //! @cond Doxygen_Suppress 19 : 20 : #ifndef _ 21 : #define _(x) (x) 22 : #endif 23 : 24 : /************************************************************************/ 25 : /* GDALVectorReadAlgorithm::GDALVectorReadAlgorithm() */ 26 : /************************************************************************/ 27 : 28 457 : GDALVectorReadAlgorithm::GDALVectorReadAlgorithm() 29 : : GDALVectorPipelineStepAlgorithm( 30 : NAME, DESCRIPTION, HELP_URL, 31 457 : ConstructorOptions().SetAddDefaultArguments(false)) 32 : { 33 457 : AddVectorInputArgs(/* hiddenForCLI = */ false); 34 457 : } 35 : 36 : /************************************************************************/ 37 : /* GDALVectorPipelineReadOutputDataset */ 38 : /************************************************************************/ 39 : 40 : /** Class used by vector pipeline steps to create an output on-the-fly 41 : * dataset where they can store on-the-fly layers. 42 : */ 43 : class GDALVectorPipelineReadOutputDataset final : public GDALDataset 44 : { 45 : GDALDataset &m_srcDS; 46 : std::vector<OGRLayer *> m_layers{}; 47 : 48 : CPL_DISALLOW_COPY_ASSIGN(GDALVectorPipelineReadOutputDataset) 49 : 50 : public: 51 : explicit GDALVectorPipelineReadOutputDataset(GDALDataset &oSrcDS); 52 : 53 : void AddLayer(OGRLayer &oSrcLayer); 54 : 55 : int GetLayerCount() const override; 56 : 57 : OGRLayer *GetLayer(int idx) const override; 58 : 59 : int TestCapability(const char *pszCap) const override; 60 : 61 : void ResetReading() override; 62 : 63 : OGRFeature *GetNextFeature(OGRLayer **ppoBelongingLayer, 64 : double *pdfProgressPct, 65 : GDALProgressFunc pfnProgress, 66 : void *pProgressData) override; 67 : }; 68 : 69 : /************************************************************************/ 70 : /* GDALVectorPipelineReadOutputDataset() */ 71 : /************************************************************************/ 72 : 73 14 : GDALVectorPipelineReadOutputDataset::GDALVectorPipelineReadOutputDataset( 74 14 : GDALDataset &srcDS) 75 14 : : m_srcDS(srcDS) 76 : { 77 14 : SetDescription(m_srcDS.GetDescription()); 78 14 : } 79 : 80 : /************************************************************************/ 81 : /* GDALVectorPipelineReadOutputDataset::AddLayer() */ 82 : /************************************************************************/ 83 : 84 11 : void GDALVectorPipelineReadOutputDataset::AddLayer(OGRLayer &oSrcLayer) 85 : { 86 11 : m_layers.push_back(&oSrcLayer); 87 11 : } 88 : 89 : /************************************************************************/ 90 : /* GDALVectorPipelineReadOutputDataset::GetLayerCount() */ 91 : /************************************************************************/ 92 : 93 24 : int GDALVectorPipelineReadOutputDataset::GetLayerCount() const 94 : { 95 24 : return static_cast<int>(m_layers.size()); 96 : } 97 : 98 : /************************************************************************/ 99 : /* GDALVectorPipelineReadOutputDataset::GetLayer() */ 100 : /************************************************************************/ 101 : 102 10 : OGRLayer *GDALVectorPipelineReadOutputDataset::GetLayer(int idx) const 103 : { 104 10 : return idx >= 0 && idx < GetLayerCount() ? m_layers[idx] : nullptr; 105 : } 106 : 107 : /************************************************************************/ 108 : /* GDALVectorPipelineReadOutputDataset::TestCapability() */ 109 : /************************************************************************/ 110 : 111 3 : int GDALVectorPipelineReadOutputDataset::TestCapability( 112 : const char *pszCap) const 113 : { 114 3 : if (EQUAL(pszCap, ODsCRandomLayerRead)) 115 3 : return m_srcDS.TestCapability(pszCap); 116 0 : return false; 117 : } 118 : 119 : /************************************************************************/ 120 : /* GDALVectorPipelineReadOutputDataset::ResetReading() */ 121 : /************************************************************************/ 122 : 123 1 : void GDALVectorPipelineReadOutputDataset::ResetReading() 124 : { 125 1 : m_srcDS.ResetReading(); 126 1 : } 127 : 128 : /************************************************************************/ 129 : /* GDALVectorPipelineReadOutputDataset::GetNextFeature() */ 130 : /************************************************************************/ 131 : 132 9 : OGRFeature *GDALVectorPipelineReadOutputDataset::GetNextFeature( 133 : OGRLayer **ppoBelongingLayer, double *pdfProgressPct, 134 : GDALProgressFunc pfnProgress, void *pProgressData) 135 : { 136 : while (true) 137 : { 138 9 : OGRLayer *poBelongingLayer = nullptr; 139 9 : auto poFeature = std::unique_ptr<OGRFeature>(m_srcDS.GetNextFeature( 140 9 : &poBelongingLayer, pdfProgressPct, pfnProgress, pProgressData)); 141 9 : if (ppoBelongingLayer) 142 9 : *ppoBelongingLayer = poBelongingLayer; 143 9 : if (!poFeature) 144 1 : break; 145 8 : if (std::find(m_layers.begin(), m_layers.end(), poBelongingLayer) != 146 16 : m_layers.end()) 147 4 : return poFeature.release(); 148 4 : } 149 1 : return nullptr; 150 : } 151 : 152 : /************************************************************************/ 153 : /* GDALVectorReadAlgorithm::RunStep() */ 154 : /************************************************************************/ 155 : 156 376 : bool GDALVectorReadAlgorithm::RunStep(GDALPipelineStepRunContext &) 157 : { 158 376 : auto poSrcDS = m_inputDataset[0].GetDatasetRef(); 159 376 : CPLAssert(poSrcDS); 160 : 161 376 : CPLAssert(m_outputDataset.GetName().empty()); 162 376 : CPLAssert(!m_outputDataset.GetDatasetRef()); 163 : 164 376 : if (m_inputLayerNames.empty()) 165 : { 166 362 : m_outputDataset.Set(poSrcDS); 167 : } 168 : else 169 : { 170 : auto poOutDS = 171 14 : std::make_unique<GDALVectorPipelineReadOutputDataset>(*poSrcDS); 172 25 : for (const auto &srcLayerName : m_inputLayerNames) 173 : { 174 16 : auto poSrcLayer = poSrcDS->GetLayerByName(srcLayerName.c_str()); 175 16 : if (!poSrcLayer) 176 : { 177 5 : ReportError(CE_Failure, CPLE_AppDefined, 178 : "Cannot find source layer '%s'", 179 : srcLayerName.c_str()); 180 5 : return false; 181 : } 182 11 : poOutDS->AddLayer(*poSrcLayer); 183 : } 184 9 : m_outputDataset.Set(std::move(poOutDS)); 185 : } 186 371 : return true; 187 : } 188 : 189 : //! @endcond