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 569 : GDALVectorReadAlgorithm::GDALVectorReadAlgorithm() 29 : : GDALVectorPipelineStepAlgorithm( 30 : NAME, DESCRIPTION, HELP_URL, 31 569 : ConstructorOptions().SetAddDefaultArguments(false)) 32 : { 33 569 : AddVectorInputArgs(/* hiddenForCLI = */ false); 34 569 : } 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 44 : : public GDALVectorDecoratedDataset 45 : { 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 : OGRLayer *ExecuteSQL(const char *pszStatement, OGRGeometry *poSpatialFilter, 64 : const char *pszDialect) override; 65 : void ReleaseResultSet(OGRLayer *poResultsSet) override; 66 : 67 : OGRFeature *GetNextFeature(OGRLayer **ppoBelongingLayer, 68 : double *pdfProgressPct, 69 : GDALProgressFunc pfnProgress, 70 : void *pProgressData) override; 71 : }; 72 : 73 : /************************************************************************/ 74 : /* GDALVectorPipelineReadOutputDataset() */ 75 : /************************************************************************/ 76 : 77 17 : GDALVectorPipelineReadOutputDataset::GDALVectorPipelineReadOutputDataset( 78 17 : GDALDataset &srcDS) 79 17 : : GDALVectorDecoratedDataset(&srcDS) 80 : { 81 17 : poDriver = m_srcDS.GetDriver(); 82 17 : } 83 : 84 : /************************************************************************/ 85 : /* GDALVectorPipelineReadOutputDataset::AddLayer() */ 86 : /************************************************************************/ 87 : 88 14 : void GDALVectorPipelineReadOutputDataset::AddLayer(OGRLayer &oSrcLayer) 89 : { 90 14 : m_layers.push_back(&oSrcLayer); 91 14 : } 92 : 93 : /************************************************************************/ 94 : /* GDALVectorPipelineReadOutputDataset::GetLayerCount() */ 95 : /************************************************************************/ 96 : 97 27 : int GDALVectorPipelineReadOutputDataset::GetLayerCount() const 98 : { 99 27 : return static_cast<int>(m_layers.size()); 100 : } 101 : 102 : /************************************************************************/ 103 : /* GDALVectorPipelineReadOutputDataset::GetLayer() */ 104 : /************************************************************************/ 105 : 106 11 : OGRLayer *GDALVectorPipelineReadOutputDataset::GetLayer(int idx) const 107 : { 108 11 : return idx >= 0 && idx < GetLayerCount() ? m_layers[idx] : nullptr; 109 : } 110 : 111 : /************************************************************************/ 112 : /* GDALVectorPipelineReadOutputDataset::TestCapability() */ 113 : /************************************************************************/ 114 : 115 3 : int GDALVectorPipelineReadOutputDataset::TestCapability( 116 : const char *pszCap) const 117 : { 118 3 : if (EQUAL(pszCap, ODsCRandomLayerRead)) 119 3 : return m_srcDS.TestCapability(pszCap); 120 0 : return false; 121 : } 122 : 123 : /************************************************************************/ 124 : /* GDALVectorPipelineReadOutputDataset::ResetReading() */ 125 : /************************************************************************/ 126 : 127 1 : void GDALVectorPipelineReadOutputDataset::ResetReading() 128 : { 129 1 : m_srcDS.ResetReading(); 130 1 : } 131 : 132 : /************************************************************************/ 133 : /* GDALVectorPipelineReadOutputDataset::ExecuteSQL() */ 134 : /************************************************************************/ 135 : 136 : OGRLayer * 137 2 : GDALVectorPipelineReadOutputDataset::ExecuteSQL(const char *pszStatement, 138 : OGRGeometry *poSpatialFilter, 139 : const char *pszDialect) 140 : { 141 2 : return m_srcDS.ExecuteSQL(pszStatement, poSpatialFilter, pszDialect); 142 : } 143 : 144 : /************************************************************************/ 145 : /* GDALVectorPipelineReadOutputDataset::ReleaseResultSet() */ 146 : /************************************************************************/ 147 : 148 2 : void GDALVectorPipelineReadOutputDataset::ReleaseResultSet( 149 : OGRLayer *poResultsSet) 150 : { 151 2 : m_srcDS.ReleaseResultSet(poResultsSet); 152 2 : } 153 : 154 : /************************************************************************/ 155 : /* GDALVectorPipelineReadOutputDataset::GetNextFeature() */ 156 : /************************************************************************/ 157 : 158 9 : OGRFeature *GDALVectorPipelineReadOutputDataset::GetNextFeature( 159 : OGRLayer **ppoBelongingLayer, double *pdfProgressPct, 160 : GDALProgressFunc pfnProgress, void *pProgressData) 161 : { 162 : while (true) 163 : { 164 9 : OGRLayer *poBelongingLayer = nullptr; 165 9 : auto poFeature = std::unique_ptr<OGRFeature>(m_srcDS.GetNextFeature( 166 9 : &poBelongingLayer, pdfProgressPct, pfnProgress, pProgressData)); 167 9 : if (ppoBelongingLayer) 168 9 : *ppoBelongingLayer = poBelongingLayer; 169 9 : if (!poFeature) 170 1 : break; 171 8 : if (std::find(m_layers.begin(), m_layers.end(), poBelongingLayer) != 172 16 : m_layers.end()) 173 4 : return poFeature.release(); 174 4 : } 175 1 : return nullptr; 176 : } 177 : 178 : /************************************************************************/ 179 : /* GDALVectorReadAlgorithm::RunStep() */ 180 : /************************************************************************/ 181 : 182 484 : bool GDALVectorReadAlgorithm::RunStep(GDALPipelineStepRunContext &) 183 : { 184 484 : auto poSrcDS = m_inputDataset[0].GetDatasetRef(); 185 484 : CPLAssert(poSrcDS); 186 : 187 484 : CPLAssert(m_outputDataset.GetName().empty()); 188 484 : CPLAssert(!m_outputDataset.GetDatasetRef()); 189 : 190 484 : if (m_inputLayerNames.empty()) 191 : { 192 467 : m_outputDataset.Set(poSrcDS); 193 : } 194 : else 195 : { 196 : auto poOutDS = 197 17 : std::make_unique<GDALVectorPipelineReadOutputDataset>(*poSrcDS); 198 31 : for (const auto &srcLayerName : m_inputLayerNames) 199 : { 200 19 : auto poSrcLayer = poSrcDS->GetLayerByName(srcLayerName.c_str()); 201 19 : if (!poSrcLayer) 202 : { 203 5 : ReportError(CE_Failure, CPLE_AppDefined, 204 : "Cannot find source layer '%s'", 205 : srcLayerName.c_str()); 206 5 : return false; 207 : } 208 14 : poOutDS->AddLayer(*poSrcLayer); 209 : } 210 12 : m_outputDataset.Set(std::move(poOutDS)); 211 : } 212 479 : return true; 213 : } 214 : 215 : //! @endcond