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