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