LCOV - code coverage report
Current view: top level - apps - gdalalg_vector_reproject.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 53 54 98.1 %
Date: 2025-03-28 11:40:40 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          16 : GDALVectorReprojectAlgorithm::GDALVectorReprojectAlgorithm(bool standaloneStep)
      31             :     : GDALVectorPipelineStepAlgorithm(NAME, DESCRIPTION, HELP_URL,
      32          16 :                                       standaloneStep)
      33             : {
      34          16 :     AddActiveLayerArg(&m_activeLayer);
      35          32 :     AddArg("src-crs", 's', _("Source CRS"), &m_srsCrs)
      36          16 :         .SetIsCRSArg()
      37          16 :         .AddHiddenAlias("s_srs");
      38          32 :     AddArg("dst-crs", 'd', _("Destination CRS"), &m_dstCrs)
      39          16 :         .SetIsCRSArg()
      40          16 :         .SetRequired()
      41          16 :         .AddHiddenAlias("t_srs");
      42          16 : }
      43             : 
      44             : /************************************************************************/
      45             : /*            GDALVectorReprojectAlgorithm::RunStep()                   */
      46             : /************************************************************************/
      47             : 
      48           6 : bool GDALVectorReprojectAlgorithm::RunStep(GDALProgressFunc, void *)
      49             : {
      50           6 :     CPLAssert(m_inputDataset.GetDatasetRef());
      51           6 :     CPLAssert(m_outputDataset.GetName().empty());
      52           6 :     CPLAssert(!m_outputDataset.GetDatasetRef());
      53             : 
      54           6 :     std::unique_ptr<OGRSpatialReference> poSrcCRS;
      55           6 :     if (!m_srsCrs.empty())
      56             :     {
      57           3 :         poSrcCRS = std::make_unique<OGRSpatialReference>();
      58           3 :         poSrcCRS->SetFromUserInput(m_srsCrs.c_str());
      59           3 :         poSrcCRS->SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER);
      60             :     }
      61             : 
      62          12 :     OGRSpatialReference oDstCRS;
      63           6 :     oDstCRS.SetFromUserInput(m_dstCrs.c_str());
      64           6 :     oDstCRS.SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER);
      65             : 
      66           6 :     auto poSrcDS = m_inputDataset.GetDatasetRef();
      67             : 
      68             :     auto reprojectedDataset =
      69          12 :         std::make_unique<GDALVectorPipelineOutputDataset>(*poSrcDS);
      70             : 
      71           6 :     const int nLayerCount = poSrcDS->GetLayerCount();
      72           6 :     bool ret = true;
      73          16 :     for (int i = 0; ret && i < nLayerCount; ++i)
      74             :     {
      75          11 :         auto poSrcLayer = poSrcDS->GetLayer(i);
      76          11 :         ret = (poSrcLayer != nullptr);
      77          11 :         if (ret)
      78             :         {
      79          13 :             if (m_activeLayer.empty() ||
      80           2 :                 m_activeLayer == poSrcLayer->GetDescription())
      81             :             {
      82             :                 OGRSpatialReference *poSrcLayerCRS;
      83          10 :                 if (poSrcCRS)
      84           3 :                     poSrcLayerCRS = poSrcCRS.get();
      85             :                 else
      86           7 :                     poSrcLayerCRS = poSrcLayer->GetSpatialRef();
      87          10 :                 if (!poSrcLayerCRS)
      88             :                 {
      89           1 :                     ReportError(CE_Failure, CPLE_AppDefined,
      90             :                                 "Layer '%s' has no spatial reference system",
      91           1 :                                 poSrcLayer->GetName());
      92           1 :                     return false;
      93             :                 }
      94             :                 auto poCT = std::unique_ptr<OGRCoordinateTransformation>(
      95          18 :                     OGRCreateCoordinateTransformation(poSrcLayerCRS, &oDstCRS));
      96             :                 auto poReversedCT =
      97             :                     std::unique_ptr<OGRCoordinateTransformation>(
      98             :                         OGRCreateCoordinateTransformation(&oDstCRS,
      99          18 :                                                           poSrcLayerCRS));
     100           9 :                 ret = (poCT != nullptr) && (poReversedCT != nullptr);
     101           9 :                 if (ret)
     102             :                 {
     103          18 :                     reprojectedDataset->AddLayer(
     104             :                         *poSrcLayer,
     105           9 :                         std::make_unique<OGRWarpedLayer>(
     106           0 :                             poSrcLayer, /* iGeomField = */ 0,
     107           9 :                             /*bTakeOwnership = */ false, poCT.release(),
     108          18 :                             poReversedCT.release()));
     109             :                 }
     110             :             }
     111             :             else
     112             :             {
     113           2 :                 reprojectedDataset->AddLayer(
     114             :                     *poSrcLayer,
     115           2 :                     std::make_unique<GDALVectorPipelinePassthroughLayer>(
     116             :                         *poSrcLayer));
     117             :             }
     118             :         }
     119             :     }
     120             : 
     121           5 :     if (ret)
     122           5 :         m_outputDataset.Set(std::move(reprojectedDataset));
     123             : 
     124           5 :     return ret;
     125             : }
     126             : 
     127             : //! @endcond

Generated by: LCOV version 1.14