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