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