LCOV - code coverage report
Current view: top level - apps - gdalalg_vector_geom.h (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 53 54 98.1 %
Date: 2025-09-10 17:48:50 Functions: 52 66 78.8 %

          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             : #include "ogr_geos.h"
      18             : 
      19             : //! @cond Doxygen_Suppress
      20             : 
      21             : /************************************************************************/
      22             : /*                       GDALVectorGeomAlgorithm                        */
      23             : /************************************************************************/
      24             : 
      25             : class GDALVectorGeomAlgorithm /* non final */
      26             :     : public GDALVectorPipelineStepAlgorithm
      27             : {
      28             :   public:
      29             :     static constexpr const char *NAME = "geom";
      30             :     static constexpr const char *DESCRIPTION =
      31             :         "Geometry operations on a vector dataset.";
      32             :     static constexpr const char *HELP_URL = "/programs/gdal_vector_geom.html";
      33             : 
      34             :     explicit GDALVectorGeomAlgorithm(bool standaloneStep = false);
      35             : 
      36             :   private:
      37             :     bool RunStep(GDALPipelineStepRunContext &ctxt) override;
      38             : 
      39             :     void WarnIfDeprecated() override;
      40             : 
      41             :     /** Register the sub-algorithm of type MyAlgorithm.
      42             :      */
      43         357 :     template <class MyAlgorithm> bool RegisterSubAlgorithm(bool standalone)
      44             :     {
      45         714 :         GDALAlgorithmRegistry::AlgInfo info;
      46         357 :         info.m_name = MyAlgorithm::NAME;
      47         357 :         info.m_aliases = MyAlgorithm::GetAliasesStatic();
      48         360 :         info.m_creationFunc = [standalone]() -> std::unique_ptr<GDALAlgorithm>
      49           3 :         { return std::make_unique<MyAlgorithm>(standalone); };
      50         714 :         return GDALAlgorithm::RegisterSubAlgorithm(info);
      51             :     }
      52             : };
      53             : 
      54             : /************************************************************************/
      55             : /*                    GDALVectorGeomAlgorithmStandalone                 */
      56             : /************************************************************************/
      57             : 
      58           6 : class GDALVectorGeomAlgorithmStandalone final : public GDALVectorGeomAlgorithm
      59             : {
      60             :   public:
      61           3 :     GDALVectorGeomAlgorithmStandalone()
      62           3 :         : GDALVectorGeomAlgorithm(/* standaloneStep = */ true)
      63             :     {
      64           3 :     }
      65             : 
      66             :     ~GDALVectorGeomAlgorithmStandalone() override;
      67             : };
      68             : 
      69             : /************************************************************************/
      70             : /*                    GDALVectorGeomAbstractAlgorithm                   */
      71             : /************************************************************************/
      72             : 
      73             : class GDALVectorGeomAbstractAlgorithm /* non final */
      74             :     : public GDALVectorPipelineStepAlgorithm
      75             : {
      76             :   protected:
      77             :     struct OptionsBase
      78             :     {
      79             :         std::string m_activeLayer{};
      80             :         std::string m_geomField{};
      81             :     };
      82             : 
      83             :     virtual std::unique_ptr<OGRLayerWithTranslateFeature>
      84             :     CreateAlgLayer(OGRLayer &srcLayer) = 0;
      85             : 
      86             :     GDALVectorGeomAbstractAlgorithm(const std::string &name,
      87             :                                     const std::string &description,
      88             :                                     const std::string &helpURL,
      89             :                                     bool standaloneStep, OptionsBase &opts);
      90             : 
      91             :     bool RunStep(GDALPipelineStepRunContext &ctxt) override;
      92             : 
      93             :   private:
      94             :     std::string &m_activeLayer;
      95             : };
      96             : 
      97             : /************************************************************************/
      98             : /*                  GDALVectorGeomOneToOneAlgorithmLayer                */
      99             : /************************************************************************/
     100             : 
     101             : template <class T>
     102             : class GDALVectorGeomOneToOneAlgorithmLayer /* non final */
     103             :     : public GDALVectorPipelineOutputLayer
     104             : {
     105             :   public:
     106         220 :     const OGRFeatureDefn *GetLayerDefn() const override
     107             :     {
     108         220 :         return m_srcLayer.GetLayerDefn();
     109             :     }
     110             : 
     111          21 :     GIntBig GetFeatureCount(int bForce) override
     112             :     {
     113          21 :         if (!m_poAttrQuery && !m_poFilterGeom)
     114          11 :             return m_srcLayer.GetFeatureCount(bForce);
     115          10 :         return OGRLayer::GetFeatureCount(bForce);
     116             :     }
     117             : 
     118          12 :     OGRErr IGetExtent(int iGeomField, OGREnvelope *psExtent,
     119             :                       bool bForce) override
     120             :     {
     121          12 :         return m_srcLayer.GetExtent(iGeomField, psExtent, bForce);
     122             :     }
     123             : 
     124          26 :     OGRFeature *GetFeature(GIntBig nFID) override
     125             :     {
     126          52 :         auto poSrcFeature =
     127          26 :             std::unique_ptr<OGRFeature>(m_srcLayer.GetFeature(nFID));
     128          26 :         if (!poSrcFeature)
     129          11 :             return nullptr;
     130          15 :         return TranslateFeature(std::move(poSrcFeature)).release();
     131             :     }
     132             : 
     133          48 :     int TestCapability(const char *pszCap) const override
     134             :     {
     135          48 :         if (EQUAL(pszCap, OLCRandomRead) || EQUAL(pszCap, OLCCurveGeometries) ||
     136          44 :             EQUAL(pszCap, OLCMeasuredGeometries) ||
     137          40 :             EQUAL(pszCap, OLCZGeometries) || EQUAL(pszCap, OLCFastGetExtent) ||
     138          35 :             (EQUAL(pszCap, OLCFastFeatureCount) && !m_poAttrQuery &&
     139           4 :              !m_poFilterGeom) ||
     140          31 :             EQUAL(pszCap, OLCStringsAsUTF8))
     141             :         {
     142          33 :             return m_srcLayer.TestCapability(pszCap);
     143             :         }
     144          15 :         return false;
     145             :     }
     146             : 
     147             :   protected:
     148             :     const typename T::Options m_opts;
     149             : 
     150          42 :     GDALVectorGeomOneToOneAlgorithmLayer(OGRLayer &oSrcLayer,
     151             :                                          const typename T::Options &opts)
     152          42 :         : GDALVectorPipelineOutputLayer(oSrcLayer), m_opts(opts)
     153             :     {
     154          42 :         SetDescription(oSrcLayer.GetDescription());
     155          42 :         SetMetadata(oSrcLayer.GetMetadata());
     156          42 :         if (!m_opts.m_geomField.empty())
     157             :         {
     158           2 :             const int nIdx = oSrcLayer.GetLayerDefn()->GetGeomFieldIndex(
     159             :                 m_opts.m_geomField.c_str());
     160           2 :             if (nIdx >= 0)
     161           2 :                 m_iGeomIdx = nIdx;
     162             :             else
     163           0 :                 m_iGeomIdx = INT_MAX;
     164             :         }
     165          42 :     }
     166             : 
     167         678 :     bool IsSelectedGeomField(int idx) const
     168             :     {
     169         678 :         return m_iGeomIdx < 0 || idx == m_iGeomIdx;
     170             :     }
     171             : 
     172             :     virtual std::unique_ptr<OGRFeature>
     173             :     TranslateFeature(std::unique_ptr<OGRFeature> poSrcFeature) const = 0;
     174             : 
     175         640 :     void TranslateFeature(
     176             :         std::unique_ptr<OGRFeature> poSrcFeature,
     177             :         std::vector<std::unique_ptr<OGRFeature>> &apoOutFeatures) override
     178             :     {
     179        1280 :         auto poDstFeature = TranslateFeature(std::move(poSrcFeature));
     180         640 :         if (poDstFeature)
     181         638 :             apoOutFeatures.push_back(std::move(poDstFeature));
     182         640 :     }
     183             : 
     184             :   private:
     185             :     int m_iGeomIdx = -1;
     186             : };
     187             : 
     188             : #ifdef HAVE_GEOS
     189             : 
     190             : /************************************************************************/
     191             : /*                    GDALGeosNonStreamingAlgorithmDataset              */
     192             : /************************************************************************/
     193             : 
     194             : /** A GDALGeosNonStreamingAlgorithmDataset manages the work of reading features
     195             :  *  from an input layer, converting OGR geometries into GEOS geometries,
     196             :  *  applying a GEOS function, and writing result to an output layer. It is
     197             :  *  appropriate only for GEOS algorithms that operate on all input geometries
     198             :  *  at a single time.
     199             :  */
     200             : class GDALGeosNonStreamingAlgorithmDataset
     201             :     : public GDALVectorNonStreamingAlgorithmDataset
     202             : {
     203             :   public:
     204             :     GDALGeosNonStreamingAlgorithmDataset();
     205             : 
     206             :     ~GDALGeosNonStreamingAlgorithmDataset() override;
     207             : 
     208             :     CPL_DISALLOW_COPY_ASSIGN(GDALGeosNonStreamingAlgorithmDataset)
     209             : 
     210             :     bool ConvertInputsToGeos(OGRLayer &srcLayer, OGRLayer &dstLayer,
     211             :                              bool sameDefn);
     212             : 
     213             :     bool ConvertOutputsFromGeos(OGRLayer &dstLayer);
     214             : 
     215             :     bool Process(OGRLayer &srcLayer, OGRLayer &dstLayer) override;
     216             : 
     217             :     virtual bool ProcessGeos() = 0;
     218             : 
     219             :     /// Whether the operation should fail if non-polygonal geometries are present
     220             :     virtual bool PolygonsOnly() const = 0;
     221             : 
     222             :     /// Whether empty result features should be excluded from the output
     223             :     virtual bool SkipEmpty() const = 0;
     224             : 
     225           6 :     void SetSourceGeometryField(int i)
     226             :     {
     227           6 :         m_sourceGeometryField = i;
     228           6 :     }
     229             : 
     230             :   protected:
     231             :     GEOSContextHandle_t m_poGeosContext{nullptr};
     232             :     std::vector<GEOSGeometry *> m_apoGeosInputs{};
     233             :     GEOSGeometry *m_poGeosResultAsCollection{nullptr};
     234             :     GEOSGeometry **m_papoGeosResults{nullptr};
     235             : 
     236             :   private:
     237             :     std::vector<std::unique_ptr<OGRFeature>> m_apoFeatures{};
     238             :     unsigned int m_nGeosResultSize{0};
     239             :     int m_sourceGeometryField{0};
     240             : };
     241             : 
     242             : #endif
     243             : 
     244             : //! @endcond
     245             : 
     246             : #endif /* GDALALG_VECTOR_GEOM_INCLUDED */

Generated by: LCOV version 1.14