GDAL
gdal_computedrasterband.h
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
38class CPL_DLL GDALComputedRasterBand final : public GDALRasterBand
39{
40 public:
42 ~GDALComputedRasterBand() override;
43
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
89
90 double GetNoDataValue(int *pbSuccess = nullptr) override;
91
94 static inline GDALComputedRasterBandH
95 ToHandle(GDALComputedRasterBand *poBand)
96 {
97 return static_cast<GDALComputedRasterBandH>(poBand);
98 }
99
102 static inline GDALComputedRasterBand *
104 {
105 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
131namespace gdal
132{
133using std::abs;
134GDALComputedRasterBand CPL_DLL abs(const GDALRasterBand &band);
135
136using std::fabs;
137GDALComputedRasterBand CPL_DLL fabs(const GDALRasterBand &band);
138
139using std::sqrt;
140GDALComputedRasterBand CPL_DLL sqrt(const GDALRasterBand &band);
141
142using std::log;
143GDALComputedRasterBand CPL_DLL log(const GDALRasterBand &band);
144
145using std::log10;
146GDALComputedRasterBand CPL_DLL log10(const GDALRasterBand &band);
147
148using std::pow;
149GDALComputedRasterBand CPL_DLL pow(const GDALRasterBand &band, double constant);
150#ifndef DOXYGEN_SKIP
151GDALComputedRasterBand CPL_DLL pow(double constant, const GDALRasterBand &band);
152GDALComputedRasterBand CPL_DLL pow(const GDALRasterBand &band1,
153 const GDALRasterBand &band2);
154#endif
155
156GDALComputedRasterBand CPL_DLL IfThenElse(const GDALRasterBand &condBand,
157 const GDALRasterBand &thenBand,
158 const GDALRasterBand &elseBand);
159
161
162GDALComputedRasterBand CPL_DLL IfThenElse(const GDALRasterBand &condBand,
163 double thenValue,
164 const GDALRasterBand &elseBand);
165
166GDALComputedRasterBand CPL_DLL IfThenElse(const GDALRasterBand &condBand,
167 const GDALRasterBand &thenBand,
168 double elseValue);
169
170GDALComputedRasterBand CPL_DLL IfThenElse(const GDALRasterBand &condBand,
171 double thenValue, double elseValue);
172
174
175using std::max;
176using std::min;
177
178GDALComputedRasterBand CPL_DLL min(const GDALRasterBand &first,
179 const GDALRasterBand &second);
180
182
183namespace detail
184{
185
186template <typename U, typename Enable> struct minDealFirstArg;
187
188template <typename U>
189struct minDealFirstArg<
190 U, typename std::enable_if<std::is_arithmetic<U>::value>::type>
191{
192 inline static void process(std::vector<const GDALRasterBand *> &,
193 double &constant, const U &first)
194 {
195 if (std::isnan(constant) || static_cast<double>(first) < constant)
196 constant = static_cast<double>(first);
197 }
198};
199
200template <typename U>
201struct minDealFirstArg<
202 U, typename std::enable_if<!std::is_arithmetic<U>::value>::type>
203{
204 inline static void process(std::vector<const GDALRasterBand *> &bands,
205 double &, const U &first)
206 {
207 if (!bands.empty())
208 GDALRasterBand::ThrowIfNotSameDimensions(first, *(bands.front()));
209 bands.push_back(&first);
210 }
211};
212
213inline static GDALComputedRasterBand
214minInternal(std::vector<const GDALRasterBand *> &bands, double constant)
215{
216 return GDALComputedRasterBand(GDALComputedRasterBand::Operation::OP_MIN,
217 bands, constant);
218}
219
220template <typename U, typename... V>
221GDALComputedRasterBand minInternal(std::vector<const GDALRasterBand *> &bands,
222 double constant, const U &first, V &&...rest)
223{
224 minDealFirstArg<U, void>::process(bands, constant, first);
225 return minInternal(bands, constant, std::forward<V>(rest)...);
226}
227
228} // namespace detail
229
230template <typename U, typename... V>
231inline GDALComputedRasterBand min(const U &first, V &&...rest)
232{
233 std::vector<const GDALRasterBand *> bands;
234 return detail::minInternal(bands, std::numeric_limits<double>::quiet_NaN(),
235 first, std::forward<V>(rest)...);
236}
237
239
240GDALComputedRasterBand CPL_DLL max(const GDALRasterBand &first,
241 const GDALRasterBand &second);
242
244
245namespace detail
246{
247
248template <typename U, typename Enable> struct maxDealFirstArg;
249
250template <typename U>
251struct maxDealFirstArg<
252 U, typename std::enable_if<std::is_arithmetic<U>::value>::type>
253{
254 inline static void process(std::vector<const GDALRasterBand *> &,
255 double &constant, const U &first)
256 {
257 if (std::isnan(constant) || static_cast<double>(first) > constant)
258 constant = static_cast<double>(first);
259 }
260};
261
262template <typename U>
263struct maxDealFirstArg<
264 U, typename std::enable_if<!std::is_arithmetic<U>::value>::type>
265{
266 inline static void process(std::vector<const GDALRasterBand *> &bands,
267 double &, const U &first)
268 {
269 if (!bands.empty())
270 GDALRasterBand::ThrowIfNotSameDimensions(first, *(bands.front()));
271 bands.push_back(&first);
272 }
273};
274
275inline static GDALComputedRasterBand
276maxInternal(std::vector<const GDALRasterBand *> &bands, double constant)
277{
278 return GDALComputedRasterBand(GDALComputedRasterBand::Operation::OP_MAX,
279 bands, constant);
280}
281
282template <typename U, typename... V>
283GDALComputedRasterBand maxInternal(std::vector<const GDALRasterBand *> &bands,
284 double constant, const U &first, V &&...rest)
285{
286 maxDealFirstArg<U, void>::process(bands, constant, first);
287 return maxInternal(bands, constant, std::forward<V>(rest)...);
288}
289
290} // namespace detail
291
292template <typename U, typename... V>
293inline GDALComputedRasterBand max(const U &first, V &&...rest)
294{
295 std::vector<const GDALRasterBand *> bands;
296 return detail::maxInternal(bands, std::numeric_limits<double>::quiet_NaN(),
297 first, std::forward<V>(rest)...);
298}
299
301
302GDALComputedRasterBand CPL_DLL mean(const GDALRasterBand &first,
303 const GDALRasterBand &second);
304
306inline GDALComputedRasterBand
307meanInternal(std::vector<const GDALRasterBand *> &bands)
308{
309 return GDALComputedRasterBand(GDALComputedRasterBand::Operation::OP_MEAN,
310 bands);
311}
312
313template <typename U, typename... V>
314inline GDALComputedRasterBand
315meanInternal(std::vector<const GDALRasterBand *> &bands, const U &first,
316 V &&...rest)
317{
318 if (!bands.empty())
319 GDALRasterBand::ThrowIfNotSameDimensions(first, *(bands.front()));
320 bands.push_back(&first);
321 return meanInternal(bands, std::forward<V>(rest)...);
322}
323
324template <typename... Args> inline GDALComputedRasterBand mean(Args &&...args)
325{
326 std::vector<const GDALRasterBand *> bands;
327 return meanInternal(bands, std::forward<Args>(args)...);
328}
329
331
332} // namespace gdal
333
334#endif
Class represented the result of an operation on one or two input bands.
Definition gdal_computedrasterband.h:39
static GDALComputedRasterBand * FromHandle(GDALComputedRasterBandH hBand)
Convert a GDALComputedRasterBandH to a GDALComputedRasterBand*.
Definition gdal_computedrasterband.h:103
static GDALComputedRasterBandH ToHandle(GDALComputedRasterBand *poBand)
Convert a GDALComputedRasterBand* to a GDALComputedRasterBandH.
Definition gdal_computedrasterband.h:95
GDALMajorObject & operator=(const GDALMajorObject &)=default
Copy assignment operator.
A single raster band (or channel).
Definition gdal_rasterband.h:105
virtual CPLErr IReadBlock(int nBlockXOff, int nBlockYOff, void *pData)=0
Default internal implementation ... to be overridden by subclasses that support reading.
virtual CPLErr IRasterIO(GDALRWFlag eRWFlag, int nXOff, int nYOff, int nXSize, int nYSize, void *pData, int nBufXSize, int nBufYSize, GDALDataType eBufType, GSpacing nPixelSpace, GSpacing nLineSpace, GDALRasterIOExtraArg *psExtraArg)
Read/write a region of image data for this band.
Definition rasterio.cpp:223
virtual double GetNoDataValue(int *pbSuccess=nullptr)
Fetch the no data value for this band.
Definition gdalrasterband.cpp:2347
CPLErr
Error category.
Definition cpl_error.h:37
Core portability definitions for CPL.
GIntBig GSpacing
Type to express pixel, line or band spacing.
Definition gdal.h:386
GDALDataType
Definition gdal.h:48
GDALRWFlag
Definition gdal.h:125
void * GDALComputedRasterBandH
Opaque type used for the C bindings of the C++ GDALComputedRasterBand class.
Definition gdal_fwd.h:48
Structure to pass extra arguments to RasterIO() method, must be initialized with INIT_RASTERIO_EXTRA_...
Definition gdal.h:168