LCOV - code coverage report
Current view: directory - frmts/usgsdem - usgsdemdataset.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 211 200 94.8 %
Date: 2010-01-09 Functions: 16 16 100.0 %

       1                 : /******************************************************************************
       2                 :  * $Id: usgsdemdataset.cpp 17664 2009-09-21 21:16:45Z rouault $
       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 17664 2009-09-21 21:16:45Z rouault $");
      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              48 : {
     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              10 : CPLErr USGSDEMRasterBand::IReadBlock( int nBlockXOff, int nBlockYOff,
     153                 :                                       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              10 :     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( strstr(poGDS->pszProjection,"PROJCS") == NULL )
     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           33785 :                     ((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              48 : USGSDEMDataset::~USGSDEMDataset()
     279                 : 
     280                 : {
     281              24 :     FlushCache();
     282                 : 
     283              24 :     CPLFree( pszProjection );
     284              24 :     if( fp != NULL )
     285              24 :         VSIFClose( fp );
     286              48 : }
     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                 : 
     399                 :     // OLD format header ends at byte 864
     400              24 :     if (bNewFormat)
     401                 :     {
     402                 :         char szHorzDatum[3];
     403                 : 
     404                 :         // year of data compilation
     405              23 :         VSIFSeek(InDem, 876, 0);
     406              23 :         fread(szDateBuffer, 4, 1, InDem);
     407              23 :         szDateBuffer[4] = 0;
     408                 : 
     409                 :         // Horizontal datum
     410                 :         // 1=North American Datum 1927 (NAD 27)
     411                 :         // 2=World Geodetic System 1972 (WGS 72)
     412                 :         // 3=WGS 84
     413                 :         // 4=NAD 83
     414                 :         // 5=Old Hawaii Datum
     415                 :         // 6=Puerto Rico Datum
     416                 :         int datum;
     417              23 :         VSIFSeek(InDem, 890, 0);
     418              23 :         VSIFRead( szHorzDatum, 1, 2, InDem );
     419              23 :         szHorzDatum[2] = '\0';
     420              23 :         datum = atoi(szHorzDatum);
     421              23 :         switch (datum)
     422                 :         {
     423                 :           case 1:
     424               1 :             sr.SetWellKnownGeogCS( "NAD27" );
     425               1 :             break;
     426                 : 
     427                 :           case 2:
     428               5 :             sr.SetWellKnownGeogCS( "WGS72" );
     429               5 :             break;
     430                 : 
     431                 :           case 3:
     432              14 :             sr.SetWellKnownGeogCS( "WGS84" );
     433              14 :             break;
     434                 : 
     435                 :           case 4:
     436               1 :             sr.SetWellKnownGeogCS( "NAD83" );
     437               1 :             break;
     438                 : 
     439                 :           default:
     440               2 :             sr.SetWellKnownGeogCS( "NAD27" );
     441                 :             break;
     442                 :         }
     443                 :     }
     444                 :     else
     445               1 :         sr.SetWellKnownGeogCS( "NAD27" );
     446                 : 
     447              24 :     if (nCoordSystem == 1)  // UTM
     448               6 :         sr.SetUTM( iUTMZone, TRUE );
     449                 : 
     450              24 :     sr.exportToWkt( &pszProjection );
     451                 : 
     452                 : /* -------------------------------------------------------------------- */
     453                 : /*      For UTM we use the extents (really the UTM coordinates of       */
     454                 : /*      the lat/long corners of the quad) to determine the size in      */
     455                 : /*      pixels and lines, but we have to make the anchors be modulus    */
     456                 : /*      the pixel size which what really gets used.                     */
     457                 : /* -------------------------------------------------------------------- */
     458              24 :     if (nCoordSystem == 1)  // UTM
     459                 :     {
     460                 :         int njunk;
     461                 :         double  dxStart;
     462                 : 
     463                 :         // expand extents modulus the pixel size.
     464               6 :         extent_min.y = floor(extent_min.y/dydelta) * dydelta;
     465               6 :         extent_max.y = ceil(extent_max.y/dydelta) * dydelta;
     466                 : 
     467                 :         // Forceably compute X extents based on first profile and pixelsize.
     468               6 :         VSIFSeek(InDem, nDataStartOffset, 0);
     469               6 :         fscanf(InDem, "%d", &njunk);
     470               6 :         fscanf(InDem, "%d", &njunk);
     471               6 :         fscanf(InDem, "%d", &njunk);
     472               6 :         fscanf(InDem, "%d", &njunk);
     473               6 :         dxStart = DConvert(InDem, 24);
     474                 :         
     475               6 :         nRasterYSize = (int) ((extent_max.y - extent_min.y)/dydelta + 1.5);
     476               6 :         nRasterXSize = nProfiles;
     477                 : 
     478               6 :         adfGeoTransform[0] = dxStart - dxdelta/2.0;
     479               6 :         adfGeoTransform[1] = dxdelta;
     480               6 :         adfGeoTransform[2] = 0.0;
     481               6 :         adfGeoTransform[3] = extent_max.y + dydelta/2.0;
     482               6 :         adfGeoTransform[4] = 0.0;
     483               6 :         adfGeoTransform[5] = -dydelta;
     484                 :     }
     485                 : /* -------------------------------------------------------------------- */
     486                 : /*      Geographic -- use corners directly.                             */
     487                 : /* -------------------------------------------------------------------- */
     488                 :     else
     489                 :     {
     490              18 :         nRasterYSize = (int) ((extent_max.y - extent_min.y)/dydelta + 1.5);
     491              18 :         nRasterXSize = nProfiles;
     492                 : 
     493                 :         // Translate extents from arc-seconds to decimal degrees.
     494              18 :         adfGeoTransform[0] = (extent_min.x - dxdelta/2.0) / 3600.0;
     495              18 :         adfGeoTransform[1] = dxdelta / 3600.0;
     496              18 :         adfGeoTransform[2] = 0.0;
     497              18 :         adfGeoTransform[3] = (extent_max.y + dydelta/2.0) / 3600.0;
     498              18 :         adfGeoTransform[4] = 0.0;
     499              18 :         adfGeoTransform[5] = (-dydelta) / 3600.0;
     500                 :     }
     501                 : 
     502              24 :     if (!GDALCheckDatasetDimensions(nRasterXSize, nRasterYSize))
     503                 :     {
     504               0 :         return FALSE;
     505                 :     }
     506                 : 
     507              24 :     return TRUE;
     508                 : }
     509                 : 
     510                 : /************************************************************************/
     511                 : /*                          GetGeoTransform()                           */
     512                 : /************************************************************************/
     513                 : 
     514              31 : CPLErr USGSDEMDataset::GetGeoTransform( double * padfTransform )
     515                 : 
     516                 : {
     517              31 :     memcpy( padfTransform, adfGeoTransform, sizeof(double) * 6 );
     518              31 :     return CE_None;
     519                 : }
     520                 : 
     521                 : /************************************************************************/
     522                 : /*                          GetProjectionRef()                          */
     523                 : /************************************************************************/
     524                 : 
     525              47 : const char *USGSDEMDataset::GetProjectionRef()
     526                 : 
     527                 : {
     528              47 :     return pszProjection;
     529                 : }
     530                 : 
     531                 : 
     532                 : /************************************************************************/
     533                 : /*                              Identify()                              */
     534                 : /************************************************************************/
     535                 : 
     536            8490 : int USGSDEMDataset::Identify( GDALOpenInfo * poOpenInfo )
     537                 : 
     538                 : {
     539            8490 :     if( poOpenInfo->fp == NULL || poOpenInfo->nHeaderBytes < 200 )
     540            8343 :         return FALSE;
     541                 : 
     542             147 :     if( !EQUALN((const char *) poOpenInfo->pabyHeader+156, "     0",6)
     543                 :         && !EQUALN((const char *) poOpenInfo->pabyHeader+156, "     1",6)
     544                 :         && !EQUALN((const char *) poOpenInfo->pabyHeader+156, "     2",6) 
     545                 :         && !EQUALN((const char *) poOpenInfo->pabyHeader+156, "     3",6) )
     546             123 :         return FALSE;
     547                 : 
     548              24 :     if( !EQUALN((const char *) poOpenInfo->pabyHeader+150, "     1",6) 
     549                 :         && !EQUALN((const char *) poOpenInfo->pabyHeader+150, "     4",6))
     550               0 :         return FALSE;
     551                 : 
     552              24 :     return TRUE;
     553                 : }
     554                 : 
     555                 : /************************************************************************/
     556                 : /*                                Open()                                */
     557                 : /************************************************************************/
     558                 : 
     559             763 : GDALDataset *USGSDEMDataset::Open( GDALOpenInfo * poOpenInfo )
     560                 : 
     561                 : {
     562             763 :     if( !Identify( poOpenInfo ) )
     563             739 :         return NULL;
     564                 : 
     565                 : /* -------------------------------------------------------------------- */
     566                 : /*      Create a corresponding GDALDataset.                             */
     567                 : /* -------------------------------------------------------------------- */
     568                 :     USGSDEMDataset  *poDS;
     569                 : 
     570              24 :     poDS = new USGSDEMDataset();
     571                 : 
     572              24 :     poDS->fp = poOpenInfo->fp;
     573              24 :     poOpenInfo->fp = NULL;
     574                 :     
     575                 : /* -------------------------------------------------------------------- */
     576                 : /*  Read the file.              */
     577                 : /* -------------------------------------------------------------------- */
     578              24 :     if( !poDS->LoadFromFile( poDS->fp ) )
     579                 :     {
     580               0 :         delete poDS;
     581               0 :         return NULL;
     582                 :     }
     583                 :     
     584                 : /* -------------------------------------------------------------------- */
     585                 : /*      Confirm the requested access is supported.                      */
     586                 : /* -------------------------------------------------------------------- */
     587              24 :     if( poOpenInfo->eAccess == GA_Update )
     588                 :     {
     589               0 :         delete poDS;
     590                 :         CPLError( CE_Failure, CPLE_NotSupported, 
     591                 :                   "The USGSDEM driver does not support update access to existing"
     592               0 :                   " datasets.\n" );
     593               0 :         return NULL;
     594                 :     }
     595                 :     
     596                 : /* -------------------------------------------------------------------- */
     597                 : /*      Create band information objects.                                */
     598                 : /* -------------------------------------------------------------------- */
     599              24 :     poDS->SetBand( 1, new USGSDEMRasterBand( poDS ));
     600                 : 
     601              24 :     poDS->SetMetadataItem( GDALMD_AREA_OR_POINT, GDALMD_AOP_POINT );
     602                 : 
     603                 : /* -------------------------------------------------------------------- */
     604                 : /*      Initialize any PAM information.                                 */
     605                 : /* -------------------------------------------------------------------- */
     606              24 :     poDS->SetDescription( poOpenInfo->pszFilename );
     607              24 :     poDS->TryLoadXML();
     608                 : 
     609                 : /* -------------------------------------------------------------------- */
     610                 : /*      Open overviews.                                                 */
     611                 : /* -------------------------------------------------------------------- */
     612              24 :     poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename );
     613                 : 
     614              24 :     return( poDS );
     615                 : }
     616                 : 
     617                 : /************************************************************************/
     618                 : /*                        GDALRegister_USGSDEM()                        */
     619                 : /************************************************************************/
     620                 : 
     621             338 : void GDALRegister_USGSDEM()
     622                 : 
     623                 : {
     624                 :     GDALDriver  *poDriver;
     625                 : 
     626             338 :     if( GDALGetDriverByName( "USGSDEM" ) == NULL )
     627                 :     {
     628             336 :         poDriver = new GDALDriver();
     629                 :         
     630             336 :         poDriver->SetDescription( "USGSDEM" );
     631                 :         poDriver->SetMetadataItem( GDAL_DMD_EXTENSION, 
     632             336 :                                    "dem" );
     633                 :         poDriver->SetMetadataItem( GDAL_DMD_LONGNAME, 
     634             336 :                                    "USGS Optional ASCII DEM (and CDED)" );
     635                 :         poDriver->SetMetadataItem( GDAL_DMD_HELPTOPIC, 
     636             336 :                                    "frmt_usgsdem.html" );
     637             336 :         poDriver->SetMetadataItem( GDAL_DMD_CREATIONDATATYPES, "Int16" );
     638                 :         poDriver->SetMetadataItem( GDAL_DMD_CREATIONOPTIONLIST, 
     639                 : "<CreationOptionList>"
     640                 : "   <Option name='PRODUCT' type='string-select' description='Specific Product Type'>"
     641                 : "       <Value>DEFAULT</Value>"
     642                 : "       <Value>CDED50K</Value>"
     643                 : "   </Option>"
     644                 : "   <Option name='TOPLEFT' type='string' description='Top left product corner (ie. 117d15w,52d30n'/>"
     645                 : "   <Option name='RESAMPLE' type='string-select' description='Resampling kernel to use if resampled.'>"
     646                 : "       <Value>Nearest</Value>"
     647                 : "       <Value>Bilinear</Value>"
     648                 : "       <Value>Cubic</Value>"
     649                 : "       <Value>CubicSpline</Value>"
     650                 : "   </Option>"
     651                 : "   <Option name='TEMPLATE' type='string' description='File to default metadata from.'/>"
     652                 : "   <Option name='DEMLevelCode' type='int' description='DEM Level (1, 2 or 3 if set)'/>"
     653                 : "   <Option name='DataSpecVersion' type='int' description='Data and Specification version/revision (eg. 1020)'/>"
     654                 : "   <Option name='PRODUCER' type='string' description='Producer Agency (up to 60 characters)'/>"
     655                 : "   <Option name='OriginCode' type='string' description='Origin code (up to 4 characters, YT for Yukon)'/>"
     656                 : "   <Option name='ProcessCode' type='string' description='Processing Code (8=ANUDEM, 9=FME, A=TopoGrid)'/>"
     657                 : "   <Option name='ZRESOLUTION' type='float' description='Scaling factor for elevation values'/>"
     658                 : "   <Option name='NTS' type='string' description='NTS Mapsheet name, used to derive TOPLEFT.'/>"
     659                 : "   <Option name='INTERNALNAME' type='string' description='Dataset name written into file header.'/>"
     660             336 : "</CreationOptionList>" );
     661                 :         
     662             336 :         poDriver->pfnOpen = USGSDEMDataset::Open;
     663             336 :         poDriver->pfnCreateCopy = USGSDEMCreateCopy;
     664             336 :         poDriver->pfnIdentify = USGSDEMDataset::Identify;
     665                 : 
     666             336 :         GetGDALDriverManager()->RegisterDriver( poDriver );
     667                 :     }
     668             338 : }

Generated by: LCOV version 1.7