LCOV - code coverage report
Current view: top level - apps - gdalalg_vector_reproject.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 56 57 98.2 %
Date: 2026-05-13 23:47:50 Functions: 2 2 100.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  GDAL
       4             :  * Purpose:  "reproject" step of "vector pipeline"
       5             :  * Author:   Even Rouault <even dot rouault at spatialys.com>
       6             :  *
       7             :  ******************************************************************************
       8             :  * Copyright (c) 2024, Even Rouault <even dot rouault at spatialys.com>
       9             :  *
      10             :  * SPDX-License-Identifier: MIT
      11             :  ****************************************************************************/
      12             : 
      13             : #include "gdalalg_vector_reproject.h"
      14             : 
      15             : #include "gdal_priv.h"
      16             : #include "ogr_spatialref.h"
      17             : #include "ogrsf_frmts.h"
      18             : #include "ogrwarpedlayer.h"
      19             : 
      20             : //! @cond Doxygen_Suppress
      21             : 
      22             : #ifndef _
      23             : #define _(x) (x)
      24             : #endif
      25             : 
      26             : /************************************************************************/
      27             : /*     GDALVectorReprojectAlgorithm::GDALVectorReprojectAlgorithm()     */
      28             : /************************************************************************/
      29             : 
      30         101 : GDALVectorReprojectAlgorithm::GDALVectorReprojectAlgorithm(bool standaloneStep)
      31             :     : GDALVectorPipelineStepAlgorithm(NAME, DESCRIPTION, HELP_URL,
      32         101 :                                       standaloneStep)
      33             : {
      34         101 :     AddActiveLayerArg(&m_activeLayer);
      35         202 :     AddArg(GDAL_ARG_NAME_INPUT_CRS, 's', _("Input CRS"), &m_srcCrs)
      36         202 :         .SetIsCRSArg()
      37         202 :         .AddHiddenAlias("src-crs")
      38         101 :         .AddHiddenAlias("s_srs");
      39         202 :     AddArg(GDAL_ARG_NAME_OUTPUT_CRS, 'd', _("Output CRS"), &m_dstCrs)
      40         202 :         .SetIsCRSArg()
      41         101 :         .SetRequired()
      42         202 :         .AddHiddenAlias("dst-crs")
      43         101 :         .AddHiddenAlias("t_srs");
      44         101 : }
      45             : 
      46             : /************************************************************************/
      47             : /*               GDALVectorReprojectAlgorithm::RunStep()                */
      48             : /************************************************************************/
      49             : 
      50          12 : bool GDALVectorReprojectAlgorithm::RunStep(GDALPipelineStepRunContext &)
      51             : {
      52          12 :     auto poSrcDS = m_inputDataset[0].GetDatasetRef();
      53          12 :     CPLAssert(poSrcDS);
      54             : 
      55          12 :     CPLAssert(m_outputDataset.GetName().empty());
      56          12 :     CPLAssert(!m_outputDataset.GetDatasetRef());
      57             : 
      58          12 :     std::unique_ptr<OGRSpatialReference> poSrcCRS;
      59          12 :     if (!m_srcCrs.empty())
      60             :     {
      61           3 :         poSrcCRS = std::make_unique<OGRSpatialReference>();
      62           3 :         poSrcCRS->SetFromUserInput(m_srcCrs.c_str());
      63           3 :         poSrcCRS->SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER);
      64             :     }
      65             : 
      66          24 :     OGRSpatialReference oDstCRS;
      67          12 :     oDstCRS.SetFromUserInput(m_dstCrs.c_str());
      68          12 :     oDstCRS.SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER);
      69             : 
      70             :     auto reprojectedDataset =
      71          24 :         std::make_unique<GDALVectorPipelineOutputDataset>(*poSrcDS);
      72             : 
      73          12 :     const int nLayerCount = poSrcDS->GetLayerCount();
      74          12 :     bool ret = true;
      75          40 :     for (int i = 0; ret && i < nLayerCount; ++i)
      76             :     {
      77          29 :         auto poSrcLayer = poSrcDS->GetLayer(i);
      78          29 :         ret = (poSrcLayer != nullptr);
      79          29 :         if (ret)
      80             :         {
      81          29 :             if ((m_activeLayer.empty() &&
      82          47 :                  poSrcLayer->GetGeomType() != wkbNone) ||
      83          18 :                 m_activeLayer == poSrcLayer->GetDescription())
      84             :             {
      85             :                 const OGRSpatialReference *poSrcLayerCRS;
      86          12 :                 if (poSrcCRS)
      87           3 :                     poSrcLayerCRS = poSrcCRS.get();
      88             :                 else
      89           9 :                     poSrcLayerCRS = poSrcLayer->GetSpatialRef();
      90          12 :                 if (!poSrcLayerCRS)
      91             :                 {
      92           1 :                     ReportError(CE_Failure, CPLE_AppDefined,
      93             :                                 "Layer '%s' has no spatial reference system",
      94           1 :                                 poSrcLayer->GetName());
      95           1 :                     return false;
      96             :                 }
      97             :                 auto poCT = std::unique_ptr<OGRCoordinateTransformation>(
      98          22 :                     OGRCreateCoordinateTransformation(poSrcLayerCRS, &oDstCRS));
      99             :                 auto poReversedCT =
     100             :                     std::unique_ptr<OGRCoordinateTransformation>(
     101             :                         OGRCreateCoordinateTransformation(&oDstCRS,
     102          22 :                                                           poSrcLayerCRS));
     103          11 :                 ret = (poCT != nullptr) && (poReversedCT != nullptr);
     104          11 :                 if (ret)
     105             :                 {
     106          22 :                     reprojectedDataset->AddLayer(
     107             :                         *poSrcLayer,
     108          11 :                         std::make_unique<OGRWarpedLayer>(
     109           0 :                             poSrcLayer, /* iGeomField = */ 0,
     110          22 :                             /*bTakeOwnership = */ false, std::move(poCT),
     111          11 :                             std::move(poReversedCT)));
     112             :                 }
     113             :             }
     114             :             else
     115             :             {
     116          34 :                 reprojectedDataset->AddLayer(
     117             :                     *poSrcLayer,
     118          34 :                     std::make_unique<GDALVectorPipelinePassthroughLayer>(
     119             :                         *poSrcLayer));
     120             :             }
     121             :         }
     122             :     }
     123             : 
     124          11 :     if (ret)
     125          11 :         m_outputDataset.Set(std::move(reprojectedDataset));
     126             : 
     127          11 :     return ret;
     128             : }
     129             : 
     130             : GDALVectorReprojectAlgorithmStandalone::
     131             :     ~GDALVectorReprojectAlgorithmStandalone() = default;
     132             : 
     133             : //! @endcond

Generated by: LCOV version 1.14