Line data Source code
1 : /******************************************************************************
2 : *
3 : * Project: GDAL Core
4 : * Purpose: GDALRasterAttributeTable class declarations.
5 : * Author: Frank Warmerdam, warmerdam@pobox.com
6 : *
7 : ******************************************************************************
8 : * Copyright (c) 2005, Frank Warmerdam <warmerdam@pobox.com>
9 : *
10 : * SPDX-License-Identifier: MIT
11 : ****************************************************************************/
12 :
13 : #ifndef GDAL_RAT_H_INCLUDED
14 : #define GDAL_RAT_H_INCLUDED
15 :
16 : #if !defined(GDAL_COMPILATION) && \
17 : !defined(GDAL_RAT_SKIP_OTHER_GDAL_HEADERS) && !defined(GDAL_4_0_COMPAT)
18 :
19 : #include "cpl_minixml.h"
20 : #include "gdal_priv.h"
21 :
22 : #else
23 :
24 : #include "cpl_port.h"
25 : #include "cpl_error.h"
26 : #include "cpl_string.h"
27 : #include "gdal.h"
28 :
29 : #endif
30 :
31 : #include <memory>
32 : #include <vector>
33 :
34 : class GDALColorTable;
35 :
36 : // Clone and Serialize are allowed to fail if GetRowCount()*GetColCount()
37 : // greater than this number
38 : #define RAT_MAX_ELEM_FOR_CLONE 1000000
39 :
40 : /************************************************************************/
41 : /* GDALRasterAttributeTable */
42 : /************************************************************************/
43 :
44 : //! Raster Attribute Table interface.
45 : class GDALDefaultRasterAttributeTable;
46 :
47 1202 : class CPL_DLL GDALRasterAttributeTable
48 : {
49 : public:
50 : virtual ~GDALRasterAttributeTable();
51 : /**
52 : * \brief Copy Raster Attribute Table
53 : *
54 : * Creates a new copy of an existing raster attribute table. The new copy
55 : * becomes the responsibility of the caller to destroy.
56 : * May fail (return nullptr) if the attribute table is too large to clone
57 : * (GetRowCount() * GetColCount() > RAT_MAX_ELEM_FOR_CLONE)
58 : *
59 : * This method is the same as the C function GDALRATClone().
60 : *
61 : * @return new copy of the RAT as an in-memory implementation.
62 : */
63 : virtual GDALRasterAttributeTable *Clone() const = 0;
64 :
65 : /**
66 : * \brief Fetch table column count.
67 : *
68 : * This method is the same as the C function GDALRATGetColumnCount().
69 : *
70 : * @return the number of columns.
71 : */
72 : virtual int GetColumnCount() const = 0;
73 :
74 : /**
75 : * \brief Fetch name of indicated column.
76 : *
77 : * This method is the same as the C function GDALRATGetNameOfCol().
78 : *
79 : * @param iCol the column index (zero based).
80 : *
81 : * @return the column name or an empty string for invalid column numbers.
82 : */
83 : virtual const char *GetNameOfCol(int iCol) const = 0;
84 :
85 : /**
86 : * \brief Fetch column usage value.
87 : *
88 : * This method is the same as the C function GDALRATGetUsageOfCol().
89 : *
90 : * @param iCol the column index (zero based).
91 : *
92 : * @return the column usage, or GFU_Generic for improper column numbers.
93 : */
94 : virtual GDALRATFieldUsage GetUsageOfCol(int iCol) const = 0;
95 :
96 : /**
97 : * \brief Fetch column type.
98 : *
99 : * This method is the same as the C function GDALRATGetTypeOfCol().
100 : *
101 : * @param iCol the column index (zero based).
102 : *
103 : * @return column type or GFT_Integer if the column index is illegal.
104 : */
105 : virtual GDALRATFieldType GetTypeOfCol(int iCol) const = 0;
106 :
107 : /**
108 : * \brief Fetch column index for given usage.
109 : *
110 : * Returns the index of the first column of the requested usage type, or -1
111 : * if no match is found.
112 : *
113 : * This method is the same as the C function GDALRATGetUsageOfCol().
114 : *
115 : * @param eUsage usage type to search for.
116 : *
117 : * @return column index, or -1 on failure.
118 : */
119 : virtual int GetColOfUsage(GDALRATFieldUsage eUsage) const = 0;
120 :
121 : /**
122 : * \brief Fetch row count.
123 : *
124 : * This method is the same as the C function GDALRATGetRowCount().
125 : *
126 : * @return the number of rows.
127 : */
128 : virtual int GetRowCount() const = 0;
129 :
130 : /**
131 : * \brief Fetch field value as a string.
132 : *
133 : * The value of the requested column in the requested row is returned
134 : * as a string. If the field is numeric, it is formatted as a string
135 : * using default rules, so some precision may be lost.
136 : *
137 : * The returned string is temporary and cannot be expected to be
138 : * available after the next GDAL call.
139 : *
140 : * This method is the same as the C function GDALRATGetValueAsString().
141 : *
142 : * @param iRow row to fetch (zero based).
143 : * @param iField column to fetch (zero based).
144 : *
145 : * @return field value.
146 : */
147 : virtual const char *GetValueAsString(int iRow, int iField) const = 0;
148 :
149 : /**
150 : * \brief Fetch field value as a integer.
151 : *
152 : * The value of the requested column in the requested row is returned
153 : * as an integer. Non-integer fields will be converted to integer with
154 : * the possibility of data loss.
155 : *
156 : * This method is the same as the C function GDALRATGetValueAsInt().
157 : *
158 : * @param iRow row to fetch (zero based).
159 : * @param iField column to fetch (zero based).
160 : *
161 : * @return field value
162 : */
163 : virtual int GetValueAsInt(int iRow, int iField) const = 0;
164 :
165 : /**
166 : * \brief Fetch field value as a double.
167 : *
168 : * The value of the requested column in the requested row is returned
169 : * as a double. Non double fields will be converted to double with
170 : * the possibility of data loss.
171 : *
172 : * This method is the same as the C function GDALRATGetValueAsDouble().
173 : *
174 : * @param iRow row to fetch (zero based).
175 : * @param iField column to fetch (zero based).
176 : *
177 : * @return field value
178 : */
179 : virtual double GetValueAsDouble(int iRow, int iField) const = 0;
180 :
181 : /**
182 : * \brief Set field value from string.
183 : *
184 : * The indicated field (column) on the indicated row is set from the
185 : * passed value. The value will be automatically converted for other field
186 : * types, with a possible loss of precision.
187 : *
188 : * This method is the same as the C function GDALRATSetValueAsString().
189 : *
190 : * @param iRow row to fetch (zero based).
191 : * @param iField column to fetch (zero based).
192 : * @param pszValue the value to assign.
193 : * @return (since 3.12) CE_None in case of success, error code otherwise
194 : */
195 : virtual CPLErr SetValue(int iRow, int iField, const char *pszValue) = 0;
196 :
197 : /**
198 : * \brief Set field value from integer.
199 : *
200 : * The indicated field (column) on the indicated row is set from the
201 : * passed value. The value will be automatically converted for other field
202 : * types, with a possible loss of precision.
203 : *
204 : * This method is the same as the C function GDALRATSetValueAsInteger().
205 : *
206 : * @param iRow row to fetch (zero based).
207 : * @param iField column to fetch (zero based).
208 : * @param nValue the value to assign.
209 : * @return (since 3.12) CE_None in case of success, error code otherwise
210 : */
211 : virtual CPLErr SetValue(int iRow, int iField, int nValue) = 0;
212 :
213 : /**
214 : * \brief Set field value from double.
215 : *
216 : * The indicated field (column) on the indicated row is set from the
217 : * passed value. The value will be automatically converted for other field
218 : * types, with a possible loss of precision.
219 : *
220 : * This method is the same as the C function GDALRATSetValueAsDouble().
221 : *
222 : * @param iRow row to fetch (zero based).
223 : * @param iField column to fetch (zero based).
224 : * @param dfValue the value to assign.
225 : * @return (since 3.12) CE_None in case of success, error code otherwise
226 : */
227 : virtual CPLErr SetValue(int iRow, int iField, double dfValue) = 0;
228 :
229 : /**
230 : * \brief Determine whether changes made to this RAT are reflected directly
231 : * in the dataset
232 : *
233 : * If this returns FALSE then GDALRasterBand.SetDefaultRAT() should be
234 : * called. Otherwise this is unnecessary since changes to this object are
235 : * reflected in the dataset.
236 : *
237 : * This method is the same as the C function
238 : * GDALRATChangesAreWrittenToFile().
239 : *
240 : */
241 : virtual int ChangesAreWrittenToFile() = 0;
242 :
243 : /**
244 : * \brief Set the RAT table type.
245 : *
246 : * Set whether the RAT is thematic or athematic (continuous).
247 : *
248 : */
249 : virtual CPLErr SetTableType(const GDALRATTableType eInTableType) = 0;
250 :
251 : /**
252 : * \brief Get the RAT table type.
253 : *
254 : * Indicates whether the RAT is thematic or athematic (continuous).
255 : *
256 : * @return table type
257 : */
258 : virtual GDALRATTableType GetTableType() const = 0;
259 :
260 : virtual CPLErr ValuesIO(GDALRWFlag eRWFlag, int iField, int iStartRow,
261 : int iLength, double *pdfData);
262 : virtual CPLErr ValuesIO(GDALRWFlag eRWFlag, int iField, int iStartRow,
263 : int iLength, int *pnData);
264 : virtual CPLErr ValuesIO(GDALRWFlag eRWFlag, int iField, int iStartRow,
265 : int iLength, char **papszStrList);
266 :
267 : virtual void SetRowCount(int iCount);
268 : virtual int GetRowOfValue(double dfValue) const;
269 : virtual int GetRowOfValue(int nValue) const;
270 :
271 : virtual CPLErr CreateColumn(const char *pszFieldName,
272 : GDALRATFieldType eFieldType,
273 : GDALRATFieldUsage eFieldUsage);
274 : virtual CPLErr SetLinearBinning(double dfRow0Min, double dfBinSize);
275 : virtual int GetLinearBinning(double *pdfRow0Min, double *pdfBinSize) const;
276 :
277 : /**
278 : * \brief Serialize
279 : *
280 : * May fail (return nullptr) if the attribute table is too large to
281 : * serialize (GetRowCount() * GetColCount() > RAT_MAX_ELEM_FOR_CLONE)
282 : */
283 : virtual CPLXMLNode *Serialize() const;
284 : virtual void *SerializeJSON() const;
285 : virtual CPLErr XMLInit(const CPLXMLNode *, const char *);
286 :
287 : virtual CPLErr InitializeFromColorTable(const GDALColorTable *);
288 : virtual GDALColorTable *TranslateToColorTable(int nEntryCount = -1);
289 :
290 : virtual void DumpReadable(FILE * = nullptr);
291 :
292 : /** Convert a GDALRasterAttributeTable* to a GDALRasterAttributeTableH.
293 : */
294 : static inline GDALRasterAttributeTableH
295 1134 : ToHandle(GDALRasterAttributeTable *poRAT)
296 : {
297 1134 : return static_cast<GDALRasterAttributeTableH>(poRAT);
298 : }
299 :
300 : /** Convert a GDALRasterAttributeTableH to a GDALRasterAttributeTable*.
301 : */
302 : static inline GDALRasterAttributeTable *
303 1446 : FromHandle(GDALRasterAttributeTableH hRAT)
304 : {
305 1446 : return static_cast<GDALRasterAttributeTable *>(hRAT);
306 : }
307 :
308 : /**
309 : * \brief Remove statistics from the RAT.
310 : *
311 : */
312 : virtual void RemoveStatistics() = 0;
313 :
314 : protected:
315 : //! @cond Doxygen_Suppress
316 1184 : GDALRasterAttributeTable() = default;
317 18 : GDALRasterAttributeTable(const GDALRasterAttributeTable &) = default;
318 : GDALRasterAttributeTable &
319 : operator=(const GDALRasterAttributeTable &) = default;
320 : GDALRasterAttributeTable(GDALRasterAttributeTable &&) = default;
321 : GDALRasterAttributeTable &operator=(GDALRasterAttributeTable &&) = default;
322 : //! @endcond
323 : };
324 :
325 : /************************************************************************/
326 : /* GDALDefaultRasterAttributeTable */
327 : /************************************************************************/
328 :
329 : //! Raster Attribute Table container.
330 :
331 1296 : class CPL_DLL GDALDefaultRasterAttributeTable : public GDALRasterAttributeTable
332 : {
333 : private:
334 : struct GDALRasterAttributeField
335 : {
336 : CPLString sName{};
337 :
338 : GDALRATFieldType eType = GFT_Integer;
339 :
340 : GDALRATFieldUsage eUsage = GFU_Generic;
341 :
342 : std::vector<GInt32> anValues{};
343 : std::vector<double> adfValues{};
344 : std::vector<CPLString> aosValues{};
345 : };
346 :
347 : std::vector<GDALRasterAttributeField> aoFields{};
348 :
349 : int bLinearBinning = false; // TODO(schwehr): Can this be a bool?
350 : double dfRow0Min = -0.5;
351 : double dfBinSize = 1.0;
352 :
353 : GDALRATTableType eTableType = GRTT_THEMATIC;
354 :
355 : void AnalyseColumns();
356 : int bColumnsAnalysed = false; // TODO(schwehr): Can this be a bool?
357 : int nMinCol = -1;
358 : int nMaxCol = -1;
359 :
360 : int nRowCount = 0;
361 :
362 : CPLString osWorkingResult{};
363 :
364 : public:
365 : GDALDefaultRasterAttributeTable();
366 : ~GDALDefaultRasterAttributeTable() override;
367 :
368 : //! @cond Doxygen_Suppress
369 18 : GDALDefaultRasterAttributeTable(const GDALDefaultRasterAttributeTable &) =
370 : default;
371 : GDALDefaultRasterAttributeTable &
372 : operator=(const GDALDefaultRasterAttributeTable &) = default;
373 : GDALDefaultRasterAttributeTable(GDALDefaultRasterAttributeTable &&) =
374 : default;
375 : GDALDefaultRasterAttributeTable &
376 : operator=(GDALDefaultRasterAttributeTable &&) = default;
377 : //! @endcond
378 :
379 : GDALDefaultRasterAttributeTable *Clone() const override;
380 :
381 : int GetColumnCount() const override;
382 :
383 : const char *GetNameOfCol(int) const override;
384 : GDALRATFieldUsage GetUsageOfCol(int) const override;
385 : GDALRATFieldType GetTypeOfCol(int) const override;
386 :
387 : int GetColOfUsage(GDALRATFieldUsage) const override;
388 :
389 : int GetRowCount() const override;
390 :
391 : const char *GetValueAsString(int iRow, int iField) const override;
392 : int GetValueAsInt(int iRow, int iField) const override;
393 : double GetValueAsDouble(int iRow, int iField) const override;
394 :
395 : CPLErr SetValue(int iRow, int iField, const char *pszValue) override;
396 : CPLErr SetValue(int iRow, int iField, double dfValue) override;
397 : CPLErr SetValue(int iRow, int iField, int nValue) override;
398 :
399 : int ChangesAreWrittenToFile() override;
400 : void SetRowCount(int iCount) override;
401 :
402 : int GetRowOfValue(double dfValue) const override;
403 : int GetRowOfValue(int nValue) const override;
404 :
405 : CPLErr CreateColumn(const char *pszFieldName, GDALRATFieldType eFieldType,
406 : GDALRATFieldUsage eFieldUsage) override;
407 : CPLErr SetLinearBinning(double dfRow0Min, double dfBinSize) override;
408 : int GetLinearBinning(double *pdfRow0Min, double *pdfBinSize) const override;
409 :
410 : CPLErr SetTableType(const GDALRATTableType eInTableType) override;
411 : GDALRATTableType GetTableType() const override;
412 :
413 : void RemoveStatistics() override;
414 : };
415 :
416 : std::unique_ptr<GDALRasterAttributeTable>
417 : CPL_DLL GDALLoadVATDBF(const char *pszFilename);
418 :
419 : #endif /* ndef GDAL_RAT_H_INCLUDED */
|