/src/gdal/gcore/gdal_rat.h
Line | Count | Source (jump to first uncovered line) |
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 | | 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 | | ToHandle(GDALRasterAttributeTable *poRAT) |
282 | 0 | { |
283 | 0 | return static_cast<GDALRasterAttributeTableH>(poRAT); |
284 | 0 | } |
285 | | |
286 | | /** Convert a GDALRasterAttributeTableH to a GDALRasterAttributeTable*. |
287 | | * @since GDAL 2.3 |
288 | | */ |
289 | | static inline GDALRasterAttributeTable * |
290 | | FromHandle(GDALRasterAttributeTableH hRAT) |
291 | 0 | { |
292 | 0 | return static_cast<GDALRasterAttributeTable *>(hRAT); |
293 | 0 | } |
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 | 0 | GDALRasterAttributeTable() = default; |
305 | 0 | 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 | | 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 | | GDALDefaultRasterAttributeTable(const GDALDefaultRasterAttributeTable &) = |
358 | 0 | 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 */ |