LCOV - code coverage report
Current view: top level - apps - gdalalg_vector_simplify_coverage.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 47 48 97.9 %
Date: 2025-12-21 22:14:19 Functions: 8 8 100.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             : *
       3             :  * Project:  GDAL
       4             :  * Purpose:  "gdal vector simplify-coverage" subcommand
       5             :  * Author:   Daniel Baston
       6             :  *
       7             :  ******************************************************************************
       8             :  * Copyright (c) 2025, ISciences LLC
       9             :  *
      10             :  * SPDX-License-Identifier: MIT
      11             :  ****************************************************************************/
      12             : 
      13             : #include "gdalalg_vector_simplify_coverage.h"
      14             : 
      15             : #include "cpl_error.h"
      16             : #include "gdal_priv.h"
      17             : #include "gdalalg_vector_geom.h"
      18             : #include "ogr_geometry.h"
      19             : #include "ogr_geos.h"
      20             : #include "ogrsf_frmts.h"
      21             : 
      22             : #include <cinttypes>
      23             : 
      24             : #ifndef _
      25             : #define _(x) (x)
      26             : #endif
      27             : 
      28             : //! @cond Doxygen_Suppress
      29             : 
      30          48 : GDALVectorSimplifyCoverageAlgorithm::GDALVectorSimplifyCoverageAlgorithm(
      31          48 :     bool standaloneStep)
      32             :     : GDALVectorPipelineStepAlgorithm(NAME, DESCRIPTION, HELP_URL,
      33          48 :                                       standaloneStep)
      34             : {
      35          48 :     AddActiveLayerArg(&m_activeLayer);
      36             :     AddArg("tolerance", 0, _("Distance tolerance for simplification."),
      37          96 :            &m_opts.tolerance)
      38          48 :         .SetPositional()
      39          48 :         .SetRequired()
      40          48 :         .SetMinValueIncluded(0);
      41             :     AddArg("preserve-boundary", 0,
      42             :            _("Whether the exterior boundary should be preserved."),
      43          48 :            &m_opts.preserveBoundary);
      44          48 : }
      45             : 
      46             : #if defined HAVE_GEOS &&                                                       \
      47             :     (GEOS_VERSION_MAJOR > 3 ||                                                 \
      48             :      (GEOS_VERSION_MAJOR == 3 && GEOS_VERSION_MINOR >= 12))
      49             : 
      50          16 : class GDALVectorSimplifyCoverageOutputDataset final
      51             :     : public GDALGeosNonStreamingAlgorithmDataset
      52             : {
      53             :   public:
      54           8 :     GDALVectorSimplifyCoverageOutputDataset(
      55             :         const GDALVectorSimplifyCoverageAlgorithm::Options &opts)
      56           8 :         : m_opts(opts)
      57             :     {
      58           8 :     }
      59             : 
      60             :     ~GDALVectorSimplifyCoverageOutputDataset() override;
      61             : 
      62          43 :     bool PolygonsOnly() const override
      63             :     {
      64          43 :         return true;
      65             :     }
      66             : 
      67          40 :     bool SkipEmpty() const override
      68             :     {
      69          40 :         return false;
      70             :     }
      71             : 
      72           4 :     bool ProcessGeos() override
      73             :     {
      74             :         // Perform coverage simplification
      75           4 :         GEOSGeometry *coll = GEOSGeom_createCollection_r(
      76             :             m_poGeosContext, GEOS_GEOMETRYCOLLECTION, m_apoGeosInputs.data(),
      77           4 :             static_cast<unsigned int>(m_apoGeosInputs.size()));
      78             : 
      79           4 :         if (coll == nullptr)
      80             :         {
      81           0 :             return false;
      82             :         }
      83             : 
      84           4 :         m_apoGeosInputs.clear();
      85             : 
      86           8 :         m_poGeosResultAsCollection = GEOSCoverageSimplifyVW_r(
      87           4 :             m_poGeosContext, coll, m_opts.tolerance, m_opts.preserveBoundary);
      88           4 :         GEOSGeom_destroy_r(m_poGeosContext, coll);
      89             : 
      90           4 :         return m_poGeosResultAsCollection != nullptr;
      91             :     }
      92             : 
      93             :   private:
      94             :     CPL_DISALLOW_COPY_ASSIGN(GDALVectorSimplifyCoverageOutputDataset)
      95             : 
      96             :     const GDALVectorSimplifyCoverageAlgorithm::Options &m_opts;
      97             : };
      98             : 
      99             : GDALVectorSimplifyCoverageOutputDataset::
     100             :     ~GDALVectorSimplifyCoverageOutputDataset() = default;
     101             : 
     102           8 : bool GDALVectorSimplifyCoverageAlgorithm::RunStep(
     103             :     GDALPipelineStepRunContext &ctxt)
     104             : {
     105           8 :     auto poSrcDS = m_inputDataset[0].GetDatasetRef();
     106             :     auto poDstDS =
     107          16 :         std::make_unique<GDALVectorSimplifyCoverageOutputDataset>(m_opts);
     108             : 
     109          16 :     GDALVectorAlgorithmLayerProgressHelper progressHelper(ctxt);
     110             : 
     111          18 :     for (auto &&poSrcLayer : poSrcDS->GetLayers())
     112             :     {
     113          14 :         if (m_activeLayer.empty() ||
     114           4 :             m_activeLayer == poSrcLayer->GetDescription())
     115             :         {
     116           7 :             progressHelper.AddProcessedLayer(*poSrcLayer);
     117             :         }
     118             :         else
     119             :         {
     120           3 :             progressHelper.AddPassThroughLayer(*poSrcLayer);
     121             :         }
     122             :     }
     123             : 
     124           8 :     if (!progressHelper.HasProcessedLayers())
     125             :     {
     126           1 :         ReportError(CE_Failure, CPLE_AppDefined,
     127             :                     "Specified layer '%s' was not found",
     128             :                     m_activeLayer.c_str());
     129           1 :         return false;
     130             :     }
     131             : 
     132          13 :     for (auto [poSrcLayer, bProcessed, layerProgressFunc, layerProgressData] :
     133          17 :          progressHelper)
     134             :     {
     135           8 :         if (bProcessed)
     136             :         {
     137           7 :             if (!poDstDS->AddProcessedLayer(*poSrcLayer, layerProgressFunc,
     138             :                                             layerProgressData.get()))
     139             :             {
     140           3 :                 return false;
     141             :             }
     142             :         }
     143             :         else
     144             :         {
     145           1 :             poDstDS->AddPassThroughLayer(*poSrcLayer);
     146             :         }
     147             :     }
     148             : 
     149           4 :     m_outputDataset.Set(std::move(poDstDS));
     150             : 
     151           4 :     return true;
     152             : }
     153             : 
     154             : #else
     155             : 
     156             : bool GDALVectorSimplifyCoverageAlgorithm::RunStep(GDALPipelineStepRunContext &)
     157             : {
     158             :     ReportError(CE_Failure, CPLE_AppDefined,
     159             :                 "%s requires GDAL to be built against version 3.12 or later of "
     160             :                 "the GEOS library.",
     161             :                 NAME);
     162             :     return false;
     163             : }
     164             : #endif  // HAVE_GEOS
     165             : 
     166             : GDALVectorSimplifyCoverageAlgorithmStandalone::
     167             :     ~GDALVectorSimplifyCoverageAlgorithmStandalone() = default;
     168             : 
     169             : //! @endcond

Generated by: LCOV version 1.14