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 1180 : 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 1064 : ToHandle(GDALRasterAttributeTable *poRAT)
282 : {
283 1064 : 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 735 : FromHandle(GDALRasterAttributeTableH hRAT)
291 : {
292 735 : 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 :
303 : /************************************************************************/
304 : /* GDALRasterAttributeField */
305 : /* */
306 : /* (private) */
307 : /************************************************************************/
308 : //! @cond Doxygen_Suppress
309 : class GDALRasterAttributeField
310 : {
311 : public:
312 : CPLString sName{};
313 :
314 : GDALRATFieldType eType = GFT_Integer;
315 :
316 : GDALRATFieldUsage eUsage = GFU_Generic;
317 :
318 : std::vector<GInt32> anValues{};
319 : std::vector<double> adfValues{};
320 : std::vector<CPLString> aosValues{};
321 : };
322 :
323 : //! @endcond
324 :
325 : /************************************************************************/
326 : /* GDALDefaultRasterAttributeTable */
327 : /************************************************************************/
328 :
329 : //! Raster Attribute Table container.
330 :
331 703 : class CPL_DLL GDALDefaultRasterAttributeTable : public GDALRasterAttributeTable
332 : {
333 : private:
334 : std::vector<GDALRasterAttributeField> aoFields{};
335 :
336 : int bLinearBinning = false; // TODO(schwehr): Can this be a bool?
337 : double dfRow0Min = -0.5;
338 : double dfBinSize = 1.0;
339 :
340 : GDALRATTableType eTableType;
341 :
342 : void AnalyseColumns();
343 : int bColumnsAnalysed = false; // TODO(schwehr): Can this be a bool?
344 : int nMinCol = -1;
345 : int nMaxCol = -1;
346 :
347 : int nRowCount = 0;
348 :
349 : CPLString osWorkingResult{};
350 :
351 : public:
352 : GDALDefaultRasterAttributeTable();
353 : ~GDALDefaultRasterAttributeTable() override;
354 :
355 : GDALDefaultRasterAttributeTable *Clone() const override;
356 :
357 : int GetColumnCount() const override;
358 :
359 : const char *GetNameOfCol(int) const override;
360 : GDALRATFieldUsage GetUsageOfCol(int) const override;
361 : GDALRATFieldType GetTypeOfCol(int) const override;
362 :
363 : int GetColOfUsage(GDALRATFieldUsage) const override;
364 :
365 : int GetRowCount() const override;
366 :
367 : const char *GetValueAsString(int iRow, int iField) const override;
368 : int GetValueAsInt(int iRow, int iField) const override;
369 : double GetValueAsDouble(int iRow, int iField) const override;
370 :
371 : CPLErr SetValue(int iRow, int iField, const char *pszValue) override;
372 : CPLErr SetValue(int iRow, int iField, double dfValue) override;
373 : CPLErr SetValue(int iRow, int iField, int nValue) override;
374 :
375 : int ChangesAreWrittenToFile() override;
376 : void SetRowCount(int iCount) override;
377 :
378 : int GetRowOfValue(double dfValue) const override;
379 : int GetRowOfValue(int nValue) const override;
380 :
381 : CPLErr CreateColumn(const char *pszFieldName, GDALRATFieldType eFieldType,
382 : GDALRATFieldUsage eFieldUsage) override;
383 : CPLErr SetLinearBinning(double dfRow0Min, double dfBinSize) override;
384 : int GetLinearBinning(double *pdfRow0Min, double *pdfBinSize) const override;
385 :
386 : CPLErr SetTableType(const GDALRATTableType eInTableType) override;
387 : GDALRATTableType GetTableType() const override;
388 :
389 : void RemoveStatistics() override;
390 : };
391 :
392 : std::unique_ptr<GDALRasterAttributeTable>
393 : CPL_DLL GDALLoadVATDBF(const char *pszFilename);
394 :
395 : #endif /* ndef GDAL_RAT_H_INCLUDED */
|