Line data Source code
1 : /****************************************************************************** 2 : * 3 : * Project: GDAL 4 : * Purpose: "geom" step of "vector pipeline", or "gdal vector geom" standalone 5 : * Author: Even Rouault <even dot rouault at spatialys.com> 6 : * 7 : ****************************************************************************** 8 : * Copyright (c) 2025, Even Rouault <even dot rouault at spatialys.com> 9 : * 10 : * SPDX-License-Identifier: MIT 11 : ****************************************************************************/ 12 : 13 : #ifndef GDALALG_VECTOR_GEOM_INCLUDED 14 : #define GDALALG_VECTOR_GEOM_INCLUDED 15 : 16 : #include "gdalalg_vector_pipeline.h" 17 : 18 : //! @cond Doxygen_Suppress 19 : 20 : /************************************************************************/ 21 : /* GDALVectorGeomAlgorithm */ 22 : /************************************************************************/ 23 : 24 : class GDALVectorGeomAlgorithm /* non final */ 25 : : public GDALVectorPipelineStepAlgorithm 26 : { 27 : public: 28 : static constexpr const char *NAME = "geom"; 29 : static constexpr const char *DESCRIPTION = 30 : "Geometry operations on a vector dataset."; 31 : static constexpr const char *HELP_URL = "/programs/gdal_vector_geom.html"; 32 : 33 : explicit GDALVectorGeomAlgorithm(bool standaloneStep = false); 34 : 35 : private: 36 : bool RunStep(GDALPipelineStepRunContext &ctxt) override; 37 : 38 : void WarnIfDeprecated() override; 39 : 40 : /** Register the sub-algorithm of type MyAlgorithm. 41 : */ 42 182 : template <class MyAlgorithm> bool RegisterSubAlgorithm(bool standalone) 43 : { 44 364 : GDALAlgorithmRegistry::AlgInfo info; 45 182 : info.m_name = MyAlgorithm::NAME; 46 182 : info.m_aliases = MyAlgorithm::GetAliasesStatic(); 47 192 : info.m_creationFunc = [standalone]() -> std::unique_ptr<GDALAlgorithm> 48 10 : { return std::make_unique<MyAlgorithm>(standalone); }; 49 364 : return GDALAlgorithm::RegisterSubAlgorithm(info); 50 : } 51 : }; 52 : 53 : /************************************************************************/ 54 : /* GDALVectorGeomAlgorithmStandalone */ 55 : /************************************************************************/ 56 : 57 6 : class GDALVectorGeomAlgorithmStandalone final : public GDALVectorGeomAlgorithm 58 : { 59 : public: 60 3 : GDALVectorGeomAlgorithmStandalone() 61 3 : : GDALVectorGeomAlgorithm(/* standaloneStep = */ true) 62 : { 63 3 : } 64 : 65 : ~GDALVectorGeomAlgorithmStandalone() override; 66 : }; 67 : 68 : /************************************************************************/ 69 : /* GDALVectorGeomAbstractAlgorithm */ 70 : /************************************************************************/ 71 : 72 : class GDALVectorGeomAbstractAlgorithm /* non final */ 73 : : public GDALVectorPipelineStepAlgorithm 74 : { 75 : protected: 76 : struct OptionsBase 77 : { 78 : std::string m_activeLayer{}; 79 : std::string m_geomField{}; 80 : }; 81 : 82 : virtual std::unique_ptr<OGRLayerWithTranslateFeature> 83 : CreateAlgLayer(OGRLayer &srcLayer) = 0; 84 : 85 : GDALVectorGeomAbstractAlgorithm(const std::string &name, 86 : const std::string &description, 87 : const std::string &helpURL, 88 : bool standaloneStep, OptionsBase &opts); 89 : 90 : bool RunStep(GDALPipelineStepRunContext &ctxt) override; 91 : 92 : private: 93 : std::string &m_activeLayer; 94 : }; 95 : 96 : /************************************************************************/ 97 : /* GDALVectorGeomOneToOneAlgorithmLayer */ 98 : /************************************************************************/ 99 : 100 : template <class T> 101 : class GDALVectorGeomOneToOneAlgorithmLayer /* non final */ 102 : : public GDALVectorPipelineOutputLayer 103 : { 104 : public: 105 223 : OGRFeatureDefn *GetLayerDefn() override 106 : { 107 223 : return m_srcLayer.GetLayerDefn(); 108 : } 109 : 110 21 : GIntBig GetFeatureCount(int bForce) override 111 : { 112 21 : if (!m_poAttrQuery && !m_poFilterGeom) 113 11 : return m_srcLayer.GetFeatureCount(bForce); 114 10 : return OGRLayer::GetFeatureCount(bForce); 115 : } 116 : 117 12 : OGRErr IGetExtent(int iGeomField, OGREnvelope *psExtent, 118 : bool bForce) override 119 : { 120 12 : return m_srcLayer.GetExtent(iGeomField, psExtent, bForce); 121 : } 122 : 123 26 : OGRFeature *GetFeature(GIntBig nFID) override 124 : { 125 52 : auto poSrcFeature = 126 26 : std::unique_ptr<OGRFeature>(m_srcLayer.GetFeature(nFID)); 127 26 : if (!poSrcFeature) 128 11 : return nullptr; 129 15 : return TranslateFeature(std::move(poSrcFeature)).release(); 130 : } 131 : 132 47 : int TestCapability(const char *pszCap) override 133 : { 134 47 : if (EQUAL(pszCap, OLCRandomRead) || EQUAL(pszCap, OLCCurveGeometries) || 135 43 : EQUAL(pszCap, OLCMeasuredGeometries) || 136 39 : EQUAL(pszCap, OLCZGeometries) || EQUAL(pszCap, OLCFastGetExtent) || 137 34 : (EQUAL(pszCap, OLCFastFeatureCount) && !m_poAttrQuery && 138 4 : !m_poFilterGeom) || 139 30 : EQUAL(pszCap, OLCStringsAsUTF8)) 140 : { 141 33 : return m_srcLayer.TestCapability(pszCap); 142 : } 143 14 : return false; 144 : } 145 : 146 : protected: 147 : const typename T::Options m_opts; 148 : 149 42 : GDALVectorGeomOneToOneAlgorithmLayer(OGRLayer &oSrcLayer, 150 : const typename T::Options &opts) 151 42 : : GDALVectorPipelineOutputLayer(oSrcLayer), m_opts(opts) 152 : { 153 42 : SetDescription(oSrcLayer.GetDescription()); 154 42 : SetMetadata(oSrcLayer.GetMetadata()); 155 42 : if (!m_opts.m_geomField.empty()) 156 : { 157 2 : const int nIdx = oSrcLayer.GetLayerDefn()->GetGeomFieldIndex( 158 : m_opts.m_geomField.c_str()); 159 2 : if (nIdx >= 0) 160 2 : m_iGeomIdx = nIdx; 161 : else 162 0 : m_iGeomIdx = INT_MAX; 163 : } 164 42 : } 165 : 166 656 : bool IsSelectedGeomField(int idx) const 167 : { 168 656 : return m_iGeomIdx < 0 || idx == m_iGeomIdx; 169 : } 170 : 171 : virtual std::unique_ptr<OGRFeature> 172 : TranslateFeature(std::unique_ptr<OGRFeature> poSrcFeature) const = 0; 173 : 174 618 : void TranslateFeature( 175 : std::unique_ptr<OGRFeature> poSrcFeature, 176 : std::vector<std::unique_ptr<OGRFeature>> &apoOutFeatures) override 177 : { 178 1236 : auto poDstFeature = TranslateFeature(std::move(poSrcFeature)); 179 618 : if (poDstFeature) 180 616 : apoOutFeatures.push_back(std::move(poDstFeature)); 181 618 : } 182 : 183 : private: 184 : int m_iGeomIdx = -1; 185 : }; 186 : 187 : //! @endcond 188 : 189 : #endif /* GDALALG_VECTOR_GEOM_INCLUDED */