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 548 : GDALVectorReadAlgorithm::GDALVectorReadAlgorithm() 29 : : GDALVectorPipelineStepAlgorithm( 30 : NAME, DESCRIPTION, HELP_URL, 31 548 : ConstructorOptions().SetAddDefaultArguments(false)) 32 : { 33 548 : AddVectorInputArgs(/* hiddenForCLI = */ false); 34 548 : } 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 : poDriver = m_srcDS.GetDriver(); 79 14 : } 80 : 81 : /************************************************************************/ 82 : /* GDALVectorPipelineReadOutputDataset::AddLayer() */ 83 : /************************************************************************/ 84 : 85 11 : void GDALVectorPipelineReadOutputDataset::AddLayer(OGRLayer &oSrcLayer) 86 : { 87 11 : m_layers.push_back(&oSrcLayer); 88 11 : } 89 : 90 : /************************************************************************/ 91 : /* GDALVectorPipelineReadOutputDataset::GetLayerCount() */ 92 : /************************************************************************/ 93 : 94 25 : int GDALVectorPipelineReadOutputDataset::GetLayerCount() const 95 : { 96 25 : return static_cast<int>(m_layers.size()); 97 : } 98 : 99 : /************************************************************************/ 100 : /* GDALVectorPipelineReadOutputDataset::GetLayer() */ 101 : /************************************************************************/ 102 : 103 10 : OGRLayer *GDALVectorPipelineReadOutputDataset::GetLayer(int idx) const 104 : { 105 10 : return idx >= 0 && idx < GetLayerCount() ? m_layers[idx] : nullptr; 106 : } 107 : 108 : /************************************************************************/ 109 : /* GDALVectorPipelineReadOutputDataset::TestCapability() */ 110 : /************************************************************************/ 111 : 112 3 : int GDALVectorPipelineReadOutputDataset::TestCapability( 113 : const char *pszCap) const 114 : { 115 3 : if (EQUAL(pszCap, ODsCRandomLayerRead)) 116 3 : return m_srcDS.TestCapability(pszCap); 117 0 : return false; 118 : } 119 : 120 : /************************************************************************/ 121 : /* GDALVectorPipelineReadOutputDataset::ResetReading() */ 122 : /************************************************************************/ 123 : 124 1 : void GDALVectorPipelineReadOutputDataset::ResetReading() 125 : { 126 1 : m_srcDS.ResetReading(); 127 1 : } 128 : 129 : /************************************************************************/ 130 : /* GDALVectorPipelineReadOutputDataset::GetNextFeature() */ 131 : /************************************************************************/ 132 : 133 9 : OGRFeature *GDALVectorPipelineReadOutputDataset::GetNextFeature( 134 : OGRLayer **ppoBelongingLayer, double *pdfProgressPct, 135 : GDALProgressFunc pfnProgress, void *pProgressData) 136 : { 137 : while (true) 138 : { 139 9 : OGRLayer *poBelongingLayer = nullptr; 140 9 : auto poFeature = std::unique_ptr<OGRFeature>(m_srcDS.GetNextFeature( 141 9 : &poBelongingLayer, pdfProgressPct, pfnProgress, pProgressData)); 142 9 : if (ppoBelongingLayer) 143 9 : *ppoBelongingLayer = poBelongingLayer; 144 9 : if (!poFeature) 145 1 : break; 146 8 : if (std::find(m_layers.begin(), m_layers.end(), poBelongingLayer) != 147 16 : m_layers.end()) 148 4 : return poFeature.release(); 149 4 : } 150 1 : return nullptr; 151 : } 152 : 153 : /************************************************************************/ 154 : /* GDALVectorReadAlgorithm::RunStep() */ 155 : /************************************************************************/ 156 : 157 466 : bool GDALVectorReadAlgorithm::RunStep(GDALPipelineStepRunContext &) 158 : { 159 466 : auto poSrcDS = m_inputDataset[0].GetDatasetRef(); 160 466 : CPLAssert(poSrcDS); 161 : 162 466 : CPLAssert(m_outputDataset.GetName().empty()); 163 466 : CPLAssert(!m_outputDataset.GetDatasetRef()); 164 : 165 466 : if (m_inputLayerNames.empty()) 166 : { 167 452 : m_outputDataset.Set(poSrcDS); 168 : } 169 : else 170 : { 171 : auto poOutDS = 172 14 : std::make_unique<GDALVectorPipelineReadOutputDataset>(*poSrcDS); 173 25 : for (const auto &srcLayerName : m_inputLayerNames) 174 : { 175 16 : auto poSrcLayer = poSrcDS->GetLayerByName(srcLayerName.c_str()); 176 16 : if (!poSrcLayer) 177 : { 178 5 : ReportError(CE_Failure, CPLE_AppDefined, 179 : "Cannot find source layer '%s'", 180 : srcLayerName.c_str()); 181 5 : return false; 182 : } 183 11 : poOutDS->AddLayer(*poSrcLayer); 184 : } 185 9 : m_outputDataset.Set(std::move(poOutDS)); 186 : } 187 461 : return true; 188 : } 189 : 190 : //! @endcond