LCOV - code coverage report
Current view: directory - ogr/ogrsf_frmts/ntf - ntf_raster.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 138 2 1.4 %
Date: 2011-12-18 Functions: 15 1 6.7 %

       1                 : /******************************************************************************
       2                 :  * $Id: ntf_raster.cpp 21977 2011-03-18 19:53:18Z warmerdam $
       3                 :  *
       4                 :  * Project:  NTF Translator
       5                 :  * Purpose:  Handle UK Ordnance Survey Raster DTM products.  Includes some
       6                 :  *           raster related methods from NTFFileReader and the implementation
       7                 :  *           of OGRNTFRasterLayer.
       8                 :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       9                 :  *
      10                 :  ******************************************************************************
      11                 :  * Copyright (c) 1999, Frank Warmerdam
      12                 :  *
      13                 :  * Permission is hereby granted, free of charge, to any person obtaining a
      14                 :  * copy of this software and associated documentation files (the "Software"),
      15                 :  * to deal in the Software without restriction, including without limitation
      16                 :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      17                 :  * and/or sell copies of the Software, and to permit persons to whom the
      18                 :  * Software is furnished to do so, subject to the following conditions:
      19                 :  *
      20                 :  * The above copyright notice and this permission notice shall be included
      21                 :  * in all copies or substantial portions of the Software.
      22                 :  *
      23                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      24                 :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      25                 :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      26                 :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      27                 :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      28                 :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      29                 :  * DEALINGS IN THE SOFTWARE.
      30                 :  ****************************************************************************/
      31                 : 
      32                 : #include "ntf.h"
      33                 : 
      34                 : CPL_CVSID("$Id: ntf_raster.cpp 21977 2011-03-18 19:53:18Z warmerdam $");
      35                 : 
      36                 : /************************************************************************/
      37                 : /* ==================================================================== */
      38                 : /*                     NTFFileReader Raster Methods                     */
      39                 : /* ==================================================================== */
      40                 : /************************************************************************/
      41                 : 
      42                 : /************************************************************************/
      43                 : /*                          IsRasterProduct()                           */
      44                 : /************************************************************************/
      45                 : 
      46           31226 : int NTFFileReader::IsRasterProduct()
      47                 : 
      48                 : {
      49                 :     return GetProductId() == NPC_LANDRANGER_DTM
      50           31226 :         || GetProductId() == NPC_LANDFORM_PROFILE_DTM;
      51                 : }
      52                 : 
      53                 : /************************************************************************/
      54                 : /*                       EstablishRasterAccess()                        */
      55                 : /************************************************************************/
      56                 : 
      57               0 : void NTFFileReader::EstablishRasterAccess()
      58                 : 
      59                 : {
      60                 : /* -------------------------------------------------------------------- */
      61                 : /*      Read the type 50 record.                                        */
      62                 : /* -------------------------------------------------------------------- */
      63                 :     NTFRecord   *poRecord;
      64                 : 
      65               0 :     while( (poRecord = ReadRecord()) != NULL
      66                 :            && poRecord->GetType() != NRT_GRIDHREC
      67                 :            && poRecord->GetType() != NRT_VTR )
      68                 :     {
      69               0 :         delete poRecord;
      70                 :     }
      71                 : 
      72               0 :     if( poRecord->GetType() != NRT_GRIDHREC )
      73                 :     {
      74               0 :         delete poRecord;
      75                 :         CPLError( CE_Failure, CPLE_AppDefined,
      76                 :                   "Unable to find GRIDHREC (type 50) record in what appears\n"
      77               0 :                   "to be an NTF Raster DTM product." );
      78               0 :         return;
      79                 :     }
      80                 : 
      81                 : /* -------------------------------------------------------------------- */
      82                 : /*      Parse if LANDRANGER_DTM                                         */
      83                 : /* -------------------------------------------------------------------- */
      84               0 :     if( GetProductId() == NPC_LANDRANGER_DTM )
      85                 :     {
      86               0 :         nRasterXSize = atoi(poRecord->GetField(13,16));
      87               0 :         nRasterYSize = atoi(poRecord->GetField(17,20));
      88                 : 
      89                 :         // NOTE: unusual use of GeoTransform - the pixel origin is the
      90                 :         // bottom left corner!
      91               0 :         adfGeoTransform[0] = atoi(poRecord->GetField(25,34));
      92               0 :         adfGeoTransform[1] = 50;
      93               0 :         adfGeoTransform[2] = 0;
      94               0 :         adfGeoTransform[3] = atoi(poRecord->GetField(35,44));
      95               0 :         adfGeoTransform[4] = 0;
      96               0 :         adfGeoTransform[5] = 50;
      97                 :         
      98               0 :         nRasterDataType = 3; /* GDT_Int16 */
      99                 :     }
     100                 : 
     101                 : /* -------------------------------------------------------------------- */
     102                 : /*      Parse if LANDFORM_PROFILE_DTM                                   */
     103                 : /* -------------------------------------------------------------------- */
     104               0 :     else if( GetProductId() == NPC_LANDFORM_PROFILE_DTM )
     105                 :     {
     106               0 :         nRasterXSize = atoi(poRecord->GetField(23,30));
     107               0 :         nRasterYSize = atoi(poRecord->GetField(31,38));
     108                 : 
     109                 :         // NOTE: unusual use of GeoTransform - the pixel origin is the
     110                 :         // bottom left corner!
     111                 :         adfGeoTransform[0] = atoi(poRecord->GetField(13,17))
     112               0 :                            + GetXOrigin();
     113               0 :         adfGeoTransform[1] = atoi(poRecord->GetField(39,42));
     114               0 :         adfGeoTransform[2] = 0;
     115                 :         adfGeoTransform[3] = atoi(poRecord->GetField(18,22))
     116               0 :                            + GetYOrigin();
     117               0 :         adfGeoTransform[4] = 0;
     118               0 :         adfGeoTransform[5] = atoi(poRecord->GetField(43,46));
     119                 :         
     120               0 :         nRasterDataType = 3; /* GDT_Int16 */
     121                 :     }
     122                 : 
     123                 : /* -------------------------------------------------------------------- */
     124                 : /*      Initialize column offsets table.                                */
     125                 : /* -------------------------------------------------------------------- */
     126               0 :     delete poRecord;
     127                 : 
     128               0 :     panColumnOffset = (long *) CPLCalloc(sizeof(long),nRasterXSize);
     129                 : 
     130               0 :     GetFPPos( panColumnOffset+0, NULL );
     131                 : 
     132                 : /* -------------------------------------------------------------------- */
     133                 : /*      Create an OGRSFLayer for this file readers raster points.       */
     134                 : /* -------------------------------------------------------------------- */
     135               0 :     if( poDS != NULL )
     136                 :     {
     137               0 :         poRasterLayer = new OGRNTFRasterLayer( poDS, this );
     138               0 :         poDS->AddLayer( poRasterLayer );
     139                 :     }
     140                 : }
     141                 : 
     142                 : /************************************************************************/
     143                 : /*                          ReadRasterColumn()                          */
     144                 : /************************************************************************/
     145                 : 
     146               0 : CPLErr NTFFileReader::ReadRasterColumn( int iColumn, float *pafElev )
     147                 : 
     148                 : {
     149                 : /* -------------------------------------------------------------------- */
     150                 : /*      If we don't already have the scanline offset of the previous    */
     151                 : /*      line, force reading of previous records to establish it.        */
     152                 : /* -------------------------------------------------------------------- */
     153               0 :     if( panColumnOffset[iColumn] == 0 )
     154                 :     {
     155                 :         int     iPrev;
     156                 :         
     157               0 :         for( iPrev = 0; iPrev < iColumn-1; iPrev++ )
     158                 :         {
     159               0 :             if( panColumnOffset[iPrev+1] == 0 )
     160                 :             {
     161                 :                 CPLErr  eErr;
     162                 :                 
     163               0 :                 eErr = ReadRasterColumn( iPrev, NULL );
     164               0 :                 if( eErr != CE_None )
     165               0 :                     return eErr;
     166                 :             }
     167                 :         }
     168                 :     }
     169                 : 
     170                 : /* -------------------------------------------------------------------- */
     171                 : /*      If the dataset isn't open, open it now.                         */
     172                 : /* -------------------------------------------------------------------- */
     173               0 :     if( GetFP() == NULL )
     174               0 :         Open();
     175                 :     
     176                 : /* -------------------------------------------------------------------- */
     177                 : /*      Read requested record.                                          */
     178                 : /* -------------------------------------------------------------------- */
     179                 :     NTFRecord   *poRecord;
     180                 :     
     181               0 :     SetFPPos( panColumnOffset[iColumn], iColumn );
     182               0 :     poRecord = ReadRecord();
     183                 : 
     184               0 :     if( iColumn < nRasterXSize-1 )
     185                 :     {
     186               0 :         GetFPPos( panColumnOffset+iColumn+1, NULL );
     187                 :     }
     188                 :     
     189                 : /* -------------------------------------------------------------------- */
     190                 : /*      Handle LANDRANGER DTM columns.                                  */
     191                 : /* -------------------------------------------------------------------- */
     192               0 :     if( pafElev != NULL && GetProductId() == NPC_LANDRANGER_DTM )
     193                 :     {
     194                 :         double  dfVScale, dfVOffset;
     195                 : 
     196               0 :         dfVOffset = atoi(poRecord->GetField(56,65));
     197               0 :         dfVScale = atoi(poRecord->GetField(66,75)) * 0.001;
     198                 : 
     199               0 :         for( int iPixel = 0; iPixel < nRasterXSize; iPixel++ )
     200                 :         {
     201               0 :             pafElev[iPixel] = (float) (dfVOffset + dfVScale *
     202               0 :                 atoi(poRecord->GetField(84+iPixel*4,87+iPixel*4)));
     203                 :         }
     204                 :     }
     205                 :             
     206                 : /* -------------------------------------------------------------------- */
     207                 : /*      Handle PROFILE                                                  */
     208                 : /* -------------------------------------------------------------------- */
     209               0 :     else if( pafElev != NULL && GetProductId() == NPC_LANDFORM_PROFILE_DTM )
     210                 :     {
     211               0 :         for( int iPixel = 0; iPixel < nRasterXSize; iPixel++ )
     212                 :         {
     213               0 :             pafElev[iPixel] = (float) 
     214               0 :            (atoi(poRecord->GetField(19+iPixel*5,23+iPixel*5)) * GetZMult());
     215                 :         }
     216                 :     }
     217                 :     
     218               0 :     delete poRecord;
     219                 : 
     220               0 :     return CE_None;
     221                 : }
     222                 : 
     223                 : /************************************************************************/
     224                 : /* ==================================================================== */
     225                 : /*                        OGRNTFRasterLayer                             */
     226                 : /* ==================================================================== */
     227                 : /************************************************************************/
     228                 : 
     229                 : /************************************************************************/
     230                 : /*                          OGRNTFRasterLayer                           */
     231                 : /************************************************************************/
     232                 : 
     233               0 : OGRNTFRasterLayer::OGRNTFRasterLayer( OGRNTFDataSource *poDSIn,
     234               0 :                                       NTFFileReader * poReaderIn )
     235                 : 
     236                 : {
     237                 :     char        szLayerName[128];
     238                 : 
     239               0 :     sprintf( szLayerName, "DTM_%s", poReaderIn->GetTileName() );
     240               0 :     poFeatureDefn = new OGRFeatureDefn( szLayerName );
     241               0 :     poFeatureDefn->Reference();
     242               0 :     poFeatureDefn->SetGeomType( wkbPoint25D );
     243                 : 
     244               0 :     OGRFieldDefn      oHeight( "HEIGHT", OFTReal );
     245               0 :     poFeatureDefn->AddFieldDefn( &oHeight );
     246                 : 
     247               0 :     poReader = poReaderIn;
     248               0 :     poDS = poDSIn;
     249               0 :     poFilterGeom = NULL;
     250                 : 
     251                 :     pafColumn = (float *) CPLCalloc(sizeof(float),
     252               0 :                                     poReader->GetRasterYSize());
     253               0 :     iColumnOffset = -1;
     254               0 :     iCurrentFC = 0;
     255                 : 
     256                 : /* -------------------------------------------------------------------- */
     257                 : /*      Check for DEM subsampling, and compute total feature count      */
     258                 : /*      accordingly.                                                    */
     259                 : /* -------------------------------------------------------------------- */
     260               0 :     if( poDS->GetOption( "DEM_SAMPLE" ) == NULL )
     261               0 :         nDEMSample = 1;
     262                 :     else
     263               0 :         nDEMSample = MAX(1,atoi(poDS->GetOption("DEM_SAMPLE")));
     264                 :     
     265                 :     nFeatureCount = (poReader->GetRasterXSize() / nDEMSample)
     266               0 :                   * (poReader->GetRasterYSize() / nDEMSample);
     267               0 : }
     268                 : 
     269                 : /************************************************************************/
     270                 : /*                         ~OGRNTFRasterLayer()                         */
     271                 : /************************************************************************/
     272                 : 
     273               0 : OGRNTFRasterLayer::~OGRNTFRasterLayer()
     274                 : 
     275                 : {
     276               0 :     CPLFree( pafColumn );
     277               0 :     if( poFeatureDefn )
     278               0 :         poFeatureDefn->Release();
     279                 : 
     280               0 :     if( poFilterGeom != NULL )
     281               0 :         delete poFilterGeom;
     282               0 : }
     283                 : 
     284                 : /************************************************************************/
     285                 : /*                          SetSpatialFilter()                          */
     286                 : /************************************************************************/
     287                 : 
     288               0 : void OGRNTFRasterLayer::SetSpatialFilter( OGRGeometry * poGeomIn )
     289                 : 
     290                 : {
     291               0 :     if( poFilterGeom != NULL )
     292                 :     {
     293               0 :         delete poFilterGeom;
     294               0 :         poFilterGeom = NULL;
     295                 :     }
     296                 : 
     297               0 :     if( poGeomIn != NULL )
     298               0 :         poFilterGeom = poGeomIn->clone();
     299               0 : }
     300                 : 
     301                 : /************************************************************************/
     302                 : /*                            ResetReading()                            */
     303                 : /************************************************************************/
     304                 : 
     305               0 : void OGRNTFRasterLayer::ResetReading()
     306                 : 
     307                 : {
     308               0 :     iCurrentFC = 0;
     309               0 : }
     310                 : 
     311                 : /************************************************************************/
     312                 : /*                           GetNextFeature()                           */
     313                 : /************************************************************************/
     314                 : 
     315               0 : OGRFeature *OGRNTFRasterLayer::GetNextFeature()
     316                 : 
     317                 : {
     318               0 :     if( iCurrentFC == 0 )
     319               0 :         iCurrentFC = 1;
     320                 :     else
     321                 :     {
     322                 :         int     iReqColumn, iReqRow;
     323                 :         
     324               0 :         iReqColumn = (iCurrentFC - 1) / poReader->GetRasterYSize();
     325               0 :         iReqRow = iCurrentFC - iReqColumn * poReader->GetRasterXSize() - 1;
     326                 : 
     327               0 :         if( iReqRow + nDEMSample > poReader->GetRasterYSize() )
     328                 :         {
     329               0 :             iReqRow = 0;
     330               0 :             iReqColumn += nDEMSample;
     331                 :         }
     332                 :         else
     333                 :         {
     334               0 :             iReqRow += nDEMSample;
     335                 :         }
     336                 : 
     337                 :         iCurrentFC = iReqColumn * poReader->GetRasterYSize()
     338               0 :             + iReqRow + 1;
     339                 :     }
     340                 : 
     341               0 :     return GetFeature( (long) iCurrentFC );
     342                 : }
     343                 : 
     344                 : /************************************************************************/
     345                 : /*                             GetFeature()                             */
     346                 : /************************************************************************/
     347                 : 
     348               0 : OGRFeature *OGRNTFRasterLayer::GetFeature( long nFeatureId )
     349                 : 
     350                 : {
     351                 :     int         iReqColumn, iReqRow;
     352                 :     
     353                 : /* -------------------------------------------------------------------- */
     354                 : /*      Is this in the range of legal feature ids (pixels)?             */
     355                 : /* -------------------------------------------------------------------- */
     356               0 :     if( nFeatureId < 1
     357                 :         || nFeatureId > poReader->GetRasterXSize()*poReader->GetRasterYSize() )
     358                 :     {
     359               0 :         return NULL;
     360                 :     }
     361                 : 
     362                 : /* -------------------------------------------------------------------- */
     363                 : /*      Do we need to load a different column.                          */
     364                 : /* -------------------------------------------------------------------- */
     365               0 :     iReqColumn = (nFeatureId - 1) / poReader->GetRasterYSize();
     366               0 :     iReqRow = nFeatureId - iReqColumn * poReader->GetRasterXSize() - 1;
     367                 :     
     368               0 :     if( iReqColumn != iColumnOffset )
     369                 :     {
     370               0 :         iColumnOffset = iReqColumn;
     371               0 :         if( poReader->ReadRasterColumn( iReqColumn, pafColumn ) != CE_None )
     372               0 :             return NULL;
     373                 :     }
     374                 :     
     375                 : /* -------------------------------------------------------------------- */
     376                 : /*      Create a corresponding feature.                                 */
     377                 : /* -------------------------------------------------------------------- */
     378               0 :     OGRFeature  *poFeature = new OGRFeature( poFeatureDefn );
     379               0 :     double      *padfGeoTransform = poReader->GetGeoTransform();
     380                 : 
     381               0 :     poFeature->SetFID( nFeatureId );
     382                 : 
     383                 :     // NOTE: unusual use of GeoTransform - the pixel origin is the
     384                 :     // bottom left corner!
     385                 :     poFeature->SetGeometryDirectly(
     386               0 :         new OGRPoint( padfGeoTransform[0] + padfGeoTransform[1] * iReqColumn,
     387               0 :                       padfGeoTransform[3] + padfGeoTransform[5] * iReqRow,
     388               0 :                       pafColumn[iReqRow] ) );
     389               0 :     poFeature->SetField( 0, pafColumn[iReqRow] );
     390                 :     
     391               0 :     return poFeature;
     392                 : }
     393                 : 
     394                 : /************************************************************************/
     395                 : /*                          GetFeatureCount()                           */
     396                 : /*                                                                      */
     397                 : /*      If a spatial filter is in effect, we turn control over to       */
     398                 : /*      the generic counter.  Otherwise we return the total count.      */
     399                 : /*      Eventually we should consider implementing a more efficient     */
     400                 : /*      way of counting features matching a spatial query.              */
     401                 : /************************************************************************/
     402                 : 
     403               0 : int OGRNTFRasterLayer::GetFeatureCount( int bForce )
     404                 : 
     405                 : {
     406               0 :     return nFeatureCount;
     407                 : }
     408                 : 
     409                 : /************************************************************************/
     410                 : /*                           GetSpatialRef()                            */
     411                 : /************************************************************************/
     412                 : 
     413               0 : OGRSpatialReference *OGRNTFRasterLayer::GetSpatialRef()
     414                 : 
     415                 : {
     416               0 :     return poDS->GetSpatialRef();
     417                 : }
     418                 : 
     419                 : /************************************************************************/
     420                 : /*                           TestCapability()                           */
     421                 : /************************************************************************/
     422                 : 
     423               0 : int OGRNTFRasterLayer::TestCapability( const char * pszCap )
     424                 : 
     425                 : {
     426               0 :     if( EQUAL(pszCap,OLCRandomRead) )
     427               0 :         return TRUE;
     428                 : 
     429               0 :     else if( EQUAL(pszCap,OLCSequentialWrite) 
     430                 :              || EQUAL(pszCap,OLCRandomWrite) )
     431               0 :         return FALSE;
     432                 : 
     433               0 :     else if( EQUAL(pszCap,OLCFastFeatureCount) )
     434               0 :         return TRUE;
     435                 : 
     436               0 :     else if( EQUAL(pszCap,OLCFastSpatialFilter) )
     437               0 :         return FALSE;
     438                 : 
     439                 :     else 
     440               0 :         return FALSE;
     441                 : }
     442                 : 
     443                 : 

Generated by: LCOV version 1.7