LCOV - code coverage report
Current view: directory - frmts/sdts - sdtsdataset.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 124 93 75.0 %
Date: 2010-01-09 Functions: 13 11 84.6 %

       1                 : /******************************************************************************
       2                 :  * $Id: sdtsdataset.cpp 17664 2009-09-21 21:16:45Z rouault $
       3                 :  *
       4                 :  * Project:  SDTS Translator
       5                 :  * Purpose:  GDALDataset driver for SDTS Raster translator.
       6                 :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       7                 :  *
       8                 :  ******************************************************************************
       9                 :  * Copyright (c) 1999, 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 "sdts_al.h"
      31                 : #include "gdal_pam.h"
      32                 : #include "ogr_spatialref.h"
      33                 : 
      34                 : CPL_CVSID("$Id: sdtsdataset.cpp 17664 2009-09-21 21:16:45Z rouault $");
      35                 : 
      36                 : /**
      37                 :  \file sdtsdataset.cpp
      38                 : 
      39                 :  exclude
      40                 : */
      41                 : 
      42                 : CPL_C_START
      43                 : void    GDALRegister_SDTS(void);
      44                 : CPL_C_END
      45                 : 
      46                 : /************************************************************************/
      47                 : /* ==================================================================== */
      48                 : /*                              SDTSDataset                             */
      49                 : /* ==================================================================== */
      50                 : /************************************************************************/
      51                 : 
      52                 : class SDTSRasterBand;
      53                 : 
      54                 : class SDTSDataset : public GDALPamDataset
      55               2 : {
      56                 :     friend class SDTSRasterBand;
      57                 :     
      58                 :     SDTSTransfer *poTransfer;
      59                 :     SDTSRasterReader *poRL;
      60                 : 
      61                 :     char        *pszProjection;
      62                 : 
      63                 :   public:
      64                 :     virtual     ~SDTSDataset();
      65                 :     
      66                 :     static GDALDataset *Open( GDALOpenInfo * );
      67                 : 
      68                 :     virtual const char *GetProjectionRef(void);
      69                 :     virtual CPLErr GetGeoTransform( double * );
      70                 : };
      71                 : 
      72                 : class SDTSRasterBand : public GDALPamRasterBand
      73               4 : {
      74                 :     friend class SDTSDataset;
      75                 : 
      76                 :     SDTSRasterReader *poRL;
      77                 :     
      78                 :   public:
      79                 : 
      80                 :                 SDTSRasterBand( SDTSDataset *, int, SDTSRasterReader * );
      81                 :     
      82                 :     virtual CPLErr IReadBlock( int, int, void * );
      83                 : 
      84                 :     virtual double GetNoDataValue( int *pbSuccess );
      85                 :     virtual const char *GetUnitType();
      86                 : };
      87                 : 
      88                 : 
      89                 : /************************************************************************/
      90                 : /*                            ~SDTSDataset()                            */
      91                 : /************************************************************************/
      92                 : 
      93               4 : SDTSDataset::~SDTSDataset()
      94                 : 
      95                 : {
      96               2 :     FlushCache();
      97                 : 
      98               2 :     if( poTransfer != NULL )
      99               2 :         delete poTransfer;
     100                 : 
     101               2 :     if( poRL != NULL )
     102               2 :         delete poRL;
     103                 : 
     104               2 :     if( pszProjection != NULL )
     105               2 :         CPLFree( pszProjection );
     106               4 : }
     107                 : 
     108                 : /************************************************************************/
     109                 : /*                                Open()                                */
     110                 : /************************************************************************/
     111                 : 
     112            9861 : GDALDataset *SDTSDataset::Open( GDALOpenInfo * poOpenInfo )
     113                 : 
     114                 : {
     115                 :     int         i;
     116                 :     
     117                 : /* -------------------------------------------------------------------- */
     118                 : /*      Before trying SDTSOpen() we first verify that the first         */
     119                 : /*      record is in fact a SDTS file descriptor record.                */
     120                 : /* -------------------------------------------------------------------- */
     121            9861 :     char        *pachLeader = (char *) poOpenInfo->pabyHeader;
     122                 :     
     123            9861 :     if( poOpenInfo->nHeaderBytes < 24 )
     124            8725 :         return NULL;
     125                 : 
     126            1136 :     if( pachLeader[5] != '1' && pachLeader[5] != '2' && pachLeader[5] != '3' )
     127            1122 :         return NULL;
     128                 : 
     129              14 :     if( pachLeader[6] != 'L' )
     130               3 :         return NULL;
     131                 : 
     132              11 :     if( pachLeader[8] != '1' && pachLeader[8] != ' ' )
     133               0 :         return NULL;
     134                 : 
     135                 : /* -------------------------------------------------------------------- */
     136                 : /*      Try opening the dataset.                                        */
     137                 : /* -------------------------------------------------------------------- */
     138              11 :     SDTSTransfer        *poTransfer = new SDTSTransfer;
     139                 :     
     140              11 :     if( !poTransfer->Open( poOpenInfo->pszFilename ) )
     141                 :     {
     142               9 :         delete poTransfer;
     143               9 :         return NULL;
     144                 :     }
     145                 :     
     146                 : /* -------------------------------------------------------------------- */
     147                 : /*      Confirm the requested access is supported.                      */
     148                 : /* -------------------------------------------------------------------- */
     149               2 :     if( poOpenInfo->eAccess == GA_Update )
     150                 :     {
     151               0 :         delete poTransfer;
     152                 :         CPLError( CE_Failure, CPLE_NotSupported, 
     153                 :                   "The SDTS driver does not support update access to existing"
     154               0 :                   " datasets.\n" );
     155               0 :         return NULL;
     156                 :     }
     157                 :     
     158                 : /* -------------------------------------------------------------------- */
     159                 : /*      Find the first raster layer.  If there are none, abort          */
     160                 : /*      returning an error.                                             */
     161                 : /* -------------------------------------------------------------------- */
     162               2 :     SDTSRasterReader    *poRL = NULL;
     163                 : 
     164               2 :     for( i = 0; i < poTransfer->GetLayerCount(); i++ )
     165                 :     {
     166               2 :         if( poTransfer->GetLayerType( i ) == SLTRaster )
     167                 :         {
     168               2 :             poRL = poTransfer->GetLayerRasterReader( i );
     169               2 :             break;
     170                 :         }
     171                 :     }
     172                 : 
     173               2 :     if( poRL == NULL )
     174                 :     {
     175               0 :         delete poTransfer;
     176                 :         
     177                 :         CPLError( CE_Warning, CPLE_AppDefined,
     178                 :                   "%s is an SDTS transfer, but has no raster cell layers.\n"
     179                 :                   "Perhaps it is a vector transfer?\n",
     180               0 :                   poOpenInfo->pszFilename );
     181               0 :         return NULL;
     182                 :     }
     183                 : 
     184                 : /* -------------------------------------------------------------------- */
     185                 : /*      Initialize a corresponding GDALDataset.                         */
     186                 : /* -------------------------------------------------------------------- */
     187               2 :     SDTSDataset *poDS = new SDTSDataset();
     188                 : 
     189               2 :     poDS->poTransfer = poTransfer;
     190               2 :     poDS->poRL = poRL;
     191                 :     
     192                 : /* -------------------------------------------------------------------- */
     193                 : /*      Capture some information from the file that is of interest.     */
     194                 : /* -------------------------------------------------------------------- */
     195               2 :     poDS->nRasterXSize = poRL->GetXSize();
     196               2 :     poDS->nRasterYSize = poRL->GetYSize();
     197                 :     
     198                 : /* -------------------------------------------------------------------- */
     199                 : /*      Create band information objects.                                */
     200                 : /* -------------------------------------------------------------------- */
     201               2 :     poDS->nBands = 1;
     202                 :     poDS->papoBands = (GDALRasterBand **)
     203               2 :         VSICalloc(sizeof(GDALRasterBand *),poDS->nBands);
     204                 : 
     205               8 :     for( i = 0; i < poDS->nBands; i++ )
     206               2 :         poDS->SetBand( i+1, new SDTSRasterBand( poDS, i+1, poRL ) );
     207                 : 
     208                 : /* -------------------------------------------------------------------- */
     209                 : /*      Try to establish the projection string.  For now we only        */
     210                 : /*      support UTM and GEO.                                            */
     211                 : /* -------------------------------------------------------------------- */
     212               2 :     OGRSpatialReference   oSRS;
     213               2 :     SDTS_XREF   *poXREF = poTransfer->GetXREF();
     214                 : 
     215               2 :     if( EQUAL(poXREF->pszSystemName,"UTM") )
     216                 :     {                 
     217               2 :         oSRS.SetUTM( poXREF->nZone );
     218                 :     }
     219               0 :     else if( EQUAL(poXREF->pszSystemName,"GEO") )
     220                 :     {
     221                 :         /* we set datum later */
     222                 :     }
     223                 :     else
     224               0 :         oSRS.SetLocalCS( poXREF->pszSystemName );
     225                 : 
     226               2 :     if( oSRS.IsLocal() )
     227                 :         /* don't try to set datum. */;
     228               2 :     else if( EQUAL(poXREF->pszDatum,"NAS") )
     229               2 :         oSRS.SetWellKnownGeogCS( "NAD27" );
     230               0 :     else if( EQUAL(poXREF->pszDatum, "NAX") )
     231               0 :         oSRS.SetWellKnownGeogCS( "NAD83" );
     232               0 :     else if( EQUAL(poXREF->pszDatum, "WGC") )
     233               0 :         oSRS.SetWellKnownGeogCS( "WGS72" );
     234               0 :     else if( EQUAL(poXREF->pszDatum, "WGE") )
     235               0 :         oSRS.SetWellKnownGeogCS( "WGS84" );
     236                 :     else
     237               0 :         oSRS.SetWellKnownGeogCS( "WGS84" );
     238                 : 
     239               2 :     oSRS.Fixup();
     240                 : 
     241               2 :     poDS->pszProjection = NULL;
     242               2 :     if( oSRS.exportToWkt( &poDS->pszProjection ) != OGRERR_NONE )
     243               0 :         poDS->pszProjection = CPLStrdup("");
     244                 : 
     245                 : 
     246                 : /* -------------------------------------------------------------------- */
     247                 : /*      Get metadata from the IDEN file.                                */
     248                 : /* -------------------------------------------------------------------- */
     249               2 :     const char* pszIDENFilePath = poTransfer->GetCATD()->GetModuleFilePath("IDEN");
     250               2 :     if (pszIDENFilePath)
     251                 :     {
     252               2 :         DDFModule   oIDENFile;
     253               2 :         if( oIDENFile.Open( pszIDENFilePath ) )
     254                 :         {
     255                 :             DDFRecord* poRecord;
     256                 : 
     257               4 :             while( (poRecord = oIDENFile.ReadRecord()) != NULL )
     258                 :             {
     259                 : 
     260               2 :                 if( poRecord->GetStringSubfield( "IDEN", 0, "MODN", 0 ) == NULL )
     261               0 :                     continue;
     262                 : 
     263                 :                 static const char* fields[][2] = { { "TITL", "TITLE" },
     264                 :                                                    { "DAID", "DATASET_ID" },
     265                 :                                                    { "DAST", "DATA_STRUCTURE" },
     266                 :                                                    { "MPDT", "MAP_DATE" },
     267                 :                                                    { "DCDT", "DATASET_CREATION_DATE" } };
     268                 : 
     269              12 :                 for (i = 0; i < (int)sizeof(fields) / (int)sizeof(fields[0]) ; i++)
     270                 :                 {
     271                 :                     const char* pszFieldValue =
     272              10 :                             poRecord->GetStringSubfield( "IDEN", 0, fields[i][0], 0 );
     273              10 :                     if ( pszFieldValue )
     274              10 :                         poDS->SetMetadataItem(fields[i][1], pszFieldValue);
     275                 :                 }
     276                 : 
     277               2 :                 break;
     278                 :             }
     279               2 :         }
     280                 :     }
     281                 : 
     282                 : /* -------------------------------------------------------------------- */
     283                 : /*      Initialize any PAM information.                                 */
     284                 : /* -------------------------------------------------------------------- */
     285               2 :     poDS->SetDescription( poOpenInfo->pszFilename );
     286               2 :     poDS->TryLoadXML();
     287                 : 
     288               2 :     return( poDS );
     289                 : }
     290                 : 
     291                 : /************************************************************************/
     292                 : /*                          GetGeoTransform()                           */
     293                 : /************************************************************************/
     294                 : 
     295               1 : CPLErr SDTSDataset::GetGeoTransform( double * padfTransform )
     296                 : 
     297                 : {
     298               1 :     if( poRL->GetTransform( padfTransform ) )
     299               1 :         return CE_None;
     300                 :     else
     301               0 :         return CE_Failure;
     302                 : }
     303                 : 
     304                 : /************************************************************************/
     305                 : /*                          GetProjectionRef()                          */
     306                 : /************************************************************************/
     307                 : 
     308               1 : const char *SDTSDataset::GetProjectionRef()
     309                 : 
     310                 : {
     311               1 :     return pszProjection;
     312                 : }
     313                 : 
     314                 : /************************************************************************/
     315                 : /* ==================================================================== */
     316                 : /*                            SDTSRasterBand                             */
     317                 : /* ==================================================================== */
     318                 : /************************************************************************/
     319                 : 
     320                 : /************************************************************************/
     321                 : /*                           SDTSRasterBand()                            */
     322                 : /************************************************************************/
     323                 : 
     324               2 : SDTSRasterBand::SDTSRasterBand( SDTSDataset *poDS, int nBand,
     325               2 :                                 SDTSRasterReader * poRL )
     326                 : 
     327                 : {
     328               2 :     this->poDS = poDS;
     329               2 :     this->nBand = nBand;
     330               2 :     this->poRL = poRL;
     331                 : 
     332               2 :     if( poRL->GetRasterType() == SDTS_RT_INT16 )
     333               2 :         eDataType = GDT_Int16;
     334                 :     else
     335               0 :         eDataType = GDT_Float32;
     336                 : 
     337               2 :     nBlockXSize = poRL->GetBlockXSize();
     338               2 :     nBlockYSize = poRL->GetBlockYSize();
     339               2 : }
     340                 : 
     341                 : /************************************************************************/
     342                 : /*                             IReadBlock()                             */
     343                 : /************************************************************************/
     344                 : 
     345              25 : CPLErr SDTSRasterBand::IReadBlock( int nBlockXOff, int nBlockYOff,
     346                 :                                   void * pImage )
     347                 : 
     348                 : {
     349              25 :     if( poRL->GetBlock( nBlockXOff, nBlockYOff, pImage ) )
     350              25 :         return CE_None;
     351                 :     else
     352               0 :         return CE_Failure;
     353                 : }
     354                 : 
     355                 : /************************************************************************/
     356                 : /*                           GetNoDataValue()                           */
     357                 : /************************************************************************/
     358                 : 
     359               0 : double SDTSRasterBand::GetNoDataValue( int *pbSuccess )
     360                 : 
     361                 : {
     362               0 :     if( pbSuccess != NULL )
     363               0 :         *pbSuccess = TRUE;
     364                 :     
     365               0 :     return -32766.0;
     366                 : }
     367                 : 
     368                 : /************************************************************************/
     369                 : /*                            GetUnitType()                             */
     370                 : /************************************************************************/
     371                 : 
     372               0 : const char *SDTSRasterBand::GetUnitType()
     373                 : 
     374                 : {
     375               0 :     if( EQUAL(poRL->szUNITS,"FEET") )
     376               0 :         return "ft";
     377               0 :     else if( EQUALN(poRL->szUNITS,"MET",3) )
     378               0 :         return "m";
     379                 :     else
     380               0 :         return poRL->szUNITS;
     381                 : }
     382                 : 
     383                 : /************************************************************************/
     384                 : /*                         GDALRegister_SDTS()                          */
     385                 : /************************************************************************/
     386                 : 
     387             338 : void GDALRegister_SDTS()
     388                 : 
     389                 : {
     390                 :     GDALDriver  *poDriver;
     391                 : 
     392             338 :     if( GDALGetDriverByName( "SDTS" ) == NULL )
     393                 :     {
     394             336 :         poDriver = new GDALDriver();
     395                 :         
     396             336 :         poDriver->SetDescription( "SDTS" );
     397                 :         poDriver->SetMetadataItem( GDAL_DMD_LONGNAME, 
     398             336 :                                    "SDTS Raster" );
     399                 :         poDriver->SetMetadataItem( GDAL_DMD_HELPTOPIC, 
     400             336 :                                    "frmt_various.html#SDTS" );
     401             336 :         poDriver->SetMetadataItem( GDAL_DMD_EXTENSION, "ddf" );
     402                 : 
     403             336 :         poDriver->pfnOpen = SDTSDataset::Open;
     404                 : 
     405             336 :         GetGDALDriverManager()->RegisterDriver( poDriver );
     406                 :     }
     407             338 : }
     408                 : 

Generated by: LCOV version 1.7