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