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 1057 : 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 : */
177 : virtual void SetValue(int iRow, int iField, const char *pszValue) = 0;
178 :
179 : /**
180 : * \brief Set field value from integer.
181 : *
182 : * The indicated field (column) on the indicated row is set from the
183 : * passed value. The value will be automatically converted for other field
184 : * types, with a possible loss of precision.
185 : *
186 : * This method is the same as the C function GDALRATSetValueAsInteger().
187 : *
188 : * @param iRow row to fetch (zero based).
189 : * @param iField column to fetch (zero based).
190 : * @param nValue the value to assign.
191 : */
192 : virtual void SetValue(int iRow, int iField, int nValue) = 0;
193 :
194 : /**
195 : * \brief Set field value from double.
196 : *
197 : * The indicated field (column) on the indicated row is set from the
198 : * passed value. The value will be automatically converted for other field
199 : * types, with a possible loss of precision.
200 : *
201 : * This method is the same as the C function GDALRATSetValueAsDouble().
202 : *
203 : * @param iRow row to fetch (zero based).
204 : * @param iField column to fetch (zero based).
205 : * @param dfValue the value to assign.
206 : */
207 : virtual void SetValue(int iRow, int iField, double dfValue) = 0;
208 :
209 : /**
210 : * \brief Determine whether changes made to this RAT are reflected directly
211 : * in the dataset
212 : *
213 : * If this returns FALSE then GDALRasterBand.SetDefaultRAT() should be
214 : * called. Otherwise this is unnecessary since changes to this object are
215 : * reflected in the dataset.
216 : *
217 : * This method is the same as the C function
218 : * GDALRATChangesAreWrittenToFile().
219 : *
220 : */
221 : virtual int ChangesAreWrittenToFile() = 0;
222 :
223 : /**
224 : * \brief Set the RAT table type.
225 : *
226 : * Set whether the RAT is thematic or athematic (continuous).
227 : *
228 : * @since GDAL 2.4
229 : */
230 : virtual CPLErr SetTableType(const GDALRATTableType eInTableType) = 0;
231 :
232 : /**
233 : * \brief Get the RAT table type.
234 : *
235 : * Indicates whether the RAT is thematic or athematic (continuous).
236 : *
237 : * @since GDAL 2.4
238 : * @return table type
239 : */
240 : virtual GDALRATTableType GetTableType() const = 0;
241 :
242 : virtual CPLErr ValuesIO(GDALRWFlag eRWFlag, int iField, int iStartRow,
243 : int iLength, double *pdfData);
244 : virtual CPLErr ValuesIO(GDALRWFlag eRWFlag, int iField, int iStartRow,
245 : int iLength, int *pnData);
246 : virtual CPLErr ValuesIO(GDALRWFlag eRWFlag, int iField, int iStartRow,
247 : int iLength, char **papszStrList);
248 :
249 : virtual void SetRowCount(int iCount);
250 : virtual int GetRowOfValue(double dfValue) const;
251 : virtual int GetRowOfValue(int nValue) const;
252 :
253 : virtual CPLErr CreateColumn(const char *pszFieldName,
254 : GDALRATFieldType eFieldType,
255 : GDALRATFieldUsage eFieldUsage);
256 : virtual CPLErr SetLinearBinning(double dfRow0Min, double dfBinSize);
257 : virtual int GetLinearBinning(double *pdfRow0Min, double *pdfBinSize) const;
258 :
259 : /**
260 : * \brief Serialize
261 : *
262 : * May fail (return nullptr) if the attribute table is too large to
263 : * serialize (GetRowCount() * GetColCount() > RAT_MAX_ELEM_FOR_CLONE)
264 : */
265 : virtual CPLXMLNode *Serialize() const;
266 : virtual void *SerializeJSON() const;
267 : virtual CPLErr XMLInit(const CPLXMLNode *, const char *);
268 :
269 : virtual CPLErr InitializeFromColorTable(const GDALColorTable *);
270 : virtual GDALColorTable *TranslateToColorTable(int nEntryCount = -1);
271 :
272 : virtual void DumpReadable(FILE * = nullptr);
273 :
274 : /** Convert a GDALRasterAttributeTable* to a GDALRasterAttributeTableH.
275 : * @since GDAL 2.3
276 : */
277 : static inline GDALRasterAttributeTableH
278 985 : ToHandle(GDALRasterAttributeTable *poRAT)
279 : {
280 985 : return static_cast<GDALRasterAttributeTableH>(poRAT);
281 : }
282 :
283 : /** Convert a GDALRasterAttributeTableH to a GDALRasterAttributeTable*.
284 : * @since GDAL 2.3
285 : */
286 : static inline GDALRasterAttributeTable *
287 721 : FromHandle(GDALRasterAttributeTableH hRAT)
288 : {
289 721 : return static_cast<GDALRasterAttributeTable *>(hRAT);
290 : }
291 :
292 : /**
293 : * \brief Remove statistics from the RAT.
294 : *
295 : * @since GDAL 2.4
296 : */
297 : virtual void RemoveStatistics() = 0;
298 : };
299 :
300 : /************************************************************************/
301 : /* GDALRasterAttributeField */
302 : /* */
303 : /* (private) */
304 : /************************************************************************/
305 : //! @cond Doxygen_Suppress
306 : class GDALRasterAttributeField
307 : {
308 : public:
309 : CPLString sName{};
310 :
311 : GDALRATFieldType eType = GFT_Integer;
312 :
313 : GDALRATFieldUsage eUsage = GFU_Generic;
314 :
315 : std::vector<GInt32> anValues{};
316 : std::vector<double> adfValues{};
317 : std::vector<CPLString> aosValues{};
318 : };
319 :
320 : //! @endcond
321 :
322 : /************************************************************************/
323 : /* GDALDefaultRasterAttributeTable */
324 : /************************************************************************/
325 :
326 : //! Raster Attribute Table container.
327 :
328 518 : class CPL_DLL GDALDefaultRasterAttributeTable : public GDALRasterAttributeTable
329 : {
330 : private:
331 : std::vector<GDALRasterAttributeField> aoFields{};
332 :
333 : int bLinearBinning = false; // TODO(schwehr): Can this be a bool?
334 : double dfRow0Min = -0.5;
335 : double dfBinSize = 1.0;
336 :
337 : GDALRATTableType eTableType;
338 :
339 : void AnalyseColumns();
340 : int bColumnsAnalysed = false; // TODO(schwehr): Can this be a bool?
341 : int nMinCol = -1;
342 : int nMaxCol = -1;
343 :
344 : int nRowCount = 0;
345 :
346 : CPLString osWorkingResult{};
347 :
348 : public:
349 : GDALDefaultRasterAttributeTable();
350 : ~GDALDefaultRasterAttributeTable() override;
351 :
352 : GDALDefaultRasterAttributeTable *Clone() const override;
353 :
354 : int GetColumnCount() const override;
355 :
356 : const char *GetNameOfCol(int) const override;
357 : GDALRATFieldUsage GetUsageOfCol(int) const override;
358 : GDALRATFieldType GetTypeOfCol(int) const override;
359 :
360 : int GetColOfUsage(GDALRATFieldUsage) const override;
361 :
362 : int GetRowCount() const override;
363 :
364 : const char *GetValueAsString(int iRow, int iField) const override;
365 : int GetValueAsInt(int iRow, int iField) const override;
366 : double GetValueAsDouble(int iRow, int iField) const override;
367 :
368 : void SetValue(int iRow, int iField, const char *pszValue) override;
369 : void SetValue(int iRow, int iField, double dfValue) override;
370 : void SetValue(int iRow, int iField, int nValue) override;
371 :
372 : int ChangesAreWrittenToFile() override;
373 : void SetRowCount(int iCount) override;
374 :
375 : int GetRowOfValue(double dfValue) const override;
376 : int GetRowOfValue(int nValue) const override;
377 :
378 : CPLErr CreateColumn(const char *pszFieldName, GDALRATFieldType eFieldType,
379 : GDALRATFieldUsage eFieldUsage) override;
380 : CPLErr SetLinearBinning(double dfRow0Min, double dfBinSize) override;
381 : int GetLinearBinning(double *pdfRow0Min, double *pdfBinSize) const override;
382 :
383 : CPLErr SetTableType(const GDALRATTableType eInTableType) override;
384 : GDALRATTableType GetTableType() const override;
385 :
386 : void RemoveStatistics() override;
387 : };
388 :
389 : std::unique_ptr<GDALRasterAttributeTable>
390 : CPL_DLL GDALLoadVATDBF(const char *pszFilename);
391 :
392 : #endif /* ndef GDAL_RAT_H_INCLUDED */
|