LCOV - code coverage report
Current view: top level - apps - gdalalg_raster_reproject.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 134 143 93.7 %
Date: 2025-05-15 13:16:46 Functions: 4 6 66.7 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  GDAL
       4             :  * Purpose:  "reproject" step of "raster 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_raster_reproject.h"
      14             : 
      15             : #include "gdal_alg.h"
      16             : #include "gdal_priv.h"
      17             : #include "gdal_utils.h"
      18             : #include "gdalwarper.h"
      19             : 
      20             : #include <cmath>
      21             : 
      22             : //! @cond Doxygen_Suppress
      23             : 
      24             : #ifndef _
      25             : #define _(x) (x)
      26             : #endif
      27             : 
      28             : /************************************************************************/
      29             : /*      GDALRasterReprojectAlgorithm::GDALRasterReprojectAlgorithm()    */
      30             : /************************************************************************/
      31             : 
      32          46 : GDALRasterReprojectAlgorithm::GDALRasterReprojectAlgorithm(bool standaloneStep)
      33             :     : GDALRasterPipelineStepAlgorithm(NAME, DESCRIPTION, HELP_URL,
      34          46 :                                       standaloneStep)
      35             : {
      36          92 :     AddArg("src-crs", 's', _("Source CRS"), &m_srsCrs)
      37          92 :         .SetIsCRSArg()
      38          46 :         .AddHiddenAlias("s_srs");
      39          92 :     AddArg("dst-crs", 'd', _("Destination CRS"), &m_dstCrs)
      40          92 :         .SetIsCRSArg()
      41          46 :         .AddHiddenAlias("t_srs");
      42          92 :     AddArg("resampling", 'r', _("Resampling method"), &m_resampling)
      43             :         .SetChoices("nearest", "bilinear", "cubic", "cubicspline", "lanczos",
      44             :                     "average", "rms", "mode", "min", "max", "med", "q1", "q3",
      45          46 :                     "sum")
      46          46 :         .SetDefault("nearest")
      47          46 :         .SetHiddenChoices("near");
      48             : 
      49             :     AddArg("resolution", 0, _("Target resolution (in destination CRS units)"),
      50          92 :            &m_resolution)
      51          46 :         .SetMinCount(2)
      52          46 :         .SetMaxCount(2)
      53          46 :         .SetMinValueExcluded(0)
      54          46 :         .SetRepeatedArgAllowed(false)
      55          46 :         .SetDisplayHintAboutRepetition(false)
      56          92 :         .SetMetaVar("<xres>,<yres>")
      57          46 :         .SetMutualExclusionGroup("resolution-size");
      58             : 
      59          92 :     AddArg("size", 0, _("Target size in pixels"), &m_size)
      60          46 :         .SetMinCount(2)
      61          46 :         .SetMaxCount(2)
      62          46 :         .SetMinValueIncluded(0)
      63          46 :         .SetRepeatedArgAllowed(false)
      64          46 :         .SetDisplayHintAboutRepetition(false)
      65          92 :         .SetMetaVar("<width>,<height>")
      66          46 :         .SetMutualExclusionGroup("resolution-size");
      67             : 
      68          46 :     AddBBOXArg(&m_bbox, _("Target bounding box (in destination CRS units)"));
      69          92 :     AddArg("bbox-crs", 0, _("CRS of target bounding box"), &m_bboxCrs)
      70          92 :         .SetIsCRSArg()
      71          46 :         .AddHiddenAlias("bbox_srs");
      72             : 
      73             :     AddArg("target-aligned-pixels", 0,
      74             :            _("Round target extent to target resolution"),
      75          92 :            &m_targetAlignedPixels)
      76          92 :         .AddHiddenAlias("tap")
      77          46 :         .SetCategory(GAAC_ADVANCED);
      78             :     AddArg("src-nodata", 0,
      79             :            _("Set nodata values for input bands ('None' to unset)."),
      80          92 :            &m_srcNoData)
      81          46 :         .SetMinCount(1)
      82          46 :         .SetRepeatedArgAllowed(false)
      83          46 :         .SetCategory(GAAC_ADVANCED);
      84             :     AddArg("dst-nodata", 0,
      85             :            _("Set nodata values for output bands ('None' to unset)."),
      86          92 :            &m_dstNoData)
      87          46 :         .SetMinCount(1)
      88          46 :         .SetRepeatedArgAllowed(false)
      89          46 :         .SetCategory(GAAC_ADVANCED);
      90             :     AddArg("add-alpha", 0,
      91             :            _("Adds an alpha mask band to the destination when the source "
      92             :              "raster have none."),
      93          92 :            &m_addAlpha)
      94          46 :         .SetCategory(GAAC_ADVANCED);
      95             :     {
      96             :         auto &arg =
      97          92 :             AddArg("warp-option", 0, _("Warping option(s)"), &m_warpOptions)
      98          92 :                 .AddAlias("wo")
      99          92 :                 .SetMetaVar("<NAME>=<VALUE>")
     100          92 :                 .SetCategory(GAAC_ADVANCED)
     101          46 :                 .SetPackedValuesAllowed(false);
     102           1 :         arg.AddValidationAction([this, &arg]()
     103          47 :                                 { return ParseAndValidateKeyValue(arg); });
     104             :         arg.SetAutoCompleteFunction(
     105           0 :             [](const std::string &currentValue)
     106             :             {
     107           0 :                 std::vector<std::string> ret;
     108           0 :                 GDALAlgorithm::AddOptionsSuggestions(GDALWarpGetOptionList(), 0,
     109             :                                                      currentValue, ret);
     110           0 :                 return ret;
     111          46 :             });
     112             :     }
     113             :     {
     114             :         auto &arg = AddArg("transform-option", 0, _("Transform option(s)"),
     115          92 :                            &m_transformOptions)
     116          92 :                         .AddAlias("to")
     117          92 :                         .SetMetaVar("<NAME>=<VALUE>")
     118          92 :                         .SetCategory(GAAC_ADVANCED)
     119          46 :                         .SetPackedValuesAllowed(false);
     120           1 :         arg.AddValidationAction([this, &arg]()
     121          47 :                                 { return ParseAndValidateKeyValue(arg); });
     122             :         arg.SetAutoCompleteFunction(
     123           0 :             [](const std::string &currentValue)
     124             :             {
     125           0 :                 std::vector<std::string> ret;
     126           0 :                 GDALAlgorithm::AddOptionsSuggestions(
     127             :                     GDALGetGenImgProjTranformerOptionList(), 0, currentValue,
     128             :                     ret);
     129           0 :                 return ret;
     130          46 :             });
     131             :     }
     132          92 :     AddArg("error-threshold", 0, _("Error threshold"), &m_errorThreshold)
     133          92 :         .AddAlias("et")
     134          46 :         .SetCategory(GAAC_ADVANCED);
     135          46 : }
     136             : 
     137             : /************************************************************************/
     138             : /*            GDALRasterReprojectAlgorithm::RunStep()                   */
     139             : /************************************************************************/
     140             : 
     141          16 : bool GDALRasterReprojectAlgorithm::RunStep(GDALProgressFunc, void *)
     142             : {
     143          16 :     CPLAssert(m_inputDataset.GetDatasetRef());
     144          16 :     CPLAssert(m_outputDataset.GetName().empty());
     145          16 :     CPLAssert(!m_outputDataset.GetDatasetRef());
     146             : 
     147          32 :     CPLStringList aosOptions;
     148          16 :     aosOptions.AddString("-of");
     149          16 :     aosOptions.AddString("VRT");
     150          16 :     if (!m_srsCrs.empty())
     151             :     {
     152           5 :         aosOptions.AddString("-s_srs");
     153           5 :         aosOptions.AddString(m_srsCrs.c_str());
     154             :     }
     155          16 :     if (!m_dstCrs.empty())
     156             :     {
     157           8 :         aosOptions.AddString("-t_srs");
     158           8 :         aosOptions.AddString(m_dstCrs.c_str());
     159             :     }
     160          16 :     if (!m_resampling.empty())
     161             :     {
     162          16 :         aosOptions.AddString("-r");
     163          16 :         aosOptions.AddString(m_resampling.c_str());
     164             :     }
     165          16 :     if (!m_resolution.empty())
     166             :     {
     167           1 :         aosOptions.AddString("-tr");
     168           1 :         aosOptions.AddString(CPLSPrintf("%.17g", m_resolution[0]));
     169           1 :         aosOptions.AddString(CPLSPrintf("%.17g", m_resolution[1]));
     170             :     }
     171          16 :     if (!m_size.empty())
     172             :     {
     173           1 :         aosOptions.AddString("-ts");
     174           1 :         aosOptions.AddString(CPLSPrintf("%d", m_size[0]));
     175           1 :         aosOptions.AddString(CPLSPrintf("%d", m_size[1]));
     176             :     }
     177          16 :     if (!m_bbox.empty())
     178             :     {
     179           2 :         aosOptions.AddString("-te");
     180           2 :         aosOptions.AddString(CPLSPrintf("%.17g", m_bbox[0]));
     181           2 :         aosOptions.AddString(CPLSPrintf("%.17g", m_bbox[1]));
     182           2 :         aosOptions.AddString(CPLSPrintf("%.17g", m_bbox[2]));
     183           2 :         aosOptions.AddString(CPLSPrintf("%.17g", m_bbox[3]));
     184             :     }
     185          16 :     if (!m_bboxCrs.empty())
     186             :     {
     187           1 :         aosOptions.AddString("-te_srs");
     188           1 :         aosOptions.AddString(m_bboxCrs.c_str());
     189             :     }
     190          16 :     if (m_targetAlignedPixels)
     191             :     {
     192           1 :         aosOptions.AddString("-tap");
     193             :     }
     194          16 :     if (!m_srcNoData.empty())
     195             :     {
     196           1 :         aosOptions.push_back("-srcnodata");
     197           2 :         std::string s;
     198           2 :         for (const std::string &v : m_srcNoData)
     199             :         {
     200           1 :             if (!s.empty())
     201           0 :                 s += " ";
     202           1 :             s += v;
     203             :         }
     204           1 :         aosOptions.push_back(s);
     205             :     }
     206          16 :     if (!m_dstNoData.empty())
     207             :     {
     208           2 :         aosOptions.push_back("-dstnodata");
     209           4 :         std::string s;
     210           5 :         for (const std::string &v : m_dstNoData)
     211             :         {
     212           3 :             if (!s.empty())
     213           1 :                 s += " ";
     214           3 :             s += v;
     215             :         }
     216           2 :         aosOptions.push_back(s);
     217             :     }
     218          16 :     if (m_addAlpha)
     219             :     {
     220           1 :         aosOptions.AddString("-dstalpha");
     221             :     }
     222          17 :     for (const std::string &opt : m_warpOptions)
     223             :     {
     224           1 :         aosOptions.AddString("-wo");
     225           1 :         aosOptions.AddString(opt.c_str());
     226             :     }
     227          17 :     for (const std::string &opt : m_transformOptions)
     228             :     {
     229           1 :         aosOptions.AddString("-to");
     230           1 :         aosOptions.AddString(opt.c_str());
     231             :     }
     232          16 :     if (std::isfinite(m_errorThreshold))
     233             :     {
     234           1 :         aosOptions.AddString("-et");
     235           1 :         aosOptions.AddString(CPLSPrintf("%.17g", m_errorThreshold));
     236             :     }
     237             : 
     238             :     GDALWarpAppOptions *psOptions =
     239          16 :         GDALWarpAppOptionsNew(aosOptions.List(), nullptr);
     240             : 
     241          16 :     GDALDatasetH hSrcDS = GDALDataset::ToHandle(m_inputDataset.GetDatasetRef());
     242          16 :     auto poRetDS = GDALDataset::FromHandle(
     243             :         GDALWarp("", nullptr, 1, &hSrcDS, psOptions, nullptr));
     244          16 :     GDALWarpAppOptionsFree(psOptions);
     245          16 :     if (!poRetDS)
     246           3 :         return false;
     247             : 
     248          13 :     m_outputDataset.Set(std::unique_ptr<GDALDataset>(poRetDS));
     249             : 
     250          13 :     return true;
     251             : }
     252             : 
     253             : //! @endcond

Generated by: LCOV version 1.14