LTP GCOV extension - code coverage report
Current view: directory - gcore - gdal_rat.cpp
Test: gdal_filtered.info
Date: 2010-07-12 Instrumented lines: 386
Code covered: 57.8 % Executed lines: 223

       1                 : /******************************************************************************
       2                 :  * $Id: gdal_rat.cpp 16570 2009-03-14 11:42:31Z rouault $
       3                 :  *
       4                 :  * Project:  GDAL Core
       5                 :  * Purpose:  Implementation of GDALRasterAttributeTable and related classes.
       6                 :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       7                 :  *
       8                 :  ******************************************************************************
       9                 :  * Copyright (c) 2005, Frank Warmerdam
      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                 : #include "gdal_priv.h"
      31                 : #include "gdal_rat.h"
      32                 : 
      33                 : CPL_CVSID("$Id: gdal_rat.cpp 16570 2009-03-14 11:42:31Z rouault $");
      34                 : 
      35                 : /**
      36                 :  * \class GDALRasterAttributeTable
      37                 :  *
      38                 :  * The GDALRasterAttributeTable (or RAT) class is used to encapsulate a table
      39                 :  * used to provide attribute information about pixel values.  Each row
      40                 :  * in the table applies to a range of pixel values (or a single value in
      41                 :  * some cases), and might have attributes such as the histogram count for
      42                 :  * that range, the color pixels of that range should be drawn names of classes
      43                 :  * or any other generic information. 
      44                 :  *
      45                 :  * Raster attribute tables can be used to represent histograms, color tables,
      46                 :  * and classification information.  
      47                 :  *
      48                 :  * Each column in a raster attribute table has a name, a type (integer,
      49                 :  * floating point or string), and a GDALRATFieldUsage.  The usage distinguishes 
      50                 :  * columns with particular understood purposes (such as color, histogram 
      51                 :  * count, name) and columns that have specific purposes not understood by 
      52                 :  * the library (long label, suitability_for_growing_wheat, etc).  
      53                 :  *
      54                 :  * In the general case each row has a column indicating the minimum pixel
      55                 :  * values falling into that category, and a column indicating the maximum
      56                 :  * pixel value.  These are indicated with usage values of GFU_Min, and
      57                 :  * GFU_Max.  In other cases where each row is a discrete pixel value, one
      58                 :  * column of usage GFU_MinMax can be used.  
      59                 :  * 
      60                 :  * In other cases all the categories are of equal size and regularly spaced 
      61                 :  * and the categorization information can be determine just by knowing the
      62                 :  * value at which the categories start, and the size of a category.  This
      63                 :  * is called "Linear Binning" and the information is kept specially on 
      64                 :  * the raster attribute table as a whole.
      65                 :  *
      66                 :  * RATs are normally associated with GDALRasterBands and be be queried
      67                 :  * using the GDALRasterBand::GetDefaultRAT() method.  
      68                 :  */
      69                 : 
      70                 : /************************************************************************/
      71                 : /*                      GDALRasterAttributeTable()                      */
      72                 : /*                                                                      */
      73                 : /*      Simple initialization constructor.                              */
      74                 : /************************************************************************/
      75                 : 
      76                 : //! Construct empty table.
      77                 : 
      78              52 : GDALRasterAttributeTable::GDALRasterAttributeTable()
      79                 : 
      80                 : {
      81              52 :     bColumnsAnalysed = FALSE;
      82              52 :     nMinCol = -1;
      83              52 :     nMaxCol = -1;
      84              52 :     bLinearBinning = FALSE;
      85              52 :     dfRow0Min = -0.5;
      86              52 :     dfBinSize = 1.0;
      87              52 :     nRowCount = 0;
      88              52 : }
      89                 : 
      90                 : /************************************************************************/
      91                 : /*                   GDALCreateRasterAttributeTable()                   */
      92                 : /************************************************************************/
      93                 : 
      94                 : /**
      95                 :  * \brief Construct empty table.
      96                 :  *
      97                 :  * This function is the same as the C++ method GDALRasterAttributeTable::GDALRasterAttributeTable()
      98                 :  */
      99               2 : GDALRasterAttributeTableH CPL_STDCALL GDALCreateRasterAttributeTable()
     100                 : 
     101                 : {
     102               2 :     return (GDALRasterAttributeTableH) (new GDALRasterAttributeTable());
     103                 : }
     104                 : 
     105                 : /************************************************************************/
     106                 : /*                      GDALRasterAttributeTable()                      */
     107                 : /************************************************************************/
     108                 : 
     109                 : //! Copy constructor.
     110                 : 
     111                 : GDALRasterAttributeTable::GDALRasterAttributeTable( 
     112               5 :     const GDALRasterAttributeTable &oOther )
     113                 : 
     114                 : {
     115                 :     // We have tried to be careful to allow wholesale assignment
     116               5 :     *this = oOther;
     117               5 : }
     118                 : 
     119                 : /************************************************************************/
     120                 : /*                     ~GDALRasterAttributeTable()                      */
     121                 : /*                                                                      */
     122                 : /*      All magic done by magic by the container destructors.           */
     123                 : /************************************************************************/
     124                 : 
     125              57 : GDALRasterAttributeTable::~GDALRasterAttributeTable()
     126                 : 
     127                 : {
     128              57 : }
     129                 : 
     130                 : /************************************************************************/
     131                 : /*                  GDALDestroyRasterAttributeTable()                   */
     132                 : /************************************************************************/
     133                 : 
     134                 : /**
     135                 :  * \brief Destroys a RAT.
     136                 :  *
     137                 :  * This function is the same as the C++ method GDALRasterAttributeTable::~GDALRasterAttributeTable()
     138                 :  */
     139                 : void CPL_STDCALL 
     140               3 : GDALDestroyRasterAttributeTable( GDALRasterAttributeTableH hRAT )
     141                 : 
     142                 : {
     143               3 :     if( hRAT != NULL )
     144               3 :         delete static_cast<GDALRasterAttributeTable *>(hRAT);
     145               3 : }
     146                 : 
     147                 : /************************************************************************/
     148                 : /*                           AnalyseColumns()                           */
     149                 : /*                                                                      */
     150                 : /*      Internal method to work out which column to use for various     */
     151                 : /*      tasks.                                                          */
     152                 : /************************************************************************/
     153                 : 
     154               2 : void GDALRasterAttributeTable::AnalyseColumns()
     155                 : 
     156                 : {
     157               2 :     bColumnsAnalysed = TRUE;
     158                 : 
     159               2 :     nMinCol = GetColOfUsage( GFU_Min );
     160               2 :     if( nMinCol == -1 )
     161               2 :         nMinCol = GetColOfUsage( GFU_MinMax );
     162                 : 
     163               2 :     nMaxCol = GetColOfUsage( GFU_Max );
     164               2 :     if( nMaxCol == -1 )
     165               2 :         nMaxCol = GetColOfUsage( GFU_MinMax );
     166               2 : }
     167                 : 
     168                 : /************************************************************************/
     169                 : /*                           GetColumnCount()                           */
     170                 : /************************************************************************/
     171                 : 
     172                 : /**
     173                 :  * \brief Fetch table column count.
     174                 :  *
     175                 :  * This method is the same as the C function GDALRATGetColumnCount().
     176                 :  *
     177                 :  * @return the number of columns.
     178                 :  */
     179                 : 
     180           11117 : int GDALRasterAttributeTable::GetColumnCount() const
     181                 : 
     182                 : {
     183           11117 :     return aoFields.size();
     184                 : }
     185                 : 
     186                 : /************************************************************************/
     187                 : /*                       GDALRATGetColumnCount()                        */
     188                 : /************************************************************************/
     189                 : 
     190                 : /**
     191                 :  * \brief Fetch table column count.
     192                 :  *
     193                 :  * This function is the same as the C++ method GDALRasterAttributeTable::GetColumnCount()
     194                 :  */
     195               4 : int CPL_STDCALL GDALRATGetColumnCount( GDALRasterAttributeTableH hRAT )
     196                 : 
     197                 : {
     198               4 :     VALIDATE_POINTER1( hRAT, "GDALRATGetColumnCount", 0 );
     199                 : 
     200               4 :     return ((GDALRasterAttributeTable *) hRAT)->GetColumnCount();
     201                 : }
     202                 : 
     203                 : /************************************************************************/
     204                 : /*                            GetNameOfCol()                            */
     205                 : /************************************************************************/
     206                 : 
     207                 : /**
     208                 :  * \brief Fetch name of indicated column.
     209                 :  *
     210                 :  * This method is the same as the C function GDALRATGetNameOfCol().
     211                 :  *
     212                 :  * @param iCol the column index (zero based). 
     213                 :  *
     214                 :  * @return the column name or an empty string for invalid column numbers.
     215                 :  */
     216                 : 
     217               0 : const char *GDALRasterAttributeTable::GetNameOfCol( int iCol ) const
     218                 : 
     219                 : {
     220               0 :     if( iCol < 0 || iCol >= (int) aoFields.size() )
     221               0 :         return "";
     222                 : 
     223                 :     else
     224               0 :         return aoFields[iCol].sName;
     225                 : }
     226                 : 
     227                 : /************************************************************************/
     228                 : /*                        GDALRATGetNameOfCol()                         */
     229                 : /************************************************************************/
     230                 : 
     231                 : /**
     232                 :  * \brief Fetch name of indicated column.
     233                 :  *
     234                 :  * This function is the same as the C++ method GDALRasterAttributeTable::GetNameOfCol()
     235                 :  */
     236                 : const char *CPL_STDCALL GDALRATGetNameOfCol( GDALRasterAttributeTableH hRAT,
     237               4 :                                              int iCol )
     238                 : 
     239                 : {
     240               4 :     VALIDATE_POINTER1( hRAT, "GDALRATGetNameOfCol", NULL );
     241                 : 
     242                 :     // we don't just wrap the normal operator because we don't want to
     243                 :     // return a temporary string, we want to return a pointer to the
     244                 :     // internal column name. 
     245                 : 
     246               4 :     GDALRasterAttributeTable *poRAT = (GDALRasterAttributeTable *) hRAT;
     247                 : 
     248               4 :     if( iCol < 0 || iCol >= (int) poRAT->aoFields.size() )
     249               0 :         return "";
     250                 : 
     251                 :     else
     252               4 :         return poRAT->aoFields[iCol].sName.c_str();
     253                 : }
     254                 : 
     255                 : /************************************************************************/
     256                 : /*                           GetUsageOfCol()                            */
     257                 : /************************************************************************/
     258                 : 
     259                 : /**
     260                 :  * \brief Fetch column usage value. 
     261                 :  *
     262                 :  * This method is the same as the C function GDALRATGetUsageOfCol().
     263                 :  *
     264                 :  * @param iCol the column index (zero based).
     265                 :  *
     266                 :  * @return the column usage, or GFU_Generic for improper column numbers.
     267                 :  */
     268                 : 
     269               5 : GDALRATFieldUsage GDALRasterAttributeTable::GetUsageOfCol( int iCol ) const
     270                 : 
     271                 : {
     272               5 :     if( iCol < 0 || iCol >= (int) aoFields.size() )
     273               0 :         return GFU_Generic;
     274                 : 
     275                 :     else
     276               5 :         return aoFields[iCol].eUsage;
     277                 : }
     278                 : 
     279                 : /************************************************************************/
     280                 : /*                        GDALRATGetUsageOfCol()                        */
     281                 : /************************************************************************/
     282                 : 
     283                 : /**
     284                 :  * \brief Fetch column usage value. 
     285                 :  *
     286                 :  * This function is the same as the C++ method GDALRasterAttributeTable::GetUsageOfColetNameOfCol()
     287                 :  */
     288                 : GDALRATFieldUsage CPL_STDCALL 
     289               5 : GDALRATGetUsageOfCol( GDALRasterAttributeTableH hRAT, int iCol )
     290                 : 
     291                 : {
     292               5 :     VALIDATE_POINTER1( hRAT, "GDALRATGetUsageOfCol", GFU_Generic );
     293                 : 
     294               5 :     return ((GDALRasterAttributeTable *) hRAT)->GetUsageOfCol( iCol );
     295                 : }
     296                 : 
     297                 : /************************************************************************/
     298                 : /*                            GetTypeOfCol()                            */
     299                 : /************************************************************************/
     300                 : 
     301                 : /**
     302                 :  * \brief Fetch column type.
     303                 :  *
     304                 :  * This method is the same as the C function GDALRATGetTypeOfCol().
     305                 :  *
     306                 :  * @param iCol the column index (zero based).
     307                 :  *
     308                 :  * @return column type or GFT_Integer if the column index is illegal.
     309                 :  */
     310                 : 
     311               5 : GDALRATFieldType GDALRasterAttributeTable::GetTypeOfCol( int iCol ) const
     312                 : 
     313                 : {
     314               5 :     if( iCol < 0 || iCol >= (int) aoFields.size() )
     315               0 :         return GFT_Integer;
     316                 : 
     317                 :     else
     318               5 :         return aoFields[iCol].eType;
     319                 : }
     320                 : 
     321                 : /************************************************************************/
     322                 : /*                        GDALRATGetTypeOfCol()                         */
     323                 : /************************************************************************/
     324                 : 
     325                 : /**
     326                 :  * \brief Fetch column type.
     327                 :  *
     328                 :  * This function is the same as the C++ method GDALRasterAttributeTable::GetTypeOfCol()
     329                 :  */
     330                 : GDALRATFieldType CPL_STDCALL 
     331               5 : GDALRATGetTypeOfCol( GDALRasterAttributeTableH hRAT, int iCol )
     332                 : 
     333                 : {
     334               5 :     VALIDATE_POINTER1( hRAT, "GDALRATGetTypeOfCol", GFT_Integer );
     335                 : 
     336               5 :     return ((GDALRasterAttributeTable *) hRAT)->GetTypeOfCol( iCol );
     337                 : }
     338                 : 
     339                 : /************************************************************************/
     340                 : /*                           GetColOfUsage()                            */
     341                 : /************************************************************************/
     342                 : 
     343                 : /**
     344                 :  * \brief Fetch column index for given usage.
     345                 :  *
     346                 :  * Returns the index of the first column of the requested usage type, or -1 
     347                 :  * if no match is found. 
     348                 :  *
     349                 :  * This method is the same as the C function GDALRATGetUsageOfCol().
     350                 :  *
     351                 :  * @param eUsage usage type to search for.
     352                 :  *
     353                 :  * @return column index, or -1 on failure. 
     354                 :  */
     355                 : 
     356               8 : int GDALRasterAttributeTable::GetColOfUsage( GDALRATFieldUsage eUsage ) const
     357                 : 
     358                 : {
     359                 :     unsigned int i;
     360                 : 
     361              16 :     for( i = 0; i < aoFields.size(); i++ )
     362                 :     {
     363              12 :         if( aoFields[i].eUsage == eUsage )
     364               4 :             return i;
     365                 :     }
     366                 : 
     367               4 :     return -1;
     368                 : }
     369                 : 
     370                 : /************************************************************************/
     371                 : /*                        GDALRATGetColOfUsage()                        */
     372                 : /************************************************************************/
     373                 : 
     374                 : /**
     375                 :  * \brief Fetch column index for given usage.
     376                 :  *
     377                 :  * This function is the same as the C++ method GDALRasterAttributeTable::GetColOfUsage()
     378                 :  */
     379                 : int CPL_STDCALL 
     380                 : GDALRATGetColOfUsage( GDALRasterAttributeTableH hRAT, 
     381               0 :                       GDALRATFieldUsage eUsage )
     382                 : 
     383                 : {
     384               0 :     VALIDATE_POINTER1( hRAT, "GDALRATGetColOfUsage", 0 );
     385                 : 
     386               0 :     return ((GDALRasterAttributeTable *) hRAT)->GetColOfUsage( eUsage );
     387                 : }
     388                 : 
     389                 : /************************************************************************/
     390                 : /*                            GetRowCount()                             */
     391                 : /************************************************************************/
     392                 : 
     393                 : /**
     394                 :  * \brief Fetch row count.
     395                 :  * 
     396                 :  * This method is the same as the C function GDALRATGetRowCount().
     397                 :  *
     398                 :  * @return the number of rows. 
     399                 :  */
     400                 : 
     401               7 : int GDALRasterAttributeTable::GetRowCount() const
     402                 : 
     403                 : {
     404               7 :     return (int) nRowCount;
     405                 : }
     406                 : 
     407                 : /************************************************************************/
     408                 : /*                        GDALRATGetUsageOfCol()                        */
     409                 : /************************************************************************/
     410                 : /**
     411                 :  * \brief Fetch row count.
     412                 :  *
     413                 :  * This function is the same as the C++ method GDALRasterAttributeTable::GetRowCount()
     414                 :  */
     415                 : int CPL_STDCALL 
     416               3 : GDALRATGetRowCount( GDALRasterAttributeTableH hRAT )
     417                 : 
     418                 : {
     419               3 :     VALIDATE_POINTER1( hRAT, "GDALRATGetRowCount", 0 );
     420                 : 
     421               3 :     return ((GDALRasterAttributeTable *) hRAT)->GetRowCount();
     422                 : }
     423                 : 
     424                 : /************************************************************************/
     425                 : /*                          GetValueAsString()                          */
     426                 : /************************************************************************/
     427                 : 
     428                 : /**
     429                 :  * \brief Fetch field value as a string.
     430                 :  *
     431                 :  * The value of the requested column in the requested row is returned
     432                 :  * as a string.  If the field is numeric, it is formatted as a string
     433                 :  * using default rules, so some precision may be lost.
     434                 :  *
     435                 :  * This method is the same as the C function GDALRATGetValueAsString().
     436                 :  *
     437                 :  * @param iRow row to fetch (zero based).
     438                 :  * @param iField column to fetch (zero based).
     439                 :  * 
     440                 :  * @return field value
     441                 :  */
     442                 : 
     443                 : const char *
     444               0 : GDALRasterAttributeTable::GetValueAsString( int iRow, int iField ) const
     445                 : 
     446                 : {
     447               0 :     if( iField < 0 || iField >= (int) aoFields.size() )
     448                 :     {
     449                 :         CPLError( CE_Failure, CPLE_AppDefined,
     450               0 :                   "iField (%d) out of range.", iField );
     451                 : 
     452               0 :         return "";
     453                 :     }
     454                 : 
     455               0 :     if( iRow < 0 || iRow >= nRowCount )
     456                 :     {
     457                 :         CPLError( CE_Failure, CPLE_AppDefined,
     458               0 :                   "iRow (%d) out of range.", iRow );
     459                 : 
     460               0 :         return "";
     461                 :     }
     462                 : 
     463               0 :     switch( aoFields[iField].eType )
     464                 :     {
     465                 :       case GFT_Integer:
     466                 :       {
     467                 :           ((GDALRasterAttributeTable *) this)->
     468               0 :               osWorkingResult.Printf( "%d", aoFields[iField].anValues[iRow] );
     469               0 :           return osWorkingResult;
     470                 :       }
     471                 : 
     472                 :       case GFT_Real:
     473                 :       {
     474                 :           ((GDALRasterAttributeTable *) this)->
     475               0 :               osWorkingResult.Printf( "%.16g", aoFields[iField].adfValues[iRow]);
     476               0 :           return osWorkingResult;
     477                 :       }
     478                 : 
     479                 :       case GFT_String:
     480                 :       {
     481               0 :           return aoFields[iField].aosValues[iRow];
     482                 :       }
     483                 :     }
     484                 : 
     485               0 :     return "";
     486                 : }
     487                 : 
     488                 : /************************************************************************/
     489                 : /*                      GDALRATGetValueAsString()                       */
     490                 : /************************************************************************/
     491                 : /**
     492                 :  * \brief Fetch field value as a string.
     493                 :  *
     494                 :  * This function is the same as the C++ method GDALRasterAttributeTable::GetValueAsString()
     495                 :  */
     496                 : const char * CPL_STDCALL 
     497               0 : GDALRATGetValueAsString( GDALRasterAttributeTableH hRAT, int iRow, int iField )
     498                 : 
     499                 : {
     500               0 :     VALIDATE_POINTER1( hRAT, "GDALRATGetValueAsString", NULL );
     501                 : 
     502               0 :     GDALRasterAttributeTable *poRAT = (GDALRasterAttributeTable *) hRAT;
     503                 : 
     504               0 :     poRAT->osWorkingResult = poRAT->GetValueAsString( iRow, iField );
     505                 :     
     506               0 :     return poRAT->osWorkingResult.c_str();
     507                 : }
     508                 : 
     509                 : /************************************************************************/
     510                 : /*                           GetValueAsInt()                            */
     511                 : /************************************************************************/
     512                 : 
     513                 : /**
     514                 :  * \brief Fetch field value as a integer.
     515                 :  *
     516                 :  * The value of the requested column in the requested row is returned
     517                 :  * as an integer.  Non-integer fields will be converted to integer with
     518                 :  * the possibility of data loss.
     519                 :  *
     520                 :  * This method is the same as the C function GDALRATGetValueAsInt().
     521                 :  *
     522                 :  * @param iRow row to fetch (zero based).
     523                 :  * @param iField column to fetch (zero based).
     524                 :  * 
     525                 :  * @return field value
     526                 :  */
     527                 : 
     528                 : int 
     529               4 : GDALRasterAttributeTable::GetValueAsInt( int iRow, int iField ) const
     530                 : 
     531                 : {
     532               4 :     if( iField < 0 || iField >= (int) aoFields.size() )
     533                 :     {
     534                 :         CPLError( CE_Failure, CPLE_AppDefined,
     535               0 :                   "iField (%d) out of range.", iField );
     536                 : 
     537               0 :         return 0;
     538                 :     }
     539                 : 
     540               4 :     if( iRow < 0 || iRow >= nRowCount )
     541                 :     {
     542                 :         CPLError( CE_Failure, CPLE_AppDefined,
     543               0 :                   "iRow (%d) out of range.", iRow );
     544                 : 
     545               0 :         return 0;
     546                 :     }
     547                 : 
     548               4 :     switch( aoFields[iField].eType )
     549                 :     {
     550                 :       case GFT_Integer:
     551               4 :         return aoFields[iField].anValues[iRow];
     552                 : 
     553                 :       case GFT_Real:
     554               0 :         return (int)  aoFields[iField].adfValues[iRow];
     555                 : 
     556                 :       case GFT_String:
     557               0 :         return atoi( aoFields[iField].aosValues[iRow].c_str() );
     558                 :     }
     559                 : 
     560               0 :     return 0;
     561                 : }
     562                 : 
     563                 : /************************************************************************/
     564                 : /*                        GDALRATGetValueAsInt()                        */
     565                 : /************************************************************************/
     566                 : 
     567                 : /**
     568                 :  * \brief Fetch field value as a integer.
     569                 :  *
     570                 :  * This function is the same as the C++ method GDALRasterAttributeTable::GetValueAsInt()
     571                 :  */
     572                 : int CPL_STDCALL 
     573               4 : GDALRATGetValueAsInt( GDALRasterAttributeTableH hRAT, int iRow, int iField )
     574                 : 
     575                 : {
     576               4 :     VALIDATE_POINTER1( hRAT, "GDALRATGetValueAsInt", 0 );
     577                 : 
     578               4 :     return ((GDALRasterAttributeTable *) hRAT)->GetValueAsInt( iRow, iField );
     579                 : }
     580                 : 
     581                 : /************************************************************************/
     582                 : /*                          GetValueAsDouble()                          */
     583                 : /************************************************************************/
     584                 : 
     585                 : /**
     586                 :  * \brief Fetch field value as a double.
     587                 :  *
     588                 :  * The value of the requested column in the requested row is returned
     589                 :  * as a double.   Non double fields will be converted to double with
     590                 :  * the possibility of data loss.
     591                 :  * 
     592                 :  * This method is the same as the C function GDALRATGetValueAsDouble().
     593                 :  *
     594                 :  * @param iRow row to fetch (zero based).
     595                 :  * @param iField column to fetch (zero based).
     596                 :  * 
     597                 :  * @return field value
     598                 :  */
     599                 : 
     600                 : double
     601               0 : GDALRasterAttributeTable::GetValueAsDouble( int iRow, int iField ) const
     602                 : 
     603                 : {
     604               0 :     if( iField < 0 || iField >= (int) aoFields.size() )
     605                 :     {
     606                 :         CPLError( CE_Failure, CPLE_AppDefined,
     607               0 :                   "iField (%d) out of range.", iField );
     608                 : 
     609               0 :         return 0;
     610                 :     }
     611                 : 
     612               0 :     if( iRow < 0 || iRow >= nRowCount )
     613                 :     {
     614                 :         CPLError( CE_Failure, CPLE_AppDefined,
     615               0 :                   "iRow (%d) out of range.", iRow );
     616                 : 
     617               0 :         return 0;
     618                 :     }
     619                 : 
     620               0 :     switch( aoFields[iField].eType )
     621                 :     {
     622                 :       case GFT_Integer:
     623               0 :         return aoFields[iField].anValues[iRow];
     624                 : 
     625                 :       case GFT_Real:
     626               0 :         return aoFields[iField].adfValues[iRow];
     627                 : 
     628                 :       case GFT_String:
     629               0 :         return atof( aoFields[iField].aosValues[iRow].c_str() );
     630                 :     }
     631                 : 
     632               0 :     return 0;
     633                 : }
     634                 : 
     635                 : /************************************************************************/
     636                 : /*                      GDALRATGetValueAsDouble()                       */
     637                 : /************************************************************************/
     638                 : 
     639                 : /**
     640                 :  * \brief Fetch field value as a double.
     641                 :  *
     642                 :  * This function is the same as the C++ method GDALRasterAttributeTable::GetValueAsDouble()
     643                 :  */
     644                 : double CPL_STDCALL 
     645               0 : GDALRATGetValueAsDouble( GDALRasterAttributeTableH hRAT, int iRow, int iField )
     646                 : 
     647                 : {
     648               0 :     VALIDATE_POINTER1( hRAT, "GDALRATGetValueAsDouble", 0 );
     649                 : 
     650               0 :     return ((GDALRasterAttributeTable *) hRAT)->GetValueAsDouble(iRow,iField);
     651                 : }
     652                 : 
     653                 : /************************************************************************/
     654                 : /*                            SetRowCount()                             */
     655                 : /************************************************************************/
     656                 : 
     657                 : /**
     658                 :  * \brief Set row count.
     659                 :  *
     660                 :  * Resizes the table to include the indicated number of rows.  Newly created
     661                 :  * rows will be initialized to their default values - "" for strings, 
     662                 :  * and zero for numeric fields. 
     663                 :  *
     664                 :  * This method is the same as the C function GDALRATSetRowCount().
     665                 :  *
     666                 :  * @param nNewCount the new number of rows.
     667                 :  */
     668                 : 
     669           11054 : void GDALRasterAttributeTable::SetRowCount( int nNewCount )
     670                 : 
     671                 : {
     672           11054 :     if( nNewCount == nRowCount )
     673               0 :         return;
     674                 : 
     675                 :     unsigned int iField;
     676           24987 :     for( iField = 0; iField < aoFields.size(); iField++ )
     677                 :     {
     678           13933 :         switch( aoFields[iField].eType )
     679                 :         {
     680                 :           case GFT_Integer:
     681            7872 :             aoFields[iField].anValues.resize( nNewCount );
     682            7872 :             break;
     683                 : 
     684                 :           case GFT_Real:
     685            6061 :             aoFields[iField].adfValues.resize( nNewCount );
     686            6061 :             break;
     687                 : 
     688                 :           case GFT_String:
     689               0 :             aoFields[iField].aosValues.resize( nNewCount );
     690                 :             break;
     691                 :         }
     692                 :     }
     693                 : 
     694           11054 :     nRowCount = nNewCount;
     695                 : }
     696                 : 
     697                 : /************************************************************************/
     698                 : /*                         GDALRATSetRowCount()                         */
     699                 : /************************************************************************/
     700                 : 
     701                 : /**
     702                 :  * \brief Set row count.
     703                 :  *
     704                 :  * This function is the same as the C++ method GDALRasterAttributeTable::SetRowCount()
     705                 :  */
     706                 : void CPL_STDCALL 
     707               1 : GDALRATSetRowCount( GDALRasterAttributeTableH hRAT, int nNewCount )
     708                 : 
     709                 : {
     710               1 :     VALIDATE_POINTER0( hRAT, "GDALRATSetRowCount" );
     711                 : 
     712               1 :     ((GDALRasterAttributeTable *) hRAT)->SetRowCount( nNewCount );
     713                 : }
     714                 : 
     715                 : /************************************************************************/
     716                 : /*                              SetValue()                              */
     717                 : /************************************************************************/
     718                 : 
     719                 : /**
     720                 :  * \brief Set field value from string.
     721                 :  *
     722                 :  * The indicated field (column) on the indicated row is set from the
     723                 :  * passed value.  The value will be automatically converted for other field
     724                 :  * types, with a possible loss of precision.
     725                 :  *
     726                 :  * This method is the same as the C function GDALRATSetValueAsString().
     727                 :  *
     728                 :  * @param iRow row to fetch (zero based).
     729                 :  * @param iField column to fetch (zero based).
     730                 :  * @param pszValue the value to assign.
     731                 :  */
     732                 : 
     733                 : void GDALRasterAttributeTable::SetValue( int iRow, int iField, 
     734             690 :                                          const char *pszValue )
     735                 : 
     736                 : {
     737             690 :     if( iField < 0 || iField >= (int) aoFields.size() )
     738                 :     {
     739                 :         CPLError( CE_Failure, CPLE_AppDefined,
     740               0 :                   "iField (%d) out of range.", iField );
     741                 : 
     742               0 :         return;
     743                 :     }
     744                 : 
     745             690 :     if( iRow == nRowCount )
     746             236 :         SetRowCount( nRowCount+1 );
     747                 :     
     748             690 :     if( iRow < 0 || iRow >= nRowCount )
     749                 :     {
     750                 :         CPLError( CE_Failure, CPLE_AppDefined,
     751               0 :                   "iRow (%d) out of range.", iRow );
     752                 : 
     753               0 :         return;
     754                 :     }
     755                 : 
     756             690 :     switch( aoFields[iField].eType )
     757                 :     {
     758                 :       case GFT_Integer:
     759             242 :         aoFields[iField].anValues[iRow] = atoi(pszValue);
     760             242 :         break;
     761                 :         
     762                 :       case GFT_Real:
     763             230 :         aoFields[iField].adfValues[iRow] = atof(pszValue);
     764             230 :         break;
     765                 :         
     766                 :       case GFT_String:
     767             218 :         aoFields[iField].aosValues[iRow] = pszValue;
     768                 :         break;
     769                 :     }
     770                 : }
     771                 : 
     772                 : /************************************************************************/
     773                 : /*                      GDALRATSetValueAsString()                       */
     774                 : /************************************************************************/
     775                 : 
     776                 : /**
     777                 :  * \brief Set field value from string.
     778                 :  *
     779                 :  * This function is the same as the C++ method GDALRasterAttributeTable::SetValue()
     780                 :  */
     781                 : void CPL_STDCALL 
     782                 : GDALRATSetValueAsString( GDALRasterAttributeTableH hRAT, int iRow, int iField,
     783               0 :                          const char *pszValue )
     784                 : 
     785                 : {
     786               0 :     VALIDATE_POINTER0( hRAT, "GDALRATSetValueAsString" );
     787                 : 
     788               0 :     ((GDALRasterAttributeTable *) hRAT)->SetValue( iRow, iField, pszValue );
     789                 : }
     790                 : 
     791                 : /************************************************************************/
     792                 : /*                              SetValue()                              */
     793                 : /************************************************************************/
     794                 : 
     795                 : /**
     796                 :  * \brief Set field value from integer.
     797                 :  *
     798                 :  * The indicated field (column) on the indicated row is set from the
     799                 :  * passed value.  The value will be automatically converted for other field
     800                 :  * types, with a possible loss of precision.
     801                 :  *
     802                 :  * This method is the same as the C function GDALRATSetValueAsInteger().
     803                 :  *
     804                 :  * @param iRow row to fetch (zero based).
     805                 :  * @param iField column to fetch (zero based).
     806                 :  * @param nValue the value to assign.
     807                 :  */
     808                 : 
     809                 : void GDALRasterAttributeTable::SetValue( int iRow, int iField, 
     810            7022 :                                          int nValue )
     811                 : 
     812                 : {
     813            7022 :     if( iField < 0 || iField >= (int) aoFields.size() )
     814                 :     {
     815                 :         CPLError( CE_Failure, CPLE_AppDefined,
     816               0 :                   "iField (%d) out of range.", iField );
     817                 : 
     818               0 :         return;
     819                 :     }
     820                 : 
     821            7022 :     if( iRow == nRowCount )
     822            4156 :         SetRowCount( nRowCount+1 );
     823                 :     
     824            7022 :     if( iRow < 0 || iRow >= nRowCount )
     825                 :     {
     826                 :         CPLError( CE_Failure, CPLE_AppDefined,
     827               0 :                   "iRow (%d) out of range.", iRow );
     828                 : 
     829               0 :         return;
     830                 :     }
     831                 : 
     832            7022 :     switch( aoFields[iField].eType )
     833                 :     {
     834                 :       case GFT_Integer:
     835            7022 :         aoFields[iField].anValues[iRow] = nValue;
     836            7022 :         break;
     837                 :         
     838                 :       case GFT_Real:
     839               0 :         aoFields[iField].adfValues[iRow] = nValue;
     840               0 :         break;
     841                 :         
     842                 :       case GFT_String:
     843                 :       {
     844                 :           char szValue[100];
     845                 : 
     846               0 :           sprintf( szValue, "%d", nValue );
     847               0 :           aoFields[iField].aosValues[iRow] = szValue;
     848                 :       }
     849                 :       break;
     850                 :     }
     851                 : }
     852                 : 
     853                 : /************************************************************************/
     854                 : /*                        GDALRATSetValueAsInt()                        */
     855                 : /************************************************************************/
     856                 : 
     857                 : /**
     858                 :  * \brief Set field value from integer.
     859                 :  *
     860                 :  * This function is the same as the C++ method GDALRasterAttributeTable::SetValue()
     861                 :  */
     862                 : void CPL_STDCALL 
     863                 : GDALRATSetValueAsInt( GDALRasterAttributeTableH hRAT, int iRow, int iField,
     864               6 :                       int nValue )
     865                 : 
     866                 : {
     867               6 :     VALIDATE_POINTER0( hRAT, "GDALRATSetValueAsInt" );
     868                 : 
     869               6 :     ((GDALRasterAttributeTable *) hRAT)->SetValue( iRow, iField, nValue);
     870                 : }
     871                 : 
     872                 : /************************************************************************/
     873                 : /*                              SetValue()                              */
     874                 : /************************************************************************/
     875                 : 
     876                 : /**
     877                 :  * \brief Set field value from double.
     878                 :  *
     879                 :  * The indicated field (column) on the indicated row is set from the
     880                 :  * passed value.  The value will be automatically converted for other field
     881                 :  * types, with a possible loss of precision.
     882                 :  *
     883                 :  * This method is the same as the C function GDALRATSetValueAsDouble().
     884                 :  *
     885                 :  * @param iRow row to fetch (zero based).
     886                 :  * @param iField column to fetch (zero based).
     887                 :  * @param dfValue the value to assign.
     888                 :  */
     889                 : 
     890                 : void GDALRasterAttributeTable::SetValue( int iRow, int iField, 
     891            9159 :                                          double dfValue )
     892                 : 
     893                 : {
     894            9159 :     if( iField < 0 || iField >= (int) aoFields.size() )
     895                 :     {
     896                 :         CPLError( CE_Failure, CPLE_AppDefined,
     897               0 :                   "iField (%d) out of range.", iField );
     898                 : 
     899               0 :         return;
     900                 :     }
     901                 : 
     902            9159 :     if( iRow == nRowCount )
     903            6661 :         SetRowCount( nRowCount+1 );
     904                 :     
     905            9159 :     if( iRow < 0 || iRow >= nRowCount )
     906                 :     {
     907                 :         CPLError( CE_Failure, CPLE_AppDefined,
     908               0 :                   "iRow (%d) out of range.", iRow );
     909                 : 
     910               0 :         return;
     911                 :     }
     912                 : 
     913            9159 :     switch( aoFields[iField].eType )
     914                 :     {
     915                 :       case GFT_Integer:
     916             830 :         aoFields[iField].anValues[iRow] = (int) dfValue;
     917             830 :         break;
     918                 :         
     919                 :       case GFT_Real:
     920            8329 :         aoFields[iField].adfValues[iRow] = dfValue;
     921            8329 :         break;
     922                 :         
     923                 :       case GFT_String:
     924                 :       {
     925                 :           char szValue[100];
     926                 : 
     927               0 :           sprintf( szValue, "%.15g", dfValue );
     928               0 :           aoFields[iField].aosValues[iRow] = szValue;
     929                 :       }
     930                 :       break;
     931                 :     }
     932                 : }
     933                 : 
     934                 : /************************************************************************/
     935                 : /*                      GDALRATSetValueAsDouble()                       */
     936                 : /************************************************************************/
     937                 : 
     938                 : /**
     939                 :  * \brief Set field value from double.
     940                 :  *
     941                 :  * This function is the same as the C++ method GDALRasterAttributeTable::SetValue()
     942                 :  */
     943                 : void CPL_STDCALL 
     944                 : GDALRATSetValueAsDouble( GDALRasterAttributeTableH hRAT, int iRow, int iField,
     945               0 :                          double dfValue )
     946                 : 
     947                 : {
     948               0 :     VALIDATE_POINTER0( hRAT, "GDALRATSetValueAsDouble" );
     949                 : 
     950               0 :     ((GDALRasterAttributeTable *) hRAT)->SetValue( iRow, iField, dfValue );
     951                 : }
     952                 : 
     953                 : /************************************************************************/
     954                 : /*                           GetRowOfValue()                            */
     955                 : /************************************************************************/
     956                 : 
     957                 : /**
     958                 :  * \brief Get row for pixel value.
     959                 :  *
     960                 :  * Given a raw pixel value, the raster attribute table is scanned to 
     961                 :  * determine which row in the table applies to the pixel value.  The
     962                 :  * row index is returned. 
     963                 :  *
     964                 :  * This method is the same as the C function GDALRATGetRowOfValue().
     965                 :  *
     966                 :  * @param dfValue the pixel value. 
     967                 :  *
     968                 :  * @return the row index or -1 if no row is appropriate. 
     969                 :  */
     970                 : 
     971               2 : int GDALRasterAttributeTable::GetRowOfValue( double dfValue ) const
     972                 : 
     973                 : {
     974                 : /* -------------------------------------------------------------------- */
     975                 : /*      Handle case of regular binning.                                 */
     976                 : /* -------------------------------------------------------------------- */
     977               2 :     if( bLinearBinning )
     978                 :     {
     979               0 :         int iBin = (int) floor((dfValue - dfRow0Min) / dfBinSize);
     980               0 :         if( iBin < 0 || iBin >= nRowCount )
     981               0 :             return -1;
     982                 :         else
     983               0 :             return iBin;
     984                 :     }
     985                 : 
     986                 : /* -------------------------------------------------------------------- */
     987                 : /*      Do we have any information?                                     */
     988                 : /* -------------------------------------------------------------------- */
     989                 :     const GDALRasterAttributeField *poMin, *poMax;
     990                 : 
     991               2 :     if( !bColumnsAnalysed )
     992               2 :         ((GDALRasterAttributeTable *) this)->AnalyseColumns();
     993                 : 
     994               2 :     if( nMinCol == -1 && nMaxCol == -1 )
     995               0 :         return -1;
     996                 : 
     997               2 :     if( nMinCol != -1 )
     998               2 :         poMin = &(aoFields[nMinCol]);
     999                 :     else
    1000               0 :         poMin = NULL;
    1001                 :     
    1002               2 :     if( nMaxCol != -1 )
    1003               2 :         poMax = &(aoFields[nMaxCol]);
    1004                 :     else
    1005               0 :         poMax = NULL;
    1006                 :     
    1007                 : /* -------------------------------------------------------------------- */
    1008                 : /*      Search through rows for match.                                  */
    1009                 : /* -------------------------------------------------------------------- */
    1010                 :     int   iRow;
    1011                 : 
    1012               4 :     for( iRow = 0; iRow < nRowCount; iRow++ )
    1013                 :     {
    1014               4 :         if( poMin != NULL )
    1015                 :         {
    1016               4 :             if( poMin->eType == GFT_Integer )
    1017                 :             {
    1018               8 :                 while( iRow < nRowCount && dfValue < poMin->anValues[iRow] ) 
    1019               0 :                     iRow++;
    1020                 :             }
    1021               0 :             else if( poMin->eType == GFT_Real )
    1022                 :             {
    1023               0 :                 while( iRow < nRowCount && dfValue < poMin->adfValues[iRow] )
    1024               0 :                     iRow++;
    1025                 :             }
    1026                 : 
    1027               4 :             if( iRow == nRowCount )
    1028               0 :                 break;
    1029                 :         }
    1030                 : 
    1031               4 :         if( poMax != NULL )
    1032                 :         {
    1033               4 :             if( (poMax->eType == GFT_Integer 
    1034                 :                  && dfValue > poMax->anValues[iRow] ) 
    1035                 :                 || (poMax->eType == GFT_Real 
    1036                 :                     && dfValue > poMax->adfValues[iRow] ) )
    1037               2 :                 continue;
    1038                 :         }
    1039                 : 
    1040               2 :         return iRow;
    1041                 :     }
    1042                 : 
    1043               0 :     return -1;
    1044                 : }
    1045                 : 
    1046                 : /************************************************************************/
    1047                 : /*                           GetRowOfValue()                            */
    1048                 : /*                                                                      */
    1049                 : /*      Int arg for now just converted to double.  Perhaps we will      */
    1050                 : /*      handle this in a special way some day?                          */
    1051                 : /************************************************************************/
    1052                 : 
    1053               0 : int GDALRasterAttributeTable::GetRowOfValue( int nValue ) const
    1054                 : 
    1055                 : {
    1056               0 :     return GetRowOfValue( (double) nValue );
    1057                 : }
    1058                 : 
    1059                 : /************************************************************************/
    1060                 : /*                        GDALRATGetRowOfValue()                        */
    1061                 : /************************************************************************/
    1062                 : 
    1063                 : /**
    1064                 :  * \brief Get row for pixel value.
    1065                 :  *
    1066                 :  * This function is the same as the C++ method GDALRasterAttributeTable::GetRowOfValue()
    1067                 :  */
    1068                 : int CPL_STDCALL 
    1069               2 : GDALRATGetRowOfValue( GDALRasterAttributeTableH hRAT, double dfValue )
    1070                 : 
    1071                 : {
    1072               2 :     VALIDATE_POINTER1( hRAT, "GDALRATGetRowOfValue", 0 );
    1073                 : 
    1074               2 :     return ((GDALRasterAttributeTable *) hRAT)->GetRowOfValue( dfValue );
    1075                 : }
    1076                 : 
    1077                 : /************************************************************************/
    1078                 : /*                          SetLinearBinning()                          */
    1079                 : /************************************************************************/
    1080                 : 
    1081                 : /**
    1082                 :  * \brief Set linear binning information.
    1083                 :  *
    1084                 :  * For RATs with equal sized categories (in pixel value space) that are
    1085                 :  * evenly spaced, this method may be used to associate the linear binning
    1086                 :  * information with the table.
    1087                 :  *
    1088                 :  * This method is the same as the C function GDALRATSetLinearBinning().
    1089                 :  *
    1090                 :  * @param dfRow0MinIn the lower bound (pixel value) of the first category.
    1091                 :  * @param dfBinSizeIn the width of each category (in pixel value units). 
    1092                 :  *
    1093                 :  * @return CE_None on success or CE_Failure on failure.
    1094                 :  */
    1095                 : 
    1096                 : CPLErr GDALRasterAttributeTable::SetLinearBinning( double dfRow0MinIn, 
    1097              31 :                                                    double dfBinSizeIn )
    1098                 : 
    1099                 : {
    1100              31 :     bLinearBinning = TRUE;
    1101              31 :     dfRow0Min = dfRow0MinIn;
    1102              31 :     dfBinSize = dfBinSizeIn;
    1103                 : 
    1104              31 :     return CE_None;
    1105                 : }
    1106                 : 
    1107                 : /************************************************************************/
    1108                 : /*                      GDALRATSetLinearBinning()                       */
    1109                 : /************************************************************************/
    1110                 : 
    1111                 : /**
    1112                 :  * \brief Set linear binning information.
    1113                 :  *
    1114                 :  * This function is the same as the C++ method GDALRasterAttributeTable::SetLinearBinning()
    1115                 :  */
    1116                 : CPLErr CPL_STDCALL 
    1117                 : GDALRATSetLinearBinning( GDALRasterAttributeTableH hRAT, 
    1118               0 :                          double dfRow0Min, double dfBinSize )
    1119                 : 
    1120                 : {
    1121               0 :     VALIDATE_POINTER1( hRAT, "GDALRATSetLinearBinning", CE_Failure );
    1122                 : 
    1123                 :     return ((GDALRasterAttributeTable *) hRAT)->SetLinearBinning(
    1124               0 :         dfRow0Min, dfBinSize );
    1125                 : }
    1126                 : 
    1127                 : /************************************************************************/
    1128                 : /*                          GetLinearBinning()                          */
    1129                 : /************************************************************************/
    1130                 : 
    1131                 : /**
    1132                 :  * \brief Get linear binning information.
    1133                 :  *
    1134                 :  * Returns linear binning information if any is associated with the RAT.
    1135                 :  *
    1136                 :  * This method is the same as the C function GDALRATGetLinearBinning().
    1137                 :  *
    1138                 :  * @param pdfRow0Min (out) the lower bound (pixel value) of the first category.
    1139                 :  * @param pdfBinSize (out) the width of each category (in pixel value units).
    1140                 :  *
    1141                 :  * @return TRUE if linear binning information exists or FALSE if there is none.
    1142                 :  */
    1143                 : 
    1144                 : int GDALRasterAttributeTable::GetLinearBinning( double *pdfRow0Min,
    1145               0 :                                                 double *pdfBinSize ) const
    1146                 : 
    1147                 : {
    1148               0 :     if( !bLinearBinning )
    1149               0 :         return FALSE;
    1150                 : 
    1151               0 :     *pdfRow0Min = dfRow0Min;
    1152               0 :     *pdfBinSize = dfBinSize;
    1153                 : 
    1154               0 :     return TRUE;
    1155                 : }
    1156                 : 
    1157                 : /************************************************************************/
    1158                 : /*                      GDALRATGetLinearBinning()                       */
    1159                 : /************************************************************************/
    1160                 : 
    1161                 : /**
    1162                 :  * \brief Get linear binning information.
    1163                 :  *
    1164                 :  * This function is the same as the C++ method GDALRasterAttributeTable::GetLinearBinning()
    1165                 :  */
    1166                 : int CPL_STDCALL 
    1167                 : GDALRATGetLinearBinning( GDALRasterAttributeTableH hRAT, 
    1168               0 :                          double *pdfRow0Min, double *pdfBinSize )
    1169                 : 
    1170                 : {
    1171               0 :     VALIDATE_POINTER1( hRAT, "GDALRATGetLinearBinning", 0 );
    1172                 : 
    1173                 :     return ((GDALRasterAttributeTable *) hRAT)->GetLinearBinning(
    1174               0 :         pdfRow0Min, pdfBinSize );
    1175                 : }
    1176                 : 
    1177                 : /************************************************************************/
    1178                 : /*                            CreateColumn()                            */
    1179                 : /************************************************************************/
    1180                 : 
    1181                 : /**
    1182                 :  * \brief Create new column.
    1183                 :  *
    1184                 :  * If the table already has rows, all row values for the new column will
    1185                 :  * be initialized to the default value ("", or zero).  The new column is
    1186                 :  * always created as the last column, can will be column (field) 
    1187                 :  * "GetColumnCount()-1" after CreateColumn() has completed successfully.
    1188                 :  * 
    1189                 :  * This method is the same as the C function GDALRATCreateColumn().
    1190                 :  *
    1191                 :  * @param pszFieldName the name of the field to create.
    1192                 :  * @param eFieldType the field type (integer, double or string).
    1193                 :  * @param eFieldUsage the field usage, GFU_Generic if not known.
    1194                 :  *
    1195                 :  * @return CE_None on success or CE_Failure if something goes wrong.
    1196                 :  */
    1197                 : 
    1198                 : CPLErr GDALRasterAttributeTable::CreateColumn( const char *pszFieldName, 
    1199                 :                                                GDALRATFieldType eFieldType,
    1200              78 :                                                GDALRATFieldUsage eFieldUsage )
    1201                 : 
    1202                 : {
    1203              78 :     int iNewField = aoFields.size();
    1204                 : 
    1205              78 :     aoFields.resize( iNewField+1 );
    1206                 : 
    1207             156 :     aoFields[iNewField].sName = pszFieldName;
    1208              78 :     aoFields[iNewField].eType = eFieldType;
    1209              78 :     aoFields[iNewField].eUsage = eFieldUsage;
    1210                 : 
    1211              78 :     if( eFieldType == GFT_Integer )
    1212              26 :         aoFields[iNewField].anValues.resize( nRowCount );
    1213              52 :     else if( eFieldType == GFT_Real )
    1214              51 :         aoFields[iNewField].adfValues.resize( nRowCount );
    1215               1 :     else if( eFieldType == GFT_String )
    1216               1 :         aoFields[iNewField].aosValues.resize( nRowCount );
    1217                 : 
    1218              78 :     return CE_None;
    1219                 : }
    1220                 : 
    1221                 : /************************************************************************/
    1222                 : /*                        GDALRATCreateColumn()                         */
    1223                 : /************************************************************************/
    1224                 : 
    1225                 : /**
    1226                 :  * \brief Create new column.
    1227                 :  *
    1228                 :  * This function is the same as the C++ method GDALRasterAttributeTable::CreateColumn()
    1229                 :  */
    1230                 : CPLErr CPL_STDCALL GDALRATCreateColumn( GDALRasterAttributeTableH hRAT, 
    1231                 :                                         const char *pszFieldName, 
    1232                 :                                         GDALRATFieldType eFieldType,
    1233               2 :                                         GDALRATFieldUsage eFieldUsage )
    1234                 : 
    1235                 : {
    1236               2 :     VALIDATE_POINTER1( hRAT, "GDALRATCreateColumn", CE_Failure );
    1237                 : 
    1238                 :     return ((GDALRasterAttributeTable *) hRAT)->CreateColumn( pszFieldName, 
    1239                 :                                                               eFieldType,
    1240               2 :                                                               eFieldUsage );
    1241                 : }
    1242                 : 
    1243                 : /************************************************************************/
    1244                 : /*                      InitializeFromColorTable()                      */
    1245                 : /************************************************************************/
    1246                 : 
    1247                 : /**
    1248                 :  * \brief Initialize from color table.
    1249                 :  *
    1250                 :  * This method will setup a whole raster attribute table based on the
    1251                 :  * contents of the passed color table.  The Value (GFU_MinMax), 
    1252                 :  * Red (GFU_Red), Green (GFU_Green), Blue (GFU_Blue), and Alpha (GFU_Alpha)
    1253                 :  * fields are created, and a row is set for each entry in the color table. 
    1254                 :  * 
    1255                 :  * The raster attribute table must be empty before calling 
    1256                 :  * InitializeFromColorTable(). 
    1257                 :  *
    1258                 :  * The Value fields are set based on the implicit assumption with color
    1259                 :  * tables that entry 0 applies to pixel value 0, 1 to 1, etc. 
    1260                 :  *
    1261                 :  * This method is the same as the C function GDALRATInitializeFromColorTable().
    1262                 :  *
    1263                 :  * @param poTable the color table to copy from.
    1264                 :  *
    1265                 :  * @param CE_None on success or CE_Failure if something goes wrong.
    1266                 :  */
    1267                 : 
    1268                 : CPLErr GDALRasterAttributeTable::InitializeFromColorTable( 
    1269               0 :     const GDALColorTable *poTable )
    1270                 : 
    1271                 : {
    1272                 :     int iRow;
    1273                 : 
    1274               0 :     if( GetRowCount() > 0 || GetColumnCount() > 0 )
    1275                 :     {
    1276                 :         CPLError( CE_Failure, CPLE_AppDefined, 
    1277               0 :                   "Raster Attribute Table not empty in InitializeFromColorTable()" );
    1278               0 :         return CE_Failure;
    1279                 :     }
    1280                 : 
    1281               0 :     SetLinearBinning( 0.0, 1.0 );
    1282               0 :     CreateColumn( "Value", GFT_Integer, GFU_MinMax );
    1283               0 :     CreateColumn( "Red", GFT_Integer, GFU_Red );
    1284               0 :     CreateColumn( "Green", GFT_Integer, GFU_Green );
    1285               0 :     CreateColumn( "Blue", GFT_Integer, GFU_Blue );
    1286               0 :     CreateColumn( "Alpha", GFT_Integer, GFU_Alpha );
    1287                 : 
    1288               0 :     SetRowCount( poTable->GetColorEntryCount() );
    1289                 : 
    1290               0 :     for( iRow = 0; iRow < poTable->GetColorEntryCount(); iRow++ )
    1291                 :     {
    1292                 :         GDALColorEntry sEntry;
    1293                 : 
    1294               0 :         poTable->GetColorEntryAsRGB( iRow, &sEntry );
    1295                 : 
    1296               0 :         SetValue( iRow, 0, iRow );
    1297               0 :         SetValue( iRow, 1, sEntry.c1 );
    1298               0 :         SetValue( iRow, 2, sEntry.c2 );
    1299               0 :         SetValue( iRow, 3, sEntry.c3 );
    1300               0 :         SetValue( iRow, 4, sEntry.c4 );
    1301                 :     }
    1302                 : 
    1303               0 :     return CE_None;
    1304                 : }
    1305                 : 
    1306                 : /************************************************************************/
    1307                 : /*                  GDALRATInitializeFromColorTable()                   */
    1308                 : /************************************************************************/
    1309                 : 
    1310                 : /**
    1311                 :  * \brief Initialize from color table.
    1312                 :  *
    1313                 :  * This function is the same as the C++ method GDALRasterAttributeTable::InitializeFromColorTable()
    1314                 :  */
    1315                 : CPLErr CPL_STDCALL 
    1316                 : GDALRATInitializeFromColorTable( GDALRasterAttributeTableH hRAT,
    1317               0 :                                  GDALColorTableH hCT )
    1318                 :                                  
    1319                 : 
    1320                 : {
    1321               0 :     VALIDATE_POINTER1( hRAT, "GDALRATInitializeFromColorTable", CE_Failure );
    1322                 : 
    1323                 :     return ((GDALRasterAttributeTable *) hRAT)->
    1324               0 :         InitializeFromColorTable( (GDALColorTable *) hCT );
    1325                 : }
    1326                 : 
    1327                 : /************************************************************************/
    1328                 : /*                       TranslateToColorTable()                        */
    1329                 : /************************************************************************/
    1330                 : 
    1331                 : /**
    1332                 :  * \brief Translate to a color table.
    1333                 :  *
    1334                 :  * This method will attempt to create a corresponding GDALColorTable from
    1335                 :  * this raster attribute table. 
    1336                 :  * 
    1337                 :  * This method is the same as the C function GDALRATTranslateToColorTable().
    1338                 :  *
    1339                 :  * @param nEntryCount The number of entries to produce (0 to nEntryCount-1), or -1 to auto-determine the number of entries.
    1340                 :  *
    1341                 :  * @return the generated color table or NULL on failure.
    1342                 :  */
    1343                 : 
    1344                 : GDALColorTable *GDALRasterAttributeTable::TranslateToColorTable( 
    1345               0 :     int nEntryCount )
    1346                 : 
    1347                 : {
    1348                 : /* -------------------------------------------------------------------- */
    1349                 : /*      Establish which fields are red, green, blue and alpha.          */
    1350                 : /* -------------------------------------------------------------------- */
    1351                 :     int iRed, iGreen, iBlue, iAlpha;
    1352                 : 
    1353               0 :     iRed = GetColOfUsage( GFU_Red );
    1354               0 :     iGreen = GetColOfUsage( GFU_Green );
    1355               0 :     iBlue = GetColOfUsage( GFU_Blue );
    1356               0 :     iAlpha = GetColOfUsage( GFU_Alpha );
    1357                 : 
    1358               0 :     if( iRed == -1 || iGreen == -1 || iBlue == -1 )
    1359               0 :         return NULL;
    1360                 : 
    1361                 : /* -------------------------------------------------------------------- */
    1362                 : /*      If we aren't given an explicit number of values to scan for,    */
    1363                 : /*      search for the maximum "max" value.                             */
    1364                 : /* -------------------------------------------------------------------- */
    1365               0 :     if( nEntryCount == -1 )
    1366                 :     {
    1367                 :         int  iRow;
    1368                 :         int  iMaxCol;
    1369                 : 
    1370               0 :         iMaxCol = GetColOfUsage( GFU_Max );
    1371               0 :         if( iMaxCol == -1 )
    1372               0 :             iMaxCol = GetColOfUsage( GFU_MinMax );
    1373                 : 
    1374               0 :         if( iMaxCol == -1 || nRowCount == 0 )
    1375               0 :             return NULL;
    1376                 :     
    1377               0 :         for( iRow = 0; iRow < nRowCount; iRow++ )
    1378               0 :             nEntryCount = MAX(nEntryCount,GetValueAsInt(iRow,iMaxCol)+1);
    1379                 : 
    1380               0 :         if( nEntryCount < 0 )
    1381               0 :             return NULL;
    1382                 : 
    1383                 :         // restrict our number of entries to something vaguely sensible
    1384               0 :         nEntryCount = MIN(65535,nEntryCount);
    1385                 :     }
    1386                 : 
    1387                 : /* -------------------------------------------------------------------- */
    1388                 : /*      Assign values to color table.                                   */
    1389                 : /* -------------------------------------------------------------------- */
    1390               0 :     GDALColorTable *poCT = new GDALColorTable();
    1391                 :     int iEntry;
    1392                 : 
    1393               0 :     for( iEntry = 0; iEntry < nEntryCount; iEntry++ )
    1394                 :     {
    1395                 :         GDALColorEntry sColor;
    1396               0 :         int iRow = GetRowOfValue( iEntry );
    1397                 : 
    1398               0 :         if( iRow == -1 )
    1399                 :         {
    1400               0 :             sColor.c1 = sColor.c2 = sColor.c3 = sColor.c4 = 0;
    1401                 :         }
    1402                 :         else
    1403                 :         {
    1404               0 :             sColor.c1 = GetValueAsInt( iRow, iRed );
    1405               0 :             sColor.c2 = GetValueAsInt( iRow, iGreen );
    1406               0 :             sColor.c3 = GetValueAsInt( iRow, iBlue );
    1407               0 :             if( iAlpha == -1 )
    1408               0 :                 sColor.c4 = 255;
    1409                 :             else
    1410               0 :                 sColor.c4 = GetValueAsInt( iRow, iAlpha );
    1411                 :         }
    1412                 :         
    1413               0 :         poCT->SetColorEntry( iEntry, &sColor );
    1414                 :     }
    1415                 : 
    1416               0 :     return poCT;
    1417                 : }
    1418                 : 
    1419                 : /************************************************************************/
    1420                 : /*                  GDALRATInitializeFromColorTable()                   */
    1421                 : /************************************************************************/
    1422                 : 
    1423                 : /**
    1424                 :  * \brief Translate to a color table.
    1425                 :  *
    1426                 :  * This function is the same as the C++ method GDALRasterAttributeTable::TranslateToColorTable()
    1427                 :  */
    1428                 : GDALColorTableH CPL_STDCALL 
    1429                 : GDALRATTranslateToColorTable( GDALRasterAttributeTableH hRAT,
    1430               0 :                               int nEntryCount )
    1431                 :                                  
    1432                 : 
    1433                 : {
    1434               0 :     VALIDATE_POINTER1( hRAT, "GDALRATTranslateToColorTable", NULL );
    1435                 : 
    1436                 :     return ((GDALRasterAttributeTable *) hRAT)->
    1437               0 :         TranslateToColorTable( nEntryCount );
    1438                 : }
    1439                 : 
    1440                 : /************************************************************************/
    1441                 : /*                              XMLInit()                               */
    1442                 : /************************************************************************/
    1443                 : 
    1444                 : CPLErr GDALRasterAttributeTable::XMLInit( CPLXMLNode *psTree, 
    1445               4 :                                           const char * /*pszVRTPath*/ )
    1446                 : 
    1447                 : {
    1448               4 :     CPLAssert( GetRowCount() == 0 && GetColumnCount() == 0 );
    1449                 :     
    1450                 : /* -------------------------------------------------------------------- */
    1451                 : /*      Linear binning.                                                 */
    1452                 : /* -------------------------------------------------------------------- */
    1453               4 :     if( CPLGetXMLValue( psTree, "Row0Min", NULL ) 
    1454                 :         && CPLGetXMLValue( psTree, "BinSize", NULL ) )
    1455                 :     {
    1456                 :         SetLinearBinning( atof(CPLGetXMLValue( psTree, "Row0Min","" )), 
    1457               0 :                           atof(CPLGetXMLValue( psTree, "BinSize","" )) );
    1458                 :     }
    1459                 : 
    1460                 : /* -------------------------------------------------------------------- */
    1461                 : /*      Column definitions                                              */
    1462                 : /* -------------------------------------------------------------------- */
    1463                 :     CPLXMLNode *psChild;
    1464                 : 
    1465             248 :     for( psChild = psTree->psChild; psChild != NULL; psChild = psChild->psNext)
    1466                 :     {
    1467             244 :         if( psChild->eType == CXT_Element 
    1468                 :             && EQUAL(psChild->pszValue,"FieldDefn") )
    1469                 :         {
    1470                 :             CreateColumn( 
    1471                 :               CPLGetXMLValue( psChild, "Name", "" ), 
    1472                 :               (GDALRATFieldType) atoi(CPLGetXMLValue( psChild, "Type", "1" )),
    1473               8 :               (GDALRATFieldUsage) atoi(CPLGetXMLValue( psChild, "Usage","0")));
    1474                 :         }
    1475                 :     }
    1476                 :     
    1477                 : /* -------------------------------------------------------------------- */
    1478                 : /*      Row data.                                                       */
    1479                 : /* -------------------------------------------------------------------- */
    1480             248 :     for( psChild = psTree->psChild; psChild != NULL; psChild = psChild->psNext)
    1481                 :     {
    1482             244 :         if( psChild->eType == CXT_Element 
    1483                 :             && EQUAL(psChild->pszValue,"Row") )
    1484                 :         {
    1485             236 :             int iRow = atoi(CPLGetXMLValue(psChild,"index","0"));
    1486             236 :             int iField = 0;
    1487                 :             CPLXMLNode *psF;
    1488                 : 
    1489             944 :             for( psF = psChild->psChild; psF != NULL; psF = psF->psNext )
    1490                 :             {
    1491             708 :                 if( psF->eType != CXT_Element || !EQUAL(psF->pszValue,"F") )
    1492             236 :                     continue;
    1493                 : 
    1494             944 :                 if( psF->psChild != NULL && psF->psChild->eType == CXT_Text )
    1495             472 :                     SetValue( iRow, iField++, psF->psChild->pszValue );
    1496                 :                 else
    1497               0 :                     SetValue( iRow, iField++, "" );
    1498                 :             }
    1499                 :         }
    1500                 :     }
    1501                 : 
    1502               4 :     return CE_None;
    1503                 : }
    1504                 : 
    1505                 : /************************************************************************/
    1506                 : /*                             Serialize()                              */
    1507                 : /************************************************************************/
    1508                 : 
    1509               4 : CPLXMLNode *GDALRasterAttributeTable::Serialize() const
    1510                 : 
    1511                 : {
    1512               4 :     CPLXMLNode *psTree = NULL;
    1513               4 :     CPLXMLNode *psRow = NULL;
    1514                 : 
    1515               4 :     psTree = CPLCreateXMLNode( NULL, CXT_Element, "GDALRasterAttributeTable" );
    1516                 : 
    1517                 : /* -------------------------------------------------------------------- */
    1518                 : /*      Add attributes with regular binning info if appropriate.        */
    1519                 : /* -------------------------------------------------------------------- */
    1520                 :     char szValue[128];
    1521                 : 
    1522               4 :     if( bLinearBinning )
    1523                 :     {
    1524               2 :         sprintf( szValue, "%.16g", dfRow0Min );
    1525                 :         CPLCreateXMLNode( 
    1526                 :             CPLCreateXMLNode( psTree, CXT_Attribute, "Row0Min" ), 
    1527               2 :             CXT_Text, szValue );
    1528                 : 
    1529               2 :         sprintf( szValue, "%.16g", dfBinSize );
    1530                 :         CPLCreateXMLNode( 
    1531                 :             CPLCreateXMLNode( psTree, CXT_Attribute, "BinSize" ), 
    1532               2 :             CXT_Text, szValue );
    1533                 :     }
    1534                 : 
    1535                 : /* -------------------------------------------------------------------- */
    1536                 : /*      Define each column.                                             */
    1537                 : /* -------------------------------------------------------------------- */
    1538                 :     int iCol;
    1539                 : 
    1540              10 :     for( iCol = 0; iCol < (int) aoFields.size(); iCol++ )
    1541                 :     {
    1542                 :         CPLXMLNode *psCol;
    1543                 : 
    1544               6 :         psCol = CPLCreateXMLNode( psTree, CXT_Element, "FieldDefn" );
    1545                 :         
    1546               6 :         sprintf( szValue, "%d", iCol );
    1547                 :         CPLCreateXMLNode( 
    1548                 :             CPLCreateXMLNode( psCol, CXT_Attribute, "index" ), 
    1549               6 :             CXT_Text, szValue );
    1550                 : 
    1551                 :         CPLCreateXMLElementAndValue( psCol, "Name", 
    1552               6 :                                      aoFields[iCol].sName.c_str() );
    1553                 : 
    1554               6 :         sprintf( szValue, "%d", (int) aoFields[iCol].eType );
    1555               6 :         CPLCreateXMLElementAndValue( psCol, "Type", szValue );
    1556                 : 
    1557               6 :         sprintf( szValue, "%d", (int) aoFields[iCol].eUsage );
    1558               6 :         CPLCreateXMLElementAndValue( psCol, "Usage", szValue );
    1559                 :     }
    1560                 : 
    1561                 : /* -------------------------------------------------------------------- */
    1562                 : /*      Write out each row.                                             */
    1563                 : /* -------------------------------------------------------------------- */
    1564                 :     int iRow;
    1565               4 :     CPLXMLNode *psTail = NULL;
    1566                 : 
    1567             595 :     for( iRow = 0; iRow < nRowCount; iRow++ )
    1568                 :     {
    1569             591 :         psRow = CPLCreateXMLNode( NULL, CXT_Element, "Row" );
    1570             591 :         if( psTail == NULL )
    1571               4 :             CPLAddXMLChild( psTree, psRow );
    1572                 :         else
    1573             587 :             psTail->psNext = psRow;
    1574             591 :         psTail = psRow;
    1575                 : 
    1576             591 :         sprintf( szValue, "%d", iRow );
    1577                 :         CPLCreateXMLNode( 
    1578                 :             CPLCreateXMLNode( psRow, CXT_Attribute, "index" ), 
    1579             591 :             CXT_Text, szValue );
    1580                 : 
    1581            1300 :         for( iCol = 0; iCol < (int) aoFields.size(); iCol++ )
    1582                 :         {
    1583             709 :             const char *pszValue = szValue;
    1584                 : 
    1585             709 :             if( aoFields[iCol].eType == GFT_Integer )
    1586             121 :                 sprintf( szValue, "%d", aoFields[iCol].anValues[iRow] );
    1587             588 :             else if( aoFields[iCol].eType == GFT_Real )
    1588             588 :                 sprintf( szValue, "%.16g", aoFields[iCol].adfValues[iRow] );
    1589                 :             else
    1590               0 :                 pszValue = aoFields[iCol].aosValues[iRow].c_str();
    1591                 : 
    1592             709 :             CPLCreateXMLElementAndValue( psRow, "F", pszValue );
    1593                 :         }
    1594                 :     }
    1595                 : 
    1596               4 :     return psTree;
    1597                 : }
    1598                 : 
    1599                 : /************************************************************************/
    1600                 : /*                            DumpReadable()                            */
    1601                 : /************************************************************************/
    1602                 : 
    1603                 : /**
    1604                 :  * \brief Dump RAT in readable form.
    1605                 :  *
    1606                 :  * Currently the readable form is the XML encoding ... only barely 
    1607                 :  * readable. 
    1608                 :  *
    1609                 :  * This method is the same as the C function GDALRATDumpReadable().
    1610                 :  *
    1611                 :  * @param fp file to dump to or NULL for stdout. 
    1612                 :  */
    1613                 : 
    1614               1 : void GDALRasterAttributeTable::DumpReadable( FILE * fp )
    1615                 : 
    1616                 : {
    1617               1 :     CPLXMLNode *psTree = Serialize();
    1618               1 :     char *pszXMLText = CPLSerializeXMLTree( psTree );
    1619                 : 
    1620               1 :     CPLDestroyXMLNode( psTree );
    1621                 : 
    1622               1 :     if( fp == NULL )
    1623               1 :         fp = stdout;
    1624                 : 
    1625               1 :     fprintf( fp, "%s\n", pszXMLText );
    1626                 : 
    1627               1 :     CPLFree( pszXMLText );
    1628               1 : }
    1629                 : 
    1630                 : /************************************************************************/
    1631                 : /*                        GDALRATDumpReadable()                         */
    1632                 : /************************************************************************/
    1633                 : 
    1634                 : /**
    1635                 :  * \brief Dump RAT in readable form.
    1636                 :  *
    1637                 :  * This function is the same as the C++ method GDALRasterAttributeTable::DumpReadable()
    1638                 :  */
    1639                 : void CPL_STDCALL 
    1640               1 : GDALRATDumpReadable( GDALRasterAttributeTableH hRAT, FILE *fp )
    1641                 : 
    1642                 : {
    1643               1 :     VALIDATE_POINTER0( hRAT, "GDALRATDumpReadable" );
    1644                 : 
    1645               1 :     ((GDALRasterAttributeTable *) hRAT)->DumpReadable( fp );
    1646                 : }
    1647                 : 
    1648                 : /************************************************************************/
    1649                 : /*                               Clone()                                */
    1650                 : /************************************************************************/
    1651                 : 
    1652                 : /**
    1653                 :  * \brief Copy Raster Attribute Table
    1654                 :  *
    1655                 :  * Creates a new copy of an existing raster attribute table.  The new copy
    1656                 :  * becomes the responsibility of the caller to destroy.
    1657                 :  *
    1658                 :  * This method is the same as the C function GDALRATClone().
    1659                 :  *
    1660                 :  * @return new copy of the RAT. 
    1661                 :  */
    1662                 : 
    1663               5 : GDALRasterAttributeTable *GDALRasterAttributeTable::Clone() const
    1664                 : 
    1665                 : {
    1666               5 :     return new GDALRasterAttributeTable( *this );
    1667                 : }
    1668                 : 
    1669                 : /************************************************************************/
    1670                 : /*                            GDALRATClone()                            */
    1671                 : /************************************************************************/
    1672                 : 
    1673                 : /**
    1674                 :  * \brief Copy Raster Attribute Table
    1675                 :  *
    1676                 :  * This function is the same as the C++ method GDALRasterAttributeTable::Clone()
    1677                 :  */
    1678                 : GDALRasterAttributeTableH CPL_STDCALL 
    1679               1 : GDALRATClone( GDALRasterAttributeTableH hRAT )
    1680                 : 
    1681                 : {
    1682               1 :     VALIDATE_POINTER1( hRAT, "GDALRATClone", NULL );
    1683                 : 
    1684               1 :     return ((GDALRasterAttributeTable *) hRAT)->Clone();
    1685                 : }

Generated by: LTP GCOV extension version 1.5