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