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(GDALProgressFunc pfnProgress, void *pProgressData) override; 37 : 38 : /** Register the sub-algorithm of type MyAlgorithm. 39 : */ 40 532 : template <class MyAlgorithm> bool RegisterSubAlgorithm(bool standalone) 41 : { 42 1064 : GDALAlgorithmRegistry::AlgInfo info; 43 532 : info.m_name = MyAlgorithm::NAME; 44 532 : info.m_aliases = MyAlgorithm::GetAliasesStatic(); 45 633 : info.m_creationFunc = [standalone]() -> std::unique_ptr<GDALAlgorithm> 46 101 : { return std::make_unique<MyAlgorithm>(standalone); }; 47 1064 : return GDALAlgorithm::RegisterSubAlgorithm(info); 48 : } 49 : }; 50 : 51 : /************************************************************************/ 52 : /* GDALVectorGeomAlgorithmStandalone */ 53 : /************************************************************************/ 54 : 55 : class GDALVectorGeomAlgorithmStandalone final : public GDALVectorGeomAlgorithm 56 : { 57 : public: 58 66 : GDALVectorGeomAlgorithmStandalone() 59 66 : : GDALVectorGeomAlgorithm(/* standaloneStep = */ true) 60 : { 61 66 : } 62 : }; 63 : 64 : /************************************************************************/ 65 : /* GDALVectorGeomAbstractAlgorithm */ 66 : /************************************************************************/ 67 : 68 : class GDALVectorGeomAbstractAlgorithm /* non final */ 69 : : public GDALVectorPipelineStepAlgorithm 70 : { 71 : protected: 72 : struct OptionsBase 73 : { 74 : std::string m_activeLayer{}; 75 : std::string m_geomField{}; 76 : }; 77 : 78 : virtual std::unique_ptr<OGRLayerWithTranslateFeature> 79 : CreateAlgLayer(OGRLayer &srcLayer) = 0; 80 : 81 : GDALVectorGeomAbstractAlgorithm(const std::string &name, 82 : const std::string &description, 83 : const std::string &helpURL, 84 : bool standaloneStep, OptionsBase &opts); 85 : 86 : bool RunStep(GDALProgressFunc, void *) override; 87 : 88 : private: 89 : std::string &m_activeLayer; 90 : }; 91 : 92 : /************************************************************************/ 93 : /* GDALVectorGeomOneToOneAlgorithmLayer */ 94 : /************************************************************************/ 95 : 96 : template <class T> 97 : class GDALVectorGeomOneToOneAlgorithmLayer /* non final */ 98 : : public GDALVectorPipelineOutputLayer 99 : { 100 : public: 101 223 : OGRFeatureDefn *GetLayerDefn() override 102 : { 103 223 : return m_srcLayer.GetLayerDefn(); 104 : } 105 : 106 21 : GIntBig GetFeatureCount(int bForce) override 107 : { 108 21 : if (!m_poAttrQuery && !m_poFilterGeom) 109 11 : return m_srcLayer.GetFeatureCount(bForce); 110 10 : return OGRLayer::GetFeatureCount(bForce); 111 : } 112 : 113 12 : OGRErr IGetExtent(int iGeomField, OGREnvelope *psExtent, 114 : bool bForce) override 115 : { 116 12 : return m_srcLayer.GetExtent(iGeomField, psExtent, bForce); 117 : } 118 : 119 26 : OGRFeature *GetFeature(GIntBig nFID) override 120 : { 121 52 : auto poSrcFeature = 122 26 : std::unique_ptr<OGRFeature>(m_srcLayer.GetFeature(nFID)); 123 26 : if (!poSrcFeature) 124 11 : return nullptr; 125 15 : return TranslateFeature(std::move(poSrcFeature)).release(); 126 : } 127 : 128 47 : int TestCapability(const char *pszCap) override 129 : { 130 47 : if (EQUAL(pszCap, OLCRandomRead) || EQUAL(pszCap, OLCCurveGeometries) || 131 43 : EQUAL(pszCap, OLCMeasuredGeometries) || 132 39 : EQUAL(pszCap, OLCZGeometries) || EQUAL(pszCap, OLCFastGetExtent) || 133 34 : (EQUAL(pszCap, OLCFastFeatureCount) && !m_poAttrQuery && 134 4 : !m_poFilterGeom) || 135 30 : EQUAL(pszCap, OLCStringsAsUTF8)) 136 : { 137 33 : return m_srcLayer.TestCapability(pszCap); 138 : } 139 14 : return false; 140 : } 141 : 142 : protected: 143 : const typename T::Options m_opts; 144 : 145 42 : GDALVectorGeomOneToOneAlgorithmLayer(OGRLayer &oSrcLayer, 146 : const typename T::Options &opts) 147 42 : : GDALVectorPipelineOutputLayer(oSrcLayer), m_opts(opts) 148 : { 149 42 : SetDescription(oSrcLayer.GetDescription()); 150 42 : SetMetadata(oSrcLayer.GetMetadata()); 151 42 : if (!m_opts.m_geomField.empty()) 152 : { 153 2 : const int nIdx = oSrcLayer.GetLayerDefn()->GetGeomFieldIndex( 154 : m_opts.m_geomField.c_str()); 155 2 : if (nIdx >= 0) 156 2 : m_iGeomIdx = nIdx; 157 : else 158 0 : m_iGeomIdx = INT_MAX; 159 : } 160 42 : } 161 : 162 656 : bool IsSelectedGeomField(int idx) const 163 : { 164 656 : return m_iGeomIdx < 0 || idx == m_iGeomIdx; 165 : } 166 : 167 : virtual std::unique_ptr<OGRFeature> 168 : TranslateFeature(std::unique_ptr<OGRFeature> poSrcFeature) const = 0; 169 : 170 618 : void TranslateFeature( 171 : std::unique_ptr<OGRFeature> poSrcFeature, 172 : std::vector<std::unique_ptr<OGRFeature>> &apoOutFeatures) override 173 : { 174 1236 : auto poDstFeature = TranslateFeature(std::move(poSrcFeature)); 175 618 : if (poDstFeature) 176 616 : apoOutFeatures.push_back(std::move(poDstFeature)); 177 618 : } 178 : 179 : private: 180 : int m_iGeomIdx = -1; 181 : }; 182 : 183 : //! @endcond 184 : 185 : #endif /* GDALALG_VECTOR_GEOM_INCLUDED */