LTP GCOV extension - code coverage report
Current view: directory - frmts/usgsdem - usgsdemdataset.cpp
Test: gdal_filtered.info
Date: 2010-07-12 Instrumented lines: 217
Code covered: 93.5 % Executed lines: 203

       1                 : /******************************************************************************
       2                 :  * $Id: usgsdemdataset.cpp 19291 2010-04-03 02:04:35Z warmerdam $
       3                 :  *
       4                 :  * Project:  USGS DEM Driver
       5                 :  * Purpose:  All reader for USGS DEM Reader
       6                 :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       7                 :  *
       8                 :  * Portions of this module derived from the VTP USGS DEM driver by Ben
       9                 :  * Discoe, see http://www.vterrain.org
      10                 :  *
      11                 :  ******************************************************************************
      12                 :  * Copyright (c) 2001, Frank Warmerdam <warmerdam@pobox.com>
      13                 :  *
      14                 :  * Permission is hereby granted, free of charge, to any person obtaining a
      15                 :  * copy of this software and associated documentation files (the "Software"),
      16                 :  * to deal in the Software without restriction, including without limitation
      17                 :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      18                 :  * and/or sell copies of the Software, and to permit persons to whom the
      19                 :  * Software is furnished to do so, subject to the following conditions:
      20                 :  *
      21                 :  * The above copyright notice and this permission notice shall be included
      22                 :  * in all copies or substantial portions of the Software.
      23                 :  *
      24                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      25                 :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      26                 :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      27                 :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      28                 :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      29                 :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      30                 :  * DEALINGS IN THE SOFTWARE.
      31                 :  ****************************************************************************/
      32                 : 
      33                 : #include "gdal_pam.h"
      34                 : #include "ogr_spatialref.h"
      35                 : 
      36                 : CPL_CVSID("$Id: usgsdemdataset.cpp 19291 2010-04-03 02:04:35Z warmerdam $");
      37                 : 
      38                 : CPL_C_START
      39                 : void  GDALRegister_USGSDEM(void);
      40                 : CPL_C_END
      41                 : 
      42                 : typedef struct {
      43                 :     double  x;
      44                 :     double  y;
      45                 : } DPoint2;
      46                 : 
      47                 : #define USGSDEM_NODATA  -32767
      48                 : 
      49                 : GDALDataset *USGSDEMCreateCopy( const char *, GDALDataset *, int, char **,
      50                 :                                 GDALProgressFunc pfnProgress, 
      51                 :                                 void * pProgressData );
      52                 : 
      53                 : /************************************************************************/
      54                 : /*                              DConvert()                              */
      55                 : /************************************************************************/
      56                 : 
      57            1598 : static double DConvert( FILE *fp, int nCharCount )
      58                 : 
      59                 : {
      60                 :     char  szBuffer[100];
      61                 :     int   i;
      62                 : 
      63            1598 :     VSIFRead( szBuffer, nCharCount, 1, fp );
      64            1598 :     szBuffer[nCharCount] = '\0';
      65                 : 
      66           40238 :     for( i = 0; i < nCharCount; i++ )
      67                 :     {
      68           38640 :         if( szBuffer[i] == 'D' )
      69            1575 :             szBuffer[i] = 'E';
      70                 :     }
      71                 : 
      72            1598 :     return atof(szBuffer);
      73                 : }
      74                 : 
      75                 : /************************************************************************/
      76                 : /* ==================================================================== */
      77                 : /*        USGSDEMDataset        */
      78                 : /* ==================================================================== */
      79                 : /************************************************************************/
      80                 : 
      81                 : class USGSDEMRasterBand;
      82                 : 
      83                 : class USGSDEMDataset : public GDALPamDataset
      84                 : {
      85                 :     friend class USGSDEMRasterBand;
      86                 : 
      87                 :     int         nDataStartOffset;
      88                 :     GDALDataType eNaturalDataFormat;
      89                 : 
      90                 :     double      adfGeoTransform[6];
      91                 :     char        *pszProjection; 
      92                 : 
      93                 :     double      fVRes;
      94                 : 
      95                 :     const char  *pszUnits; 
      96                 : 
      97                 :     int         LoadFromFile( FILE * );
      98                 : 
      99                 :     FILE  *fp;
     100                 : 
     101                 :   public:
     102                 :                 USGSDEMDataset();
     103                 :     ~USGSDEMDataset();
     104                 :     
     105                 :     static int  Identify( GDALOpenInfo * );
     106                 :     static GDALDataset *Open( GDALOpenInfo * );
     107                 :     CPLErr  GetGeoTransform( double * padfTransform );
     108                 :     const char *GetProjectionRef();
     109                 : };
     110                 : 
     111                 : /************************************************************************/
     112                 : /* ==================================================================== */
     113                 : /*                            USGSDEMRasterBand                             */
     114                 : /* ==================================================================== */
     115                 : /************************************************************************/
     116                 : 
     117                 : class USGSDEMRasterBand : public GDALPamRasterBand
     118              24 : {
     119                 :     friend class USGSDEMDataset;
     120                 : 
     121                 :   public:
     122                 : 
     123                 :         USGSDEMRasterBand( USGSDEMDataset * );
     124                 :     
     125                 :     virtual const char *GetUnitType();
     126                 :     virtual double GetNoDataValue( int *pbSuccess = NULL );
     127                 :     virtual CPLErr IReadBlock( int, int, void * );
     128                 : };
     129                 : 
     130                 : 
     131                 : /************************************************************************/
     132                 : /*                           USGSDEMRasterBand()                            */
     133                 : /************************************************************************/
     134                 : 
     135              24 : USGSDEMRasterBand::USGSDEMRasterBand( USGSDEMDataset *poDS )
     136                 : 
     137                 : {
     138              24 :     this->poDS = poDS;
     139              24 :     this->nBand = 1;
     140                 : 
     141              24 :     eDataType = poDS->eNaturalDataFormat;
     142                 : 
     143              24 :     nBlockXSize = poDS->GetRasterXSize();
     144              24 :     nBlockYSize = poDS->GetRasterYSize();
     145                 : 
     146              24 : }
     147                 : 
     148                 : /************************************************************************/
     149                 : /*                             IReadBlock()                             */
     150                 : /************************************************************************/
     151                 : 
     152                 : CPLErr USGSDEMRasterBand::IReadBlock( int nBlockXOff, int nBlockYOff,
     153              10 :                                       void * pImage )
     154                 : 
     155                 : {
     156                 :     double  dfYMin;
     157              10 :     int   bad = FALSE;
     158              10 :     USGSDEMDataset *poGDS = (USGSDEMDataset *) poDS;
     159                 : 
     160                 : /* -------------------------------------------------------------------- */
     161                 : /*      Initialize image buffer to nodata value.                        */
     162                 : /* -------------------------------------------------------------------- */
     163           40678 :     for( int k = GetXSize() * GetYSize() - 1; k >= 0; k-- )
     164                 :     {
     165           40668 :         if( GetRasterDataType() == GDT_Int16 )
     166           37846 :             ((GInt16 *) pImage)[k] = USGSDEM_NODATA;
     167                 :         else
     168            2822 :             ((float *) pImage)[k] = USGSDEM_NODATA;
     169                 :     }
     170                 : 
     171                 : /* -------------------------------------------------------------------- */
     172                 : /*      Seek to data.                                                   */
     173                 : /* -------------------------------------------------------------------- */
     174              10 :     VSIFSeek(poGDS->fp, poGDS->nDataStartOffset, 0);
     175                 : 
     176                 :     dfYMin = poGDS->adfGeoTransform[3] 
     177              10 :         + (GetYSize()-0.5) * poGDS->adfGeoTransform[5];
     178                 : 
     179                 : /* -------------------------------------------------------------------- */
     180                 : /*      Read all the profiles into the image buffer.                    */
     181                 : /* -------------------------------------------------------------------- */
     182             266 :     for( int i = 0; i < GetXSize(); i++)
     183                 :     {
     184                 :         int njunk, nCPoints, lygap;
     185                 :         double  djunk, dxStart, dyStart, dfElevOffset;
     186                 : 
     187             256 :         fscanf(poGDS->fp, "%d", &njunk);
     188             256 :         fscanf(poGDS->fp, "%d", &njunk);
     189             256 :         fscanf(poGDS->fp, "%d", &nCPoints);
     190             256 :         fscanf(poGDS->fp, "%d", &njunk);
     191                 : 
     192             256 :         dxStart = DConvert(poGDS->fp, 24);
     193             256 :         dyStart = DConvert(poGDS->fp, 24);
     194             256 :         dfElevOffset = DConvert(poGDS->fp, 24);
     195             256 :         djunk = DConvert(poGDS->fp, 24);
     196             256 :         djunk = DConvert(poGDS->fp, 24);
     197                 : 
     198             256 :         if( EQUALN(poGDS->pszProjection,"GEOGCS",6) )
     199             246 :             dyStart = dyStart / 3600.0;
     200                 : 
     201             256 :         lygap = (int)((dfYMin - dyStart)/poGDS->adfGeoTransform[5]+ 0.5);
     202                 : 
     203           39494 :         for (int j=lygap; j < (nCPoints+(int)lygap); j++)
     204                 :         {
     205           39238 :             int   iY = GetYSize() - j - 1;
     206                 :             int         nElev;
     207                 : 
     208           39238 :             fscanf(poGDS->fp, "%d", &nElev);
     209           39238 :             if (iY < 0 || iY >= GetYSize() )
     210               0 :                 bad = TRUE;
     211           39238 :             else if( nElev == USGSDEM_NODATA )
     212                 :                 /* leave in output buffer as nodata */;
     213                 :             else
     214                 :             {
     215                 :                 float fComputedElev = 
     216           33846 :                     (float)(nElev * poGDS->fVRes + dfElevOffset);
     217                 : 
     218           33846 :                 if( GetRasterDataType() == GDT_Int16 )
     219                 :                 {
     220                 :                     ((GInt16 *) pImage)[i + iY*GetXSize()] = 
     221           33785 :                         (GInt16) fComputedElev;
     222                 :                 }
     223                 :                 else
     224                 :                 {
     225              61 :                     ((float *) pImage)[i + iY*GetXSize()] = fComputedElev;
     226                 :                 }
     227                 :             }
     228                 :         }
     229                 :     }
     230                 : 
     231              10 :     return CE_None;
     232                 : }
     233                 : 
     234                 : /************************************************************************/
     235                 : /*                           GetNoDataValue()                           */
     236                 : /************************************************************************/
     237                 : 
     238              16 : double USGSDEMRasterBand::GetNoDataValue( int *pbSuccess )
     239                 : 
     240                 : {
     241              16 :     if( pbSuccess != NULL )
     242              14 :         *pbSuccess = TRUE;
     243                 : 
     244              16 :     return USGSDEM_NODATA;
     245                 : }
     246                 : 
     247                 : /************************************************************************/
     248                 : /*                            GetUnitType()                             */
     249                 : /************************************************************************/
     250               9 : const char *USGSDEMRasterBand::GetUnitType()
     251                 : {
     252               9 :     USGSDEMDataset *poGDS = (USGSDEMDataset *) poDS;
     253                 : 
     254               9 :     return poGDS->pszUnits;
     255                 : }
     256                 : 
     257                 : /************************************************************************/
     258                 : /* ==================================================================== */
     259                 : /*        USGSDEMDataset        */
     260                 : /* ==================================================================== */
     261                 : /************************************************************************/
     262                 : 
     263                 : /************************************************************************/
     264                 : /*                           USGSDEMDataset()                           */
     265                 : /************************************************************************/
     266                 : 
     267              24 : USGSDEMDataset::USGSDEMDataset()
     268                 : 
     269                 : {
     270              24 :     fp = NULL;
     271              24 :     pszProjection = NULL;
     272              24 : }
     273                 : 
     274                 : /************************************************************************/
     275                 : /*                            ~USGSDEMDataset()                         */
     276                 : /************************************************************************/
     277                 : 
     278              24 : USGSDEMDataset::~USGSDEMDataset()
     279                 : 
     280                 : {
     281              24 :     FlushCache();
     282                 : 
     283              24 :     CPLFree( pszProjection );
     284              24 :     if( fp != NULL )
     285              24 :         VSIFClose( fp );
     286              24 : }
     287                 : 
     288                 : /************************************************************************/
     289                 : /*                            LoadFromFile()                            */
     290                 : /*                                                                      */
     291                 : /*      If the data from DEM is in meters, then values are stored as    */
     292                 : /*      shorts. If DEM data is in feet, then height data will be        */
     293                 : /*      stored in float, to preserve the precision of the original      */
     294                 : /*      data. returns true if the file was successfully opened and      */
     295                 : /*      read.                                                           */
     296                 : /************************************************************************/
     297                 : 
     298              24 : int USGSDEMDataset::LoadFromFile(FILE *InDem)
     299                 : {
     300                 :     int   i, j;
     301                 :     int   nRow, nColumn;
     302                 :     int   nVUnit, nGUnit;
     303                 :     double  dxdelta, dydelta;
     304                 :     double  dElevMax, dElevMin;
     305                 :     int   bNewFormat;
     306                 :     int   nCoordSystem;
     307                 :     int   nProfiles;
     308                 :     char  szDateBuffer[5];
     309                 :     DPoint2 corners[4];     // SW, NW, NE, SE
     310                 :     DPoint2 extent_min, extent_max;
     311                 :     int   iUTMZone;
     312                 : 
     313                 :     // check for version of DEM format
     314              24 :     VSIFSeek(InDem, 864, 0);
     315                 : 
     316                 :     // Read DEM into matrix
     317              24 :     fscanf(InDem, "%d", &nRow);
     318              24 :     fscanf(InDem, "%d", &nColumn);
     319              24 :     bNewFormat = ((nRow!=1)||(nColumn!=1));
     320              24 :     if (bNewFormat)
     321                 :     {
     322              23 :         VSIFSeek(InDem, 1024, 0);   // New Format
     323              23 :         fscanf(InDem, "%d", &i);
     324              23 :         fscanf(InDem, "%d", &j);
     325              24 :         if ((i!=1)||(j!=1 && j != 0)) // File OK?
     326                 :         {
     327               1 :             VSIFSeek(InDem, 893, 0);  // Undocumented Format (39109h1.dem)
     328               1 :             fscanf(InDem, "%d", &i);
     329               1 :             fscanf(InDem, "%d", &j);
     330               1 :             if ((i!=1)||(j!=1))     // File OK?
     331                 :             {
     332                 :                 CPLError( CE_Failure, CPLE_AppDefined,
     333               0 :                           "Does not appear to be a USGS DEM file." );
     334               0 :                 return FALSE;
     335                 :             }
     336                 :             else
     337               1 :                 nDataStartOffset = 893;
     338                 :         }
     339                 :         else
     340              22 :             nDataStartOffset = 1024;
     341                 :     }
     342                 :     else
     343               1 :         nDataStartOffset = 864;
     344                 : 
     345              24 :     VSIFSeek(InDem, 156, 0);
     346              24 :     fscanf(InDem, "%d", &nCoordSystem);
     347              24 :     fscanf(InDem, "%d", &iUTMZone);
     348                 : 
     349              24 :     VSIFSeek(InDem, 528, 0);
     350              24 :     fscanf(InDem, "%d", &nGUnit);
     351              24 :     fscanf(InDem, "%d", &nVUnit);
     352                 : 
     353                 :     // Vertical Units in meters
     354              24 :     if (nVUnit==1)
     355               0 :         pszUnits = "ft";
     356                 :     else
     357              24 :         pszUnits = "m";
     358                 : 
     359              24 :     VSIFSeek(InDem, 816, 0);
     360              24 :     dxdelta = DConvert(InDem, 12);
     361              24 :     dydelta = DConvert(InDem, 12);
     362              24 :     fVRes = DConvert(InDem, 12);
     363                 : 
     364                 : /* -------------------------------------------------------------------- */
     365                 : /*      Should we treat this as floating point, or GInt16.              */
     366                 : /* -------------------------------------------------------------------- */
     367              25 :     if (nVUnit==1 || fVRes < 1.0)
     368               1 :         eNaturalDataFormat = GDT_Float32;
     369                 :     else
     370              23 :         eNaturalDataFormat = GDT_Int16;
     371                 : 
     372                 : /* -------------------------------------------------------------------- */
     373                 : /*      Read four corner coordinates.                                   */
     374                 : /* -------------------------------------------------------------------- */
     375              24 :     VSIFSeek(InDem, 546, 0);
     376             120 :     for (i = 0; i < 4; i++)
     377                 :     {
     378              96 :         corners[i].x = DConvert(InDem, 24);
     379              96 :         corners[i].y = DConvert(InDem, 24);
     380                 :     }
     381                 :     
     382                 :     // find absolute extents of raw vales
     383              24 :     extent_min.x = MIN(corners[0].x, corners[1].x);
     384              24 :     extent_max.x = MAX(corners[2].x, corners[3].x);
     385              24 :     extent_min.y = MIN(corners[0].y, corners[3].y);
     386              24 :     extent_max.y = MAX(corners[1].y, corners[2].y);
     387                 : 
     388              24 :     dElevMin = DConvert(InDem, 48);
     389              24 :     dElevMax = DConvert(InDem, 48);
     390                 : 
     391              24 :     VSIFSeek(InDem, 858, 0);
     392              24 :     fscanf(InDem, "%d", &nProfiles);
     393                 : 
     394                 : /* -------------------------------------------------------------------- */
     395                 : /*      Collect the spatial reference system.                           */
     396                 : /* -------------------------------------------------------------------- */
     397              24 :     OGRSpatialReference sr;
     398              24 :     int bNAD83 =TRUE;
     399                 : 
     400                 :     // OLD format header ends at byte 864
     401              24 :     if (bNewFormat)
     402                 :     {
     403                 :         char szHorzDatum[3];
     404                 : 
     405                 :         // year of data compilation
     406              23 :         VSIFSeek(InDem, 876, 0);
     407              23 :         fread(szDateBuffer, 4, 1, InDem);
     408              23 :         szDateBuffer[4] = 0;
     409                 : 
     410                 :         // Horizontal datum
     411                 :         // 1=North American Datum 1927 (NAD 27)
     412                 :         // 2=World Geodetic System 1972 (WGS 72)
     413                 :         // 3=WGS 84
     414                 :         // 4=NAD 83
     415                 :         // 5=Old Hawaii Datum
     416                 :         // 6=Puerto Rico Datum
     417                 :         int datum;
     418              23 :         VSIFSeek(InDem, 890, 0);
     419              23 :         VSIFRead( szHorzDatum, 1, 2, InDem );
     420              23 :         szHorzDatum[2] = '\0';
     421              23 :         datum = atoi(szHorzDatum);
     422              23 :         switch (datum)
     423                 :         {
     424                 :           case 1:
     425               1 :             sr.SetWellKnownGeogCS( "NAD27" );
     426               1 :             bNAD83 = FALSE;
     427               1 :             break;
     428                 : 
     429                 :           case 2:
     430               5 :             sr.SetWellKnownGeogCS( "WGS72" );
     431               5 :             break;
     432                 : 
     433                 :           case 3:
     434              14 :             sr.SetWellKnownGeogCS( "WGS84" );
     435              14 :             break;
     436                 : 
     437                 :           case 4:
     438               1 :             sr.SetWellKnownGeogCS( "NAD83" );
     439               1 :             break;
     440                 : 
     441                 :           case -9:
     442               0 :             break;
     443                 : 
     444                 :           default:
     445               2 :             sr.SetWellKnownGeogCS( "NAD27" );
     446                 :             break;
     447                 :         }
     448                 :     }
     449                 :     else
     450                 :     {
     451               1 :         sr.SetWellKnownGeogCS( "NAD27" );
     452               1 :         bNAD83 = FALSE;
     453                 :     }
     454                 : 
     455              24 :     if (nCoordSystem == 1)  // UTM
     456               6 :         sr.SetUTM( iUTMZone, TRUE );
     457                 : 
     458              18 :     else if (nCoordSystem == 2) // state plane
     459                 :     {
     460               0 :         if( nGUnit == 1 )
     461                 :             sr.SetStatePlane( iUTMZone, bNAD83,
     462               0 :                               "Foot", CPLAtof(SRS_UL_US_FOOT_CONV) );
     463                 :         else
     464               0 :             sr.SetStatePlane( iUTMZone, bNAD83 );
     465                 :     }
     466                 : 
     467              24 :     sr.exportToWkt( &pszProjection );
     468                 : 
     469                 : /* -------------------------------------------------------------------- */
     470                 : /*      For UTM we use the extents (really the UTM coordinates of       */
     471                 : /*      the lat/long corners of the quad) to determine the size in      */
     472                 : /*      pixels and lines, but we have to make the anchors be modulus    */
     473                 : /*      the pixel size which what really gets used.                     */
     474                 : /* -------------------------------------------------------------------- */
     475              30 :     if (nCoordSystem == 1          // UTM
     476                 :         || nCoordSystem == 2     // State Plane
     477                 :         || nCoordSystem == -9999 ) // unknown
     478                 :     {
     479                 :         int njunk;
     480                 :         double  dxStart;
     481                 : 
     482                 :         // expand extents modulus the pixel size.
     483               6 :         extent_min.y = floor(extent_min.y/dydelta) * dydelta;
     484               6 :         extent_max.y = ceil(extent_max.y/dydelta) * dydelta;
     485                 : 
     486                 :         // Forceably compute X extents based on first profile and pixelsize.
     487               6 :         VSIFSeek(InDem, nDataStartOffset, 0);
     488               6 :         fscanf(InDem, "%d", &njunk);
     489               6 :         fscanf(InDem, "%d", &njunk);
     490               6 :         fscanf(InDem, "%d", &njunk);
     491               6 :         fscanf(InDem, "%d", &njunk);
     492               6 :         dxStart = DConvert(InDem, 24);
     493                 :         
     494               6 :         nRasterYSize = (int) ((extent_max.y - extent_min.y)/dydelta + 1.5);
     495               6 :         nRasterXSize = nProfiles;
     496                 : 
     497               6 :         adfGeoTransform[0] = dxStart - dxdelta/2.0;
     498               6 :         adfGeoTransform[1] = dxdelta;
     499               6 :         adfGeoTransform[2] = 0.0;
     500               6 :         adfGeoTransform[3] = extent_max.y + dydelta/2.0;
     501               6 :         adfGeoTransform[4] = 0.0;
     502               6 :         adfGeoTransform[5] = -dydelta;
     503                 :     }
     504                 : /* -------------------------------------------------------------------- */
     505                 : /*      Geographic -- use corners directly.                             */
     506                 : /* -------------------------------------------------------------------- */
     507                 :     else
     508                 :     {
     509              18 :         nRasterYSize = (int) ((extent_max.y - extent_min.y)/dydelta + 1.5);
     510              18 :         nRasterXSize = nProfiles;
     511                 : 
     512                 :         // Translate extents from arc-seconds to decimal degrees.
     513              18 :         adfGeoTransform[0] = (extent_min.x - dxdelta/2.0) / 3600.0;
     514              18 :         adfGeoTransform[1] = dxdelta / 3600.0;
     515              18 :         adfGeoTransform[2] = 0.0;
     516              18 :         adfGeoTransform[3] = (extent_max.y + dydelta/2.0) / 3600.0;
     517              18 :         adfGeoTransform[4] = 0.0;
     518              18 :         adfGeoTransform[5] = (-dydelta) / 3600.0;
     519                 :     }
     520                 : 
     521              24 :     if (!GDALCheckDatasetDimensions(nRasterXSize, nRasterYSize))
     522                 :     {
     523              24 :         return FALSE;
     524                 :     }
     525                 : 
     526              24 :     return TRUE;
     527                 : }
     528                 : 
     529                 : /************************************************************************/
     530                 : /*                          GetGeoTransform()                           */
     531                 : /************************************************************************/
     532                 : 
     533              31 : CPLErr USGSDEMDataset::GetGeoTransform( double * padfTransform )
     534                 : 
     535                 : {
     536              31 :     memcpy( padfTransform, adfGeoTransform, sizeof(double) * 6 );
     537              31 :     return CE_None;
     538                 : }
     539                 : 
     540                 : /************************************************************************/
     541                 : /*                          GetProjectionRef()                          */
     542                 : /************************************************************************/
     543                 : 
     544              47 : const char *USGSDEMDataset::GetProjectionRef()
     545                 : 
     546                 : {
     547              47 :     return pszProjection;
     548                 : }
     549                 : 
     550                 : 
     551                 : /************************************************************************/
     552                 : /*                              Identify()                              */
     553                 : /************************************************************************/
     554                 : 
     555            9615 : int USGSDEMDataset::Identify( GDALOpenInfo * poOpenInfo )
     556                 : 
     557                 : {
     558            9615 :     if( poOpenInfo->fp == NULL || poOpenInfo->nHeaderBytes < 200 )
     559            9359 :         return FALSE;
     560                 : 
     561             256 :     if( !EQUALN((const char *) poOpenInfo->pabyHeader+156, "     0",6)
     562                 :         && !EQUALN((const char *) poOpenInfo->pabyHeader+156, "     1",6)
     563                 :         && !EQUALN((const char *) poOpenInfo->pabyHeader+156, "     2",6) 
     564                 :         && !EQUALN((const char *) poOpenInfo->pabyHeader+156, "     3",6)
     565                 :         && !EQUALN((const char *) poOpenInfo->pabyHeader+156, " -9999",6) )
     566             232 :         return FALSE;
     567                 : 
     568              24 :     if( !EQUALN((const char *) poOpenInfo->pabyHeader+150, "     1",6) 
     569                 :         && !EQUALN((const char *) poOpenInfo->pabyHeader+150, "     4",6))
     570               0 :         return FALSE;
     571                 : 
     572              24 :     return TRUE;
     573                 : }
     574                 : 
     575                 : /************************************************************************/
     576                 : /*                                Open()                                */
     577                 : /************************************************************************/
     578                 : 
     579            1370 : GDALDataset *USGSDEMDataset::Open( GDALOpenInfo * poOpenInfo )
     580                 : 
     581                 : {
     582            1370 :     if( !Identify( poOpenInfo ) )
     583            1346 :         return NULL;
     584                 : 
     585                 : /* -------------------------------------------------------------------- */
     586                 : /*      Create a corresponding GDALDataset.                             */
     587                 : /* -------------------------------------------------------------------- */
     588                 :     USGSDEMDataset  *poDS;
     589                 : 
     590              24 :     poDS = new USGSDEMDataset();
     591                 : 
     592              24 :     poDS->fp = poOpenInfo->fp;
     593              24 :     poOpenInfo->fp = NULL;
     594                 :     
     595                 : /* -------------------------------------------------------------------- */
     596                 : /*  Read the file.              */
     597                 : /* -------------------------------------------------------------------- */
     598              24 :     if( !poDS->LoadFromFile( poDS->fp ) )
     599                 :     {
     600               0 :         delete poDS;
     601               0 :         return NULL;
     602                 :     }
     603                 :     
     604                 : /* -------------------------------------------------------------------- */
     605                 : /*      Confirm the requested access is supported.                      */
     606                 : /* -------------------------------------------------------------------- */
     607              24 :     if( poOpenInfo->eAccess == GA_Update )
     608                 :     {
     609               0 :         delete poDS;
     610                 :         CPLError( CE_Failure, CPLE_NotSupported, 
     611                 :                   "The USGSDEM driver does not support update access to existing"
     612               0 :                   " datasets.\n" );
     613               0 :         return NULL;
     614                 :     }
     615                 :     
     616                 : /* -------------------------------------------------------------------- */
     617                 : /*      Create band information objects.                                */
     618                 : /* -------------------------------------------------------------------- */
     619              24 :     poDS->SetBand( 1, new USGSDEMRasterBand( poDS ));
     620                 : 
     621              24 :     poDS->SetMetadataItem( GDALMD_AREA_OR_POINT, GDALMD_AOP_POINT );
     622                 : 
     623                 : /* -------------------------------------------------------------------- */
     624                 : /*      Initialize any PAM information.                                 */
     625                 : /* -------------------------------------------------------------------- */
     626              24 :     poDS->SetDescription( poOpenInfo->pszFilename );
     627              24 :     poDS->TryLoadXML();
     628                 : 
     629                 : /* -------------------------------------------------------------------- */
     630                 : /*      Open overviews.                                                 */
     631                 : /* -------------------------------------------------------------------- */
     632              24 :     poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename );
     633                 : 
     634              24 :     return( poDS );
     635                 : }
     636                 : 
     637                 : /************************************************************************/
     638                 : /*                        GDALRegister_USGSDEM()                        */
     639                 : /************************************************************************/
     640                 : 
     641             409 : void GDALRegister_USGSDEM()
     642                 : 
     643                 : {
     644                 :     GDALDriver  *poDriver;
     645                 : 
     646             409 :     if( GDALGetDriverByName( "USGSDEM" ) == NULL )
     647                 :     {
     648             392 :         poDriver = new GDALDriver();
     649                 :         
     650             392 :         poDriver->SetDescription( "USGSDEM" );
     651                 :         poDriver->SetMetadataItem( GDAL_DMD_EXTENSION, 
     652             392 :                                    "dem" );
     653                 :         poDriver->SetMetadataItem( GDAL_DMD_LONGNAME, 
     654             392 :                                    "USGS Optional ASCII DEM (and CDED)" );
     655                 :         poDriver->SetMetadataItem( GDAL_DMD_HELPTOPIC, 
     656             392 :                                    "frmt_usgsdem.html" );
     657             392 :         poDriver->SetMetadataItem( GDAL_DMD_CREATIONDATATYPES, "Int16" );
     658                 :         poDriver->SetMetadataItem( GDAL_DMD_CREATIONOPTIONLIST, 
     659                 : "<CreationOptionList>"
     660                 : "   <Option name='PRODUCT' type='string-select' description='Specific Product Type'>"
     661                 : "       <Value>DEFAULT</Value>"
     662                 : "       <Value>CDED50K</Value>"
     663                 : "   </Option>"
     664                 : "   <Option name='TOPLEFT' type='string' description='Top left product corner (ie. 117d15w,52d30n'/>"
     665                 : "   <Option name='RESAMPLE' type='string-select' description='Resampling kernel to use if resampled.'>"
     666                 : "       <Value>Nearest</Value>"
     667                 : "       <Value>Bilinear</Value>"
     668                 : "       <Value>Cubic</Value>"
     669                 : "       <Value>CubicSpline</Value>"
     670                 : "   </Option>"
     671                 : "   <Option name='TEMPLATE' type='string' description='File to default metadata from.'/>"
     672                 : "   <Option name='DEMLevelCode' type='int' description='DEM Level (1, 2 or 3 if set)'/>"
     673                 : "   <Option name='DataSpecVersion' type='int' description='Data and Specification version/revision (eg. 1020)'/>"
     674                 : "   <Option name='PRODUCER' type='string' description='Producer Agency (up to 60 characters)'/>"
     675                 : "   <Option name='OriginCode' type='string' description='Origin code (up to 4 characters, YT for Yukon)'/>"
     676                 : "   <Option name='ProcessCode' type='string' description='Processing Code (8=ANUDEM, 9=FME, A=TopoGrid)'/>"
     677                 : "   <Option name='ZRESOLUTION' type='float' description='Scaling factor for elevation values'/>"
     678                 : "   <Option name='NTS' type='string' description='NTS Mapsheet name, used to derive TOPLEFT.'/>"
     679                 : "   <Option name='INTERNALNAME' type='string' description='Dataset name written into file header.'/>"
     680             392 : "</CreationOptionList>" );
     681                 :         
     682             392 :         poDriver->pfnOpen = USGSDEMDataset::Open;
     683             392 :         poDriver->pfnCreateCopy = USGSDEMCreateCopy;
     684             392 :         poDriver->pfnIdentify = USGSDEMDataset::Identify;
     685                 : 
     686             392 :         GetGDALDriverManager()->RegisterDriver( poDriver );
     687                 :     }
     688             409 : }

Generated by: LTP GCOV extension version 1.5