Line data Source code
1 : /****************************************************************************** 2 : * 3 : * Project: GDAL 4 : * Purpose: "slope" step of "raster pipeline" 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 : #include "gdalalg_raster_slope.h" 14 : 15 : #include "gdal_priv.h" 16 : #include "gdal_utils.h" 17 : 18 : #include <cmath> 19 : 20 : //! @cond Doxygen_Suppress 21 : 22 : #ifndef _ 23 : #define _(x) (x) 24 : #endif 25 : 26 : /************************************************************************/ 27 : /* GDALRasterSlopeAlgorithm::GDALRasterSlopeAlgorithm() */ 28 : /************************************************************************/ 29 : 30 38 : GDALRasterSlopeAlgorithm::GDALRasterSlopeAlgorithm(bool standaloneStep) 31 : : GDALRasterPipelineStepAlgorithm(NAME, DESCRIPTION, HELP_URL, 32 38 : standaloneStep) 33 : { 34 38 : SetOutputVRTCompatible(false); 35 : 36 38 : AddBandArg(&m_band).SetDefault(m_band); 37 76 : AddArg("unit", 0, _("Unit in which to express slopes"), &m_unit) 38 38 : .SetChoices("degree", "percent") 39 38 : .SetDefault(m_unit); 40 : AddArg("xscale", 0, _("Ratio of vertical units to horizontal X axis units"), 41 76 : &m_xscale) 42 38 : .SetMinValueExcluded(0); 43 : AddArg("yscale", 0, _("Ratio of vertical units to horizontal Y axis units"), 44 76 : &m_yscale) 45 38 : .SetMinValueExcluded(0); 46 : AddArg("gradient-alg", 0, _("Algorithm used to compute terrain gradient"), 47 76 : &m_gradientAlg) 48 38 : .SetChoices("Horn", "ZevenbergenThorne") 49 38 : .SetDefault(m_gradientAlg); 50 : AddArg("no-edges", 0, 51 : _("Do not try to interpolate values at dataset edges or close to " 52 : "nodata values"), 53 38 : &m_noEdges); 54 38 : } 55 : 56 : /************************************************************************/ 57 : /* GDALRasterSlopeAlgorithm::RunStep() */ 58 : /************************************************************************/ 59 : 60 11 : bool GDALRasterSlopeAlgorithm::RunStep(GDALPipelineStepRunContext &) 61 : { 62 11 : const auto poSrcDS = m_inputDataset[0].GetDatasetRef(); 63 11 : CPLAssert(poSrcDS); 64 11 : CPLAssert(m_outputDataset.GetName().empty()); 65 11 : CPLAssert(!m_outputDataset.GetDatasetRef()); 66 : 67 22 : CPLStringList aosOptions; 68 11 : aosOptions.AddString("-of"); 69 11 : aosOptions.AddString("stream"); 70 11 : aosOptions.AddString("-b"); 71 11 : aosOptions.AddString(CPLSPrintf("%d", m_band)); 72 11 : if (!std::isnan(m_xscale)) 73 : { 74 2 : aosOptions.AddString("-xscale"); 75 2 : aosOptions.AddString(CPLSPrintf("%.17g", m_xscale)); 76 : } 77 11 : if (!std::isnan(m_yscale)) 78 : { 79 2 : aosOptions.AddString("-yscale"); 80 2 : aosOptions.AddString(CPLSPrintf("%.17g", m_yscale)); 81 : } 82 11 : if (m_unit == "percent") 83 1 : aosOptions.AddString("-p"); 84 11 : aosOptions.AddString("-alg"); 85 11 : aosOptions.AddString(m_gradientAlg.c_str()); 86 : 87 11 : if (!m_noEdges) 88 9 : aosOptions.AddString("-compute_edges"); 89 : 90 : GDALDEMProcessingOptions *psOptions = 91 11 : GDALDEMProcessingOptionsNew(aosOptions.List(), nullptr); 92 : 93 : auto poOutDS = std::unique_ptr<GDALDataset>(GDALDataset::FromHandle( 94 : GDALDEMProcessing("", GDALDataset::ToHandle(poSrcDS), "slope", nullptr, 95 11 : psOptions, nullptr))); 96 11 : GDALDEMProcessingOptionsFree(psOptions); 97 11 : const bool bRet = poOutDS != nullptr; 98 11 : if (poOutDS) 99 : { 100 11 : m_outputDataset.Set(std::move(poOutDS)); 101 : } 102 : 103 22 : return bRet; 104 : } 105 : 106 : GDALRasterSlopeAlgorithmStandalone::~GDALRasterSlopeAlgorithmStandalone() = 107 : default; 108 : 109 : //! @endcond