LCOV - code coverage report
Current view: top level - frmts/pcraster - pcrasterrasterband.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 44 158 27.8 %
Date: 2024-05-02 00:41:30 Functions: 7 10 70.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  PCRaster Integration
       4             :  * Purpose:  PCRaster raster band implementation.
       5             :  * Author:   Kor de Jong, Oliver Schmitz
       6             :  *
       7             :  ******************************************************************************
       8             :  * Copyright (c) PCRaster owners
       9             :  *
      10             :  * Permission is hereby granted, free of charge, to any person obtaining a
      11             :  * copy of this software and associated documentation files (the "Software"),
      12             :  * to deal in the Software without restriction, including without limitation
      13             :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      14             :  * and/or sell copies of the Software, and to permit persons to whom the
      15             :  * Software is furnished to do so, subject to the following conditions:
      16             :  *
      17             :  * The above copyright notice and this permission notice shall be included
      18             :  * in all copies or substantial portions of the Software.
      19             :  *
      20             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      21             :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      22             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      23             :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      24             :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      25             :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      26             :  * DEALINGS IN THE SOFTWARE.
      27             :  ****************************************************************************/
      28             : 
      29             : #include "csf.h"
      30             : #include "csfimpl.h"
      31             : #include "pcrasterdataset.h"
      32             : #include "pcrasterrasterband.h"
      33             : #include "pcrasterutil.h"
      34             : 
      35             : /*!
      36             :   \file
      37             :   This file contains the implementation of the PCRasterRasterBand class.
      38             : */
      39             : 
      40             : //------------------------------------------------------------------------------
      41             : // DEFINITION OF PCRRASTERBAND MEMBERS
      42             : //------------------------------------------------------------------------------
      43             : 
      44             : //! Constructor.
      45             : /*!
      46             :   \param     dataset The dataset we are a part of.
      47             : */
      48          13 : PCRasterRasterBand::PCRasterRasterBand(PCRasterDataset *dataset)
      49             :     : GDALPamRasterBand(), d_dataset(dataset), d_noDataValue(),
      50          13 :       d_defaultNoDataValueOverridden(false), d_create_in(GDT_Unknown)
      51             : {
      52          13 :     poDS = dataset;
      53          13 :     nBand = 1;
      54          13 :     eDataType = cellRepresentation2GDALType(dataset->cellRepresentation());
      55          13 :     nBlockXSize = dataset->GetRasterXSize();
      56          13 :     nBlockYSize = 1;
      57          13 : }
      58             : 
      59             : //! Destructor.
      60             : /*!
      61             :  */
      62          26 : PCRasterRasterBand::~PCRasterRasterBand()
      63             : {
      64          26 : }
      65             : 
      66         455 : double PCRasterRasterBand::GetNoDataValue(int *success)
      67             : {
      68         455 :     if (success)
      69             :     {
      70          12 :         *success = 1;
      71             :     }
      72             : 
      73         455 :     return d_defaultNoDataValueOverridden ? d_noDataValue
      74         455 :                                           : d_dataset->defaultNoDataValue();
      75             : }
      76             : 
      77           0 : double PCRasterRasterBand::GetMinimum(int *success)
      78             : {
      79             :     double result;
      80             :     bool isValid;
      81             : 
      82           0 :     switch (d_dataset->cellRepresentation())
      83             :     {
      84             :         // CSF version 2.
      85             :         // ----------------------------------------------------------
      86           0 :         case CR_UINT1:
      87             :         {
      88             :             UINT1 min;
      89           0 :             isValid = CPL_TO_BOOL(RgetMinVal(d_dataset->map(), &min));
      90           0 :             result = static_cast<double>(min);
      91           0 :             break;
      92             :         }
      93           0 :         case CR_INT4:
      94             :         {
      95             :             INT4 min;
      96           0 :             isValid = CPL_TO_BOOL(RgetMinVal(d_dataset->map(), &min));
      97           0 :             result = static_cast<double>(min);
      98           0 :             break;
      99             :         }
     100           0 :         case CR_REAL4:
     101             :         {
     102             :             REAL4 min;
     103           0 :             isValid = CPL_TO_BOOL(RgetMinVal(d_dataset->map(), &min));
     104           0 :             result = static_cast<double>(min);
     105           0 :             break;
     106             :         }
     107           0 :         case CR_REAL8:
     108             :         {
     109             :             REAL8 min;
     110           0 :             isValid = CPL_TO_BOOL(RgetMinVal(d_dataset->map(), &min));
     111           0 :             result = static_cast<double>(min);
     112           0 :             break;
     113             :         }
     114             :         // CSF version 1.
     115             :         // ----------------------------------------------------------
     116           0 :         case CR_INT1:
     117             :         {
     118             :             INT1 min;
     119           0 :             isValid = CPL_TO_BOOL(RgetMinVal(d_dataset->map(), &min));
     120           0 :             result = static_cast<double>(min);
     121           0 :             break;
     122             :         }
     123           0 :         case CR_INT2:
     124             :         {
     125             :             INT2 min;
     126           0 :             isValid = CPL_TO_BOOL(RgetMinVal(d_dataset->map(), &min));
     127           0 :             result = static_cast<double>(min);
     128           0 :             break;
     129             :         }
     130           0 :         case CR_UINT2:
     131             :         {
     132             :             UINT2 min;
     133           0 :             isValid = CPL_TO_BOOL(RgetMinVal(d_dataset->map(), &min));
     134           0 :             result = static_cast<double>(min);
     135           0 :             break;
     136             :         }
     137           0 :         case CR_UINT4:
     138             :         {
     139             :             UINT4 min;
     140           0 :             isValid = CPL_TO_BOOL(RgetMinVal(d_dataset->map(), &min));
     141           0 :             result = static_cast<double>(min);
     142           0 :             break;
     143             :         }
     144           0 :         default:
     145             :         {
     146           0 :             result = 0.0;
     147           0 :             isValid = false;
     148           0 :             break;
     149             :         }
     150             :     }
     151             : 
     152           0 :     if (success)
     153             :     {
     154           0 :         *success = isValid ? 1 : 0;
     155             :     }
     156             : 
     157           0 :     return result;
     158             : }
     159             : 
     160           0 : double PCRasterRasterBand::GetMaximum(int *success)
     161             : {
     162             :     double result;
     163             :     bool isValid;
     164             : 
     165           0 :     switch (d_dataset->cellRepresentation())
     166             :     {
     167           0 :         case CR_UINT1:
     168             :         {
     169             :             UINT1 max;
     170           0 :             isValid = CPL_TO_BOOL(RgetMaxVal(d_dataset->map(), &max));
     171           0 :             result = static_cast<double>(max);
     172           0 :             break;
     173             :         }
     174           0 :         case CR_INT4:
     175             :         {
     176             :             INT4 max;
     177           0 :             isValid = CPL_TO_BOOL(RgetMaxVal(d_dataset->map(), &max));
     178           0 :             result = static_cast<double>(max);
     179           0 :             break;
     180             :         }
     181           0 :         case CR_REAL4:
     182             :         {
     183             :             REAL4 max;
     184           0 :             isValid = CPL_TO_BOOL(RgetMaxVal(d_dataset->map(), &max));
     185           0 :             result = static_cast<double>(max);
     186           0 :             break;
     187             :         }
     188             :         // CSF version 1.
     189             :         // ----------------------------------------------------------
     190           0 :         case CR_INT1:
     191             :         {
     192             :             INT1 max;
     193           0 :             isValid = CPL_TO_BOOL(RgetMaxVal(d_dataset->map(), &max));
     194           0 :             result = static_cast<double>(max);
     195           0 :             break;
     196             :         }
     197           0 :         case CR_INT2:
     198             :         {
     199             :             INT2 max;
     200           0 :             isValid = CPL_TO_BOOL(RgetMaxVal(d_dataset->map(), &max));
     201           0 :             result = static_cast<double>(max);
     202           0 :             break;
     203             :         }
     204           0 :         case CR_UINT2:
     205             :         {
     206             :             UINT2 max;
     207           0 :             isValid = CPL_TO_BOOL(RgetMaxVal(d_dataset->map(), &max));
     208           0 :             result = static_cast<double>(max);
     209           0 :             break;
     210             :         }
     211           0 :         case CR_UINT4:
     212             :         {
     213             :             UINT4 max;
     214           0 :             isValid = CPL_TO_BOOL(RgetMaxVal(d_dataset->map(), &max));
     215           0 :             result = static_cast<double>(max);
     216           0 :             break;
     217             :         }
     218           0 :         default:
     219             :         {
     220           0 :             result = 0.0;
     221           0 :             isValid = false;
     222           0 :             break;
     223             :         }
     224             :     }
     225             : 
     226           0 :     if (success)
     227             :     {
     228           0 :         *success = isValid ? 1 : 0;
     229             :     }
     230             : 
     231           0 :     return result;
     232             : }
     233             : 
     234         420 : CPLErr PCRasterRasterBand::IReadBlock(CPL_UNUSED int nBlockXoff, int nBlockYoff,
     235             :                                       void *buffer)
     236             : {
     237         420 :     size_t nrCellsRead = RgetRow(d_dataset->map(), nBlockYoff, buffer);
     238             : 
     239             :     // Now we have raw values, missing values are set according to the CSF
     240             :     // conventions. This means that floating points should not be evaluated.
     241             :     // Since this is done by the GDal library we replace these with valid
     242             :     // values. Non-MV values are not touched.
     243             : 
     244             :     // Replace in-file MV with in-app MV which may be different.
     245         420 :     alterFromStdMV(buffer, nrCellsRead, d_dataset->cellRepresentation(),
     246             :                    GetNoDataValue());
     247             : 
     248         420 :     return CE_None;
     249             : }
     250             : 
     251         441 : CPLErr PCRasterRasterBand::IRasterIO(GDALRWFlag eRWFlag, int nXOff, int nYOff,
     252             :                                      int nXSize, int nYSize, void *pData,
     253             :                                      int nBufXSize, int nBufYSize,
     254             :                                      GDALDataType eBufType,
     255             :                                      GSpacing nPixelSpace, GSpacing nLineSpace,
     256             :                                      GDALRasterIOExtraArg *psExtraArg)
     257             : {
     258         441 :     if (eRWFlag == GF_Read)
     259             :     {
     260             :         // read should just be the default
     261         440 :         return GDALRasterBand::IRasterIO(GF_Read, nXOff, nYOff, nXSize, nYSize,
     262             :                                          pData, nBufXSize, nBufYSize, eBufType,
     263         440 :                                          nPixelSpace, nLineSpace, psExtraArg);
     264             :     }
     265             :     else
     266             :     {
     267             :         // the datatype of the incoming data can be of different type than the
     268             :         // cell representation used in the raster
     269             :         // 'remember' the GDAL type to distinguish it later on in iWriteBlock
     270           1 :         d_create_in = eBufType;
     271           1 :         return GDALRasterBand::IRasterIO(GF_Write, nXOff, nYOff, nXSize, nYSize,
     272             :                                          pData, nBufXSize, nBufYSize, eBufType,
     273           1 :                                          nPixelSpace, nLineSpace, psExtraArg);
     274             :     }
     275             : }
     276             : 
     277          20 : CPLErr PCRasterRasterBand::IWriteBlock(CPL_UNUSED int nBlockXoff,
     278             :                                        int nBlockYoff, void *source)
     279             : {
     280          20 :     CSF_VS valuescale = d_dataset->valueScale();
     281             : 
     282          20 :     if (valuescale == VS_LDD)
     283             :     {
     284           0 :         if ((d_create_in == GDT_Byte) || (d_create_in == GDT_Float32) ||
     285           0 :             (d_create_in == GDT_Float64))
     286             :         {
     287           0 :             CPLError(CE_Failure, CPLE_NotSupported,
     288             :                      "PCRaster driver: "
     289             :                      "conversion from %s to LDD not supported",
     290             :                      GDALGetDataTypeName(d_create_in));
     291           0 :             return CE_Failure;
     292             :         }
     293             :     }
     294             : 
     295             :     // set new location attributes to the header
     296          20 :     if (d_dataset->location_changed())
     297             :     {
     298           0 :         REAL8 west = 0.0;
     299           0 :         REAL8 north = 0.0;
     300           0 :         REAL8 cellSize = 1.0;
     301             :         double transform[6];
     302           0 :         if (this->poDS->GetGeoTransform(transform) == CE_None)
     303             :         {
     304           0 :             if (transform[2] == 0.0 && transform[4] == 0.0)
     305             :             {
     306           0 :                 west = static_cast<REAL8>(transform[0]);
     307           0 :                 north = static_cast<REAL8>(transform[3]);
     308           0 :                 cellSize = static_cast<REAL8>(transform[1]);
     309             :             }
     310             :         }
     311           0 :         (void)RputXUL(d_dataset->map(), west);
     312           0 :         (void)RputYUL(d_dataset->map(), north);
     313           0 :         (void)RputCellSize(d_dataset->map(), cellSize);
     314             :     }
     315             : 
     316          20 :     const int nr_cols = this->poDS->GetRasterXSize();
     317             : 
     318             :     // new maps from create() set min/max to MV
     319             :     // in case of reopening that map the min/max
     320             :     // value tracking is disabled (MM_WRONGVALUE)
     321             :     // reactivate it again to ensure that the output will
     322             :     // get the correct values when values are written to map
     323          20 :     d_dataset->map()->minMaxStatus = MM_KEEPTRACK;
     324             : 
     325             :     // allocate memory for row
     326          20 :     void *buffer = Rmalloc(d_dataset->map(), nr_cols);
     327          20 :     memcpy(buffer, source, nr_cols * 4);
     328             : 
     329             :     // convert source no_data values to MV in dest
     330          20 :     switch (valuescale)
     331             :     {
     332           0 :         case VS_BOOLEAN:
     333             :         case VS_LDD:
     334             :         {
     335           0 :             alterToStdMV(buffer, nr_cols, CR_UINT1, GetNoDataValue());
     336           0 :             break;
     337             :         }
     338           0 :         case VS_NOMINAL:
     339             :         case VS_ORDINAL:
     340             :         {
     341           0 :             alterToStdMV(buffer, nr_cols, CR_INT4, GetNoDataValue());
     342           0 :             break;
     343             :         }
     344          20 :         case VS_SCALAR:
     345             :         case VS_DIRECTION:
     346             :         {
     347          20 :             alterToStdMV(buffer, nr_cols, CR_REAL4, GetNoDataValue());
     348          20 :             break;
     349             :         }
     350           0 :         default:
     351             :         {
     352           0 :             break;
     353             :         }
     354             :     }
     355             : 
     356             :     // conversion of values according to value scale
     357          20 :     switch (valuescale)
     358             :     {
     359           0 :         case VS_BOOLEAN:
     360             :         {
     361           0 :             castValuesToBooleanRange(buffer, nr_cols, CR_UINT1);
     362           0 :             break;
     363             :         }
     364           0 :         case VS_LDD:
     365             :         {
     366           0 :             castValuesToLddRange(buffer, nr_cols);
     367           0 :             break;
     368             :         }
     369           0 :         case VS_DIRECTION:
     370             :         {
     371           0 :             castValuesToDirectionRange(buffer, nr_cols);
     372           0 :             break;
     373             :         }
     374          20 :         default:
     375             :         {
     376          20 :             break;
     377             :         }
     378             :     }
     379             : 
     380          20 :     RputRow(d_dataset->map(), nBlockYoff, buffer);
     381          20 :     free(buffer);
     382             : 
     383          20 :     return CE_None;
     384             : }
     385             : 
     386           0 : CPLErr PCRasterRasterBand::SetNoDataValue(double nodata)
     387             : {
     388           0 :     d_noDataValue = nodata;
     389           0 :     d_defaultNoDataValueOverridden = true;
     390             : 
     391           0 :     return CE_None;
     392             : }

Generated by: LCOV version 1.14