LCOV - code coverage report
Current view: top level - gcore - gdal_computedrasterband.h (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 46 46 100.0 %
Date: 2025-10-01 17:07:58 Functions: 35 35 100.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Name:     gdalc_omputedrasterband.h
       4             :  * Project:  GDAL Core
       5             :  * Purpose:  Declaration of GDALComputedRasterBand and related gdal:: methods
       6             :  * Author:   Even Rouault, <even.rouault@spatialys.com>
       7             :  *
       8             :  ******************************************************************************
       9             :  * Copyright (c) 2025, Even Rouault, <even.rouault@spatialys.com>
      10             :  *
      11             :  * SPDX-License-Identifier: MIT
      12             :  ****************************************************************************/
      13             : 
      14             : #ifndef GDALCOMPUTEDRASTERBAND_H_INCLUDED
      15             : #define GDALCOMPUTEDRASTERBAND_H_INCLUDED
      16             : 
      17             : #include "cpl_port.h"
      18             : #include "gdal_dataset.h"  // GDALDatasetUniquePtrReleaser
      19             : #include "gdal_rasterband.h"
      20             : 
      21             : #include <algorithm>
      22             : #include <cmath>
      23             : #include <limits>
      24             : #include <memory>
      25             : #include <vector>
      26             : 
      27             : /* ******************************************************************** */
      28             : /*                       GDALComputedRasterBand                         */
      29             : /* ******************************************************************** */
      30             : 
      31             : /** Class represented the result of an operation on one or two input bands.
      32             :  *
      33             :  * Such class is instantiated only by operators on GDALRasterBand.
      34             :  * The resulting band is lazy evaluated.
      35             :  *
      36             :  * @since 3.12
      37             :  */
      38             : class CPL_DLL GDALComputedRasterBand final : public GDALRasterBand
      39             : {
      40             :   public:
      41             :     /** Destructor */
      42             :     ~GDALComputedRasterBand() override;
      43             : 
      44             :     //! @cond Doxygen_Suppress
      45             :     enum class Operation
      46             :     {
      47             :         OP_ADD,
      48             :         OP_SUBTRACT,
      49             :         OP_MULTIPLY,
      50             :         OP_DIVIDE,
      51             :         OP_MIN,
      52             :         OP_MAX,
      53             :         OP_MEAN,
      54             :         OP_GT,
      55             :         OP_GE,
      56             :         OP_LT,
      57             :         OP_LE,
      58             :         OP_EQ,
      59             :         OP_NE,
      60             :         OP_LOGICAL_AND,
      61             :         OP_LOGICAL_OR,
      62             :         OP_CAST,
      63             :         OP_TERNARY,
      64             :         OP_ABS,
      65             :         OP_SQRT,
      66             :         OP_LOG,
      67             :         OP_LOG10,
      68             :         OP_POW,
      69             :     };
      70             : 
      71             :     GDALComputedRasterBand(
      72             :         Operation op, const std::vector<const GDALRasterBand *> &bands,
      73             :         double constant = std::numeric_limits<double>::quiet_NaN());
      74             :     GDALComputedRasterBand(Operation op, const GDALRasterBand &band);
      75             :     GDALComputedRasterBand(Operation op, double constant,
      76             :                            const GDALRasterBand &band);
      77             :     GDALComputedRasterBand(Operation op, const GDALRasterBand &band,
      78             :                            double constant);
      79             :     GDALComputedRasterBand(Operation op, const GDALRasterBand &band,
      80             :                            GDALDataType dt);
      81             : 
      82             :     // Semi-public for gdal::min(), gdal::max()
      83             :     GDALComputedRasterBand(Operation op, const GDALRasterBand &firstBand,
      84             :                            const GDALRasterBand &secondBand);
      85             : 
      86             :     GDALComputedRasterBand(GDALComputedRasterBand &&) = default;
      87             : 
      88             :     //! @endcond
      89             : 
      90             :     double GetNoDataValue(int *pbSuccess = nullptr) override;
      91             : 
      92             :     /** Convert a GDALComputedRasterBand* to a GDALComputedRasterBandH.
      93             :      */
      94             :     static inline GDALComputedRasterBandH
      95             :     ToHandle(GDALComputedRasterBand *poBand)
      96             :     {
      97             :         return static_cast<GDALComputedRasterBandH>(poBand);
      98             :     }
      99             : 
     100             :     /** Convert a GDALComputedRasterBandH to a GDALComputedRasterBand*.
     101             :      */
     102             :     static inline GDALComputedRasterBand *
     103         163 :     FromHandle(GDALComputedRasterBandH hBand)
     104             :     {
     105         163 :         return static_cast<GDALComputedRasterBand *>(hBand);
     106             :     }
     107             : 
     108             :   protected:
     109             :     friend class GDALRasterBand;
     110             : 
     111             :     CPLErr IReadBlock(int, int, void *) override;
     112             : 
     113             :     CPLErr IRasterIO(GDALRWFlag eRWFlag, int nXOff, int nYOff, int nXSize,
     114             :                      int nYSize, void *pData, int nBufXSize, int nBufYSize,
     115             :                      GDALDataType eBufType, GSpacing nPixelSpace,
     116             :                      GSpacing nLineSpace,
     117             :                      GDALRasterIOExtraArg *psExtraArg) override;
     118             : 
     119             :   private:
     120             :     friend class GDALComputedDataset;
     121             :     std::unique_ptr<GDALDataset, GDALDatasetUniquePtrReleaser> m_poOwningDS{};
     122             :     bool m_bHasNoData{false};
     123             :     double m_dfNoDataValue{0};
     124             : 
     125             :     GDALComputedRasterBand(const GDALComputedRasterBand &, bool);
     126             :     GDALComputedRasterBand(const GDALComputedRasterBand &) = delete;
     127             :     GDALComputedRasterBand &operator=(const GDALComputedRasterBand &) = delete;
     128             :     GDALComputedRasterBand &operator=(GDALComputedRasterBand &&) = delete;
     129             : };
     130             : 
     131             : namespace gdal
     132             : {
     133             : using std::abs;
     134             : GDALComputedRasterBand CPL_DLL abs(const GDALRasterBand &band);
     135             : 
     136             : using std::fabs;
     137             : GDALComputedRasterBand CPL_DLL fabs(const GDALRasterBand &band);
     138             : 
     139             : using std::sqrt;
     140             : GDALComputedRasterBand CPL_DLL sqrt(const GDALRasterBand &band);
     141             : 
     142             : using std::log;
     143             : GDALComputedRasterBand CPL_DLL log(const GDALRasterBand &band);
     144             : 
     145             : using std::log10;
     146             : GDALComputedRasterBand CPL_DLL log10(const GDALRasterBand &band);
     147             : 
     148             : using std::pow;
     149             : GDALComputedRasterBand CPL_DLL pow(const GDALRasterBand &band, double constant);
     150             : #ifndef DOXYGEN_SKIP
     151             : GDALComputedRasterBand CPL_DLL pow(double constant, const GDALRasterBand &band);
     152             : GDALComputedRasterBand CPL_DLL pow(const GDALRasterBand &band1,
     153             :                                    const GDALRasterBand &band2);
     154             : #endif
     155             : 
     156             : GDALComputedRasterBand CPL_DLL IfThenElse(const GDALRasterBand &condBand,
     157             :                                           const GDALRasterBand &thenBand,
     158             :                                           const GDALRasterBand &elseBand);
     159             : 
     160             : //! @cond Doxygen_Suppress
     161             : 
     162             : GDALComputedRasterBand CPL_DLL IfThenElse(const GDALRasterBand &condBand,
     163             :                                           double thenValue,
     164             :                                           const GDALRasterBand &elseBand);
     165             : 
     166             : GDALComputedRasterBand CPL_DLL IfThenElse(const GDALRasterBand &condBand,
     167             :                                           const GDALRasterBand &thenBand,
     168             :                                           double elseValue);
     169             : 
     170             : GDALComputedRasterBand CPL_DLL IfThenElse(const GDALRasterBand &condBand,
     171             :                                           double thenValue, double elseValue);
     172             : 
     173             : //! @endcond
     174             : 
     175             : using std::max;
     176             : using std::min;
     177             : 
     178             : GDALComputedRasterBand CPL_DLL min(const GDALRasterBand &first,
     179             :                                    const GDALRasterBand &second);
     180             : 
     181             : //! @cond Doxygen_Suppress
     182             : 
     183             : namespace detail
     184             : {
     185             : 
     186             : template <typename U, typename Enable> struct minDealFirstArg;
     187             : 
     188             : template <typename U>
     189             : struct minDealFirstArg<
     190             :     U, typename std::enable_if<std::is_arithmetic<U>::value>::type>
     191             : {
     192           2 :     inline static void process(std::vector<const GDALRasterBand *> &,
     193             :                                double &constant, const U &first)
     194             :     {
     195           2 :         if (std::isnan(constant) || static_cast<double>(first) < constant)
     196           2 :             constant = static_cast<double>(first);
     197           2 :     }
     198             : };
     199             : 
     200             : template <typename U>
     201             : struct minDealFirstArg<
     202             :     U, typename std::enable_if<!std::is_arithmetic<U>::value>::type>
     203             : {
     204          16 :     inline static void process(std::vector<const GDALRasterBand *> &bands,
     205             :                                double &, const U &first)
     206             :     {
     207          16 :         if (!bands.empty())
     208          10 :             GDALRasterBand::ThrowIfNotSameDimensions(first, *(bands.front()));
     209          14 :         bands.push_back(&first);
     210          14 :     }
     211             : };
     212             : 
     213             : inline static GDALComputedRasterBand
     214           4 : minInternal(std::vector<const GDALRasterBand *> &bands, double constant)
     215             : {
     216             :     return GDALComputedRasterBand(GDALComputedRasterBand::Operation::OP_MIN,
     217           4 :                                   bands, constant);
     218             : }
     219             : 
     220             : template <typename U, typename... V>
     221          18 : GDALComputedRasterBand minInternal(std::vector<const GDALRasterBand *> &bands,
     222             :                                    double constant, const U &first, V &&...rest)
     223             : {
     224          18 :     minDealFirstArg<U, void>::process(bands, constant, first);
     225          16 :     return minInternal(bands, constant, std::forward<V>(rest)...);
     226             : }
     227             : 
     228             : }  // namespace detail
     229             : 
     230             : template <typename U, typename... V>
     231           6 : inline GDALComputedRasterBand min(const U &first, V &&...rest)
     232             : {
     233          12 :     std::vector<const GDALRasterBand *> bands;
     234             :     return detail::minInternal(bands, std::numeric_limits<double>::quiet_NaN(),
     235          10 :                                first, std::forward<V>(rest)...);
     236             : }
     237             : 
     238             : //! @endcond
     239             : 
     240             : GDALComputedRasterBand CPL_DLL max(const GDALRasterBand &first,
     241             :                                    const GDALRasterBand &second);
     242             : 
     243             : //! @cond Doxygen_Suppress
     244             : 
     245             : namespace detail
     246             : {
     247             : 
     248             : template <typename U, typename Enable> struct maxDealFirstArg;
     249             : 
     250             : template <typename U>
     251             : struct maxDealFirstArg<
     252             :     U, typename std::enable_if<std::is_arithmetic<U>::value>::type>
     253             : {
     254           2 :     inline static void process(std::vector<const GDALRasterBand *> &,
     255             :                                double &constant, const U &first)
     256             :     {
     257           2 :         if (std::isnan(constant) || static_cast<double>(first) > constant)
     258           2 :             constant = static_cast<double>(first);
     259           2 :     }
     260             : };
     261             : 
     262             : template <typename U>
     263             : struct maxDealFirstArg<
     264             :     U, typename std::enable_if<!std::is_arithmetic<U>::value>::type>
     265             : {
     266          14 :     inline static void process(std::vector<const GDALRasterBand *> &bands,
     267             :                                double &, const U &first)
     268             :     {
     269          14 :         if (!bands.empty())
     270           9 :             GDALRasterBand::ThrowIfNotSameDimensions(first, *(bands.front()));
     271          12 :         bands.push_back(&first);
     272          12 :     }
     273             : };
     274             : 
     275             : inline static GDALComputedRasterBand
     276           3 : maxInternal(std::vector<const GDALRasterBand *> &bands, double constant)
     277             : {
     278             :     return GDALComputedRasterBand(GDALComputedRasterBand::Operation::OP_MAX,
     279           3 :                                   bands, constant);
     280             : }
     281             : 
     282             : template <typename U, typename... V>
     283          16 : GDALComputedRasterBand maxInternal(std::vector<const GDALRasterBand *> &bands,
     284             :                                    double constant, const U &first, V &&...rest)
     285             : {
     286          16 :     maxDealFirstArg<U, void>::process(bands, constant, first);
     287          14 :     return maxInternal(bands, constant, std::forward<V>(rest)...);
     288             : }
     289             : 
     290             : }  // namespace detail
     291             : 
     292             : template <typename U, typename... V>
     293           5 : inline GDALComputedRasterBand max(const U &first, V &&...rest)
     294             : {
     295          10 :     std::vector<const GDALRasterBand *> bands;
     296             :     return detail::maxInternal(bands, std::numeric_limits<double>::quiet_NaN(),
     297           8 :                                first, std::forward<V>(rest)...);
     298             : }
     299             : 
     300             : //! @endcond
     301             : 
     302             : GDALComputedRasterBand CPL_DLL mean(const GDALRasterBand &first,
     303             :                                     const GDALRasterBand &second);
     304             : 
     305             : //! @cond Doxygen_Suppress
     306             : inline GDALComputedRasterBand
     307           1 : meanInternal(std::vector<const GDALRasterBand *> &bands)
     308             : {
     309             :     return GDALComputedRasterBand(GDALComputedRasterBand::Operation::OP_MEAN,
     310           1 :                                   bands);
     311             : }
     312             : 
     313             : template <typename U, typename... V>
     314             : inline GDALComputedRasterBand
     315           8 : meanInternal(std::vector<const GDALRasterBand *> &bands, const U &first,
     316             :              V &&...rest)
     317             : {
     318           8 :     if (!bands.empty())
     319           5 :         GDALRasterBand::ThrowIfNotSameDimensions(first, *(bands.front()));
     320           6 :     bands.push_back(&first);
     321           6 :     return meanInternal(bands, std::forward<V>(rest)...);
     322             : }
     323             : 
     324           3 : template <typename... Args> inline GDALComputedRasterBand mean(Args &&...args)
     325             : {
     326           6 :     std::vector<const GDALRasterBand *> bands;
     327           4 :     return meanInternal(bands, std::forward<Args>(args)...);
     328             : }
     329             : 
     330             : //! @endcond
     331             : 
     332             : }  // namespace gdal
     333             : 
     334             : #endif

Generated by: LCOV version 1.14