LCOV - code coverage report
Current view: top level - apps - gdalalg_vector_geom.h (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 39 40 97.5 %
Date: 2026-06-23 16:35:19 Functions: 50 72 69.4 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  GDAL
       4             :  * Purpose:  Base classes for some geometry-related vector algorithms
       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 "gdalvectorpipelinestepalgorithm.h"
      17             : 
      18             : #include "ogr_geos.h"
      19             : 
      20             : //! @cond Doxygen_Suppress
      21             : 
      22             : /************************************************************************/
      23             : /*                   GDALVectorGeomAbstractAlgorithm                    */
      24             : /************************************************************************/
      25             : 
      26             : class GDALVectorGeomAbstractAlgorithm /* non final */
      27             :     : public GDALVectorPipelineStepAlgorithm
      28             : {
      29             :   protected:
      30             :     struct OptionsBase
      31             :     {
      32             :         std::string m_activeLayer{};
      33             :         std::string m_geomField{};
      34             :     };
      35             : 
      36             :     virtual std::unique_ptr<OGRLayerWithTranslateFeature>
      37             :     CreateAlgLayer(OGRLayer &srcLayer) = 0;
      38             : 
      39             :     GDALVectorGeomAbstractAlgorithm(const std::string &name,
      40             :                                     const std::string &description,
      41             :                                     const std::string &helpURL,
      42             :                                     bool standaloneStep, OptionsBase &opts);
      43             : 
      44             :     bool RunStep(GDALPipelineStepRunContext &ctxt) override;
      45             : 
      46             :   private:
      47             :     std::string &m_activeLayer;
      48             : };
      49             : 
      50             : /************************************************************************/
      51             : /*                 GDALVectorGeomOneToOneAlgorithmLayer                 */
      52             : /************************************************************************/
      53             : 
      54             : template <class T>
      55             : class GDALVectorGeomOneToOneAlgorithmLayer /* non final */
      56             :     : public GDALVectorPipelineOutputLayer
      57             : {
      58             :   public:
      59         233 :     const OGRFeatureDefn *GetLayerDefn() const override
      60             :     {
      61         233 :         return m_srcLayer.GetLayerDefn();
      62             :     }
      63             : 
      64          25 :     GIntBig GetFeatureCount(int bForce) override
      65             :     {
      66          25 :         if (!m_poAttrQuery && !m_poFilterGeom)
      67          15 :             return m_srcLayer.GetFeatureCount(bForce);
      68          10 :         return OGRLayer::GetFeatureCount(bForce);
      69             :     }
      70             : 
      71          12 :     OGRErr IGetExtent(int iGeomField, OGREnvelope *psExtent,
      72             :                       bool bForce) override
      73             :     {
      74          12 :         return m_srcLayer.GetExtent(iGeomField, psExtent, bForce);
      75             :     }
      76             : 
      77          26 :     OGRFeature *GetFeature(GIntBig nFID) override
      78             :     {
      79          52 :         auto poSrcFeature =
      80          26 :             std::unique_ptr<OGRFeature>(m_srcLayer.GetFeature(nFID));
      81          26 :         if (!poSrcFeature)
      82          11 :             return nullptr;
      83          15 :         return TranslateFeature(std::move(poSrcFeature)).release();
      84             :     }
      85             : 
      86          51 :     int TestCapability(const char *pszCap) const override
      87             :     {
      88          51 :         if (EQUAL(pszCap, OLCRandomRead) || EQUAL(pszCap, OLCCurveGeometries) ||
      89          47 :             EQUAL(pszCap, OLCMeasuredGeometries) ||
      90          43 :             EQUAL(pszCap, OLCZGeometries) || EQUAL(pszCap, OLCFastGetExtent) ||
      91          38 :             (EQUAL(pszCap, OLCFastFeatureCount) && !m_poAttrQuery &&
      92           4 :              !m_poFilterGeom) ||
      93          34 :             EQUAL(pszCap, OLCStringsAsUTF8))
      94             :         {
      95          34 :             return m_srcLayer.TestCapability(pszCap);
      96             :         }
      97          17 :         return false;
      98             :     }
      99             : 
     100             :   protected:
     101             :     const typename T::Options m_opts;
     102             : 
     103          65 :     GDALVectorGeomOneToOneAlgorithmLayer(OGRLayer &oSrcLayer,
     104             :                                          const typename T::Options &opts)
     105          65 :         : GDALVectorPipelineOutputLayer(oSrcLayer), m_opts(opts)
     106             :     {
     107          65 :         SetDescription(oSrcLayer.GetDescription());
     108          65 :         SetMetadata(oSrcLayer.GetMetadata());
     109          65 :         if (!m_opts.m_geomField.empty())
     110             :         {
     111           2 :             const int nIdx = oSrcLayer.GetLayerDefn()->GetGeomFieldIndex(
     112             :                 m_opts.m_geomField.c_str());
     113           2 :             if (nIdx >= 0)
     114           2 :                 m_iGeomIdx = nIdx;
     115             :             else
     116           0 :                 m_iGeomIdx = INT_MAX;
     117             :         }
     118          65 :     }
     119             : 
     120         746 :     bool IsSelectedGeomField(int idx) const
     121             :     {
     122         746 :         return m_iGeomIdx < 0 || idx == m_iGeomIdx;
     123             :     }
     124             : 
     125             :     virtual std::unique_ptr<OGRFeature>
     126             :     TranslateFeature(std::unique_ptr<OGRFeature> poSrcFeature) const = 0;
     127             : 
     128         684 :     bool TranslateFeature(
     129             :         std::unique_ptr<OGRFeature> poSrcFeature,
     130             :         std::vector<std::unique_ptr<OGRFeature>> &apoOutFeatures) override
     131             :     {
     132         684 :         auto poDstFeature = TranslateFeature(std::move(poSrcFeature));
     133         684 :         if (poDstFeature && PassesFilters(poDstFeature.get()))
     134         503 :             apoOutFeatures.push_back(std::move(poDstFeature));
     135        1368 :         return true;
     136             :     }
     137             : 
     138             :   private:
     139             :     int m_iGeomIdx = -1;
     140             : };
     141             : 
     142             : #ifdef HAVE_GEOS
     143             : 
     144             : /************************************************************************/
     145             : /*                  GDALGeosNonStreamingAlgorithmLayer                  */
     146             : /************************************************************************/
     147             : 
     148             : /** A GDALGeosNonStreamingAlgorithmLayer manages the work of reading features
     149             :  *  from an input layer, converting OGR geometries into GEOS geometries,
     150             :  *  applying a GEOS function, and creating OGRFeatures for the results. It
     151             :  *  appropriate only for GEOS algorithms that operate on all input geometries
     152             :  *  at a single time.
     153             :  */
     154             : class GDALGeosNonStreamingAlgorithmLayer
     155             :     : public GDALVectorNonStreamingAlgorithmLayer
     156             : {
     157             :   public:
     158             :     GDALGeosNonStreamingAlgorithmLayer(OGRLayer &srcLayer, int geomFieldIndex);
     159             : 
     160             :     ~GDALGeosNonStreamingAlgorithmLayer() override;
     161             : 
     162             :     void ResetReading() override;
     163             : 
     164             :     CPL_DISALLOW_COPY_ASSIGN(GDALGeosNonStreamingAlgorithmLayer)
     165             : 
     166             :     bool Process(GDALProgressFunc pfnProgress, void *pProgressData) override;
     167             : 
     168             :     std::unique_ptr<OGRFeature> GetNextProcessedFeature() override;
     169             : 
     170             :     virtual bool ProcessGeos() = 0;
     171             : 
     172             :     /// Whether the operation should fail if non-polygonal geometries are present
     173             :     virtual bool PolygonsOnly() const = 0;
     174             : 
     175             :     /// Whether empty result features should be excluded from the output
     176             :     virtual bool SkipEmpty() const = 0;
     177             : 
     178             :   protected:
     179             :     GEOSContextHandle_t m_poGeosContext{nullptr};
     180             :     std::vector<GEOSGeometry *> m_apoGeosInputs{};
     181             :     GEOSGeometry *m_poGeosResultAsCollection{nullptr};
     182             :     GEOSGeometry **m_papoGeosResults{nullptr};
     183             : 
     184             :   private:
     185             :     bool ConvertInputsToGeos(OGRLayer &srcLayer, int geomFieldIndex,
     186             :                              GDALProgressFunc pfnProgress, void *pProgressData);
     187             : 
     188             :     void Cleanup();
     189             : 
     190             :     std::vector<std::unique_ptr<OGRFeature>> m_apoFeatures{};
     191             :     unsigned int m_nGeosResultSize{0};
     192             :     unsigned int m_readPos{0};
     193             : };
     194             : 
     195             : #endif
     196             : 
     197             : //! @endcond
     198             : 
     199             : #endif /* GDALALG_VECTOR_GEOM_INCLUDED */

Generated by: LCOV version 1.14