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: 2025-12-17 01:24:48 Functions: 39 48 81.2 %

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

Generated by: LCOV version 1.14