LCOV - code coverage report
Current view: directory - frmts/srtmhgt - srtmhgtdataset.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 194 153 78.9 %
Date: 2010-01-09 Functions: 17 16 94.1 %

       1                 : /******************************************************************************
       2                 :  * $Id: srtmhgtdataset.cpp 18117 2009-11-27 19:42:29Z rouault $
       3                 :  *
       4                 :  * Project:  SRTM HGT Driver
       5                 :  * Purpose:  SRTM HGT File Read Support.
       6                 :  *           http://dds.cr.usgs.gov/srtm/version2_1/Documentation/SRTM_Topo.pdf
       7                 :  *           http://www2.jpl.nasa.gov/srtm/faq.html
       8                 :  *           http://dds.cr.usgs.gov/srtm/version2_1
       9                 :  * Authors:  Michael Mazzella, Even Rouault
      10                 :  *
      11                 :  ******************************************************************************
      12                 :  * Copyright (c) 2005, 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 "cpl_port.h"
      35                 : #include "cpl_string.h"
      36                 : #include "ogr_spatialref.h"
      37                 : 
      38                 : #define SRTMHG_NODATA_VALUE -32768
      39                 : 
      40                 : CPL_CVSID("$Id: srtmhgtdataset.cpp 18117 2009-11-27 19:42:29Z rouault $");
      41                 : 
      42                 : CPL_C_START
      43                 : void  GDALRegister_SRTMHGT(void);
      44                 : CPL_C_END
      45                 : 
      46                 : /************************************************************************/
      47                 : /* ==================================================================== */
      48                 : /*        SRTMHGTDataset        */
      49                 : /* ==================================================================== */
      50                 : /************************************************************************/
      51                 : 
      52                 : class SRTMHGTRasterBand;
      53                 : 
      54                 : class SRTMHGTDataset : public GDALPamDataset
      55                 : {
      56                 :     friend class SRTMHGTRasterBand;
      57                 : 
      58                 :     FILE*  fpImage;
      59                 :     double adfGeoTransform[6];
      60                 :     GInt16* panBuffer;
      61                 : 
      62                 :   public:
      63                 :     SRTMHGTDataset();
      64                 :     ~SRTMHGTDataset();
      65                 : 
      66                 :     virtual const char *GetProjectionRef(void);
      67                 :     virtual CPLErr GetGeoTransform(double*);
      68                 :     
      69                 :     static int Identify( GDALOpenInfo * poOpenInfo );
      70                 :     static GDALDataset* Open(GDALOpenInfo*);
      71                 :     static GDALDataset* CreateCopy( const char * pszFilename, GDALDataset *poSrcDS, 
      72                 :                                     int bStrict, char ** papszOptions, 
      73                 :                                     GDALProgressFunc pfnProgress, void * pProgressData );
      74                 : 
      75                 : };
      76                 : 
      77                 : /************************************************************************/
      78                 : /* ==================================================================== */
      79                 : /*                            SRTMHGTRasterBand                             */
      80                 : /* ==================================================================== */
      81                 : /************************************************************************/
      82                 : 
      83                 : class SRTMHGTRasterBand : public GDALPamRasterBand
      84              10 : {
      85                 :     friend class SRTMHGTDataset;
      86                 : 
      87                 :     int         bNoDataSet;
      88                 :     double  dfNoDataValue;
      89                 : 
      90                 :   public:
      91                 :     SRTMHGTRasterBand(SRTMHGTDataset*, int);
      92                 : 
      93                 :     virtual CPLErr IReadBlock(int, int, void*);
      94                 :     virtual CPLErr IWriteBlock(int nBlockXOff, int nBlockYOff, void* pImage);
      95                 : 
      96                 :     virtual GDALColorInterp GetColorInterpretation();
      97                 : 
      98                 :     virtual double  GetNoDataValue( int *pbSuccess = NULL );
      99                 : 
     100               3 :     virtual const char* GetUnitType() { return "m"; }
     101                 : };
     102                 : 
     103                 : /************************************************************************/
     104                 : /*                           SRTMHGTRasterBand()                            */
     105                 : /************************************************************************/
     106                 : 
     107               5 : SRTMHGTRasterBand::SRTMHGTRasterBand(SRTMHGTDataset* poDS, int nBand)
     108                 : {
     109               5 :   this->poDS = poDS;
     110               5 :   this->nBand = nBand;
     111               5 :   eDataType = GDT_Int16;
     112               5 :   nBlockXSize = poDS->nRasterXSize;
     113               5 :   nBlockYSize = 1;
     114               5 :   bNoDataSet = TRUE;
     115               5 :   dfNoDataValue = SRTMHG_NODATA_VALUE;
     116               5 : }
     117                 : 
     118                 : /************************************************************************/
     119                 : /*                             IReadBlock()                             */
     120                 : /************************************************************************/
     121                 : 
     122            3603 : CPLErr SRTMHGTRasterBand::IReadBlock(int nBlockXOff, int nBlockYOff,
     123                 :                                      void* pImage)
     124                 : {
     125            3603 :   SRTMHGTDataset* poGDS = (SRTMHGTDataset*) poDS;
     126                 : 
     127                 :   CPLAssert(nBlockXOff == 0);
     128            3603 :   if(nBlockXOff != 0)
     129                 :   {
     130                 :       CPLError(CE_Failure, CPLE_NotSupported,
     131               0 :                "unhandled nBlockXOff value : %d", nBlockXOff);
     132               0 :       return CE_Failure;
     133                 :   }
     134                 : 
     135            3603 :   if((poGDS == NULL) || (poGDS->fpImage == NULL))
     136               0 :     return CE_Failure;
     137                 : 
     138                 : /* -------------------------------------------------------------------- */
     139                 : /*      Load the desired data into the working buffer.                  */
     140                 : /* -------------------------------------------------------------------- */
     141            3603 :   VSIFSeekL(poGDS->fpImage, nBlockYOff*nBlockXSize*2, SEEK_SET);
     142            3603 :   VSIFReadL((unsigned char*)pImage, nBlockXSize, 2, poGDS->fpImage);
     143                 : #ifdef CPL_LSB
     144            3603 :   GDALSwapWords(pImage, 2, nBlockXSize, 2);
     145                 : #endif
     146                 : 
     147            3603 :   return CE_None;
     148                 : }
     149                 : 
     150                 : /************************************************************************/
     151                 : /*                             IWriteBlock()                            */
     152                 : /************************************************************************/
     153                 : 
     154               0 : CPLErr SRTMHGTRasterBand::IWriteBlock(int nBlockXOff, int nBlockYOff, void* pImage)
     155                 : {
     156               0 :     SRTMHGTDataset* poGDS = (SRTMHGTDataset*) poDS;
     157                 : 
     158                 :     CPLAssert(nBlockXOff == 0);
     159               0 :     if(nBlockXOff != 0)
     160                 :     {
     161               0 :         CPLError(CE_Failure, CPLE_NotSupported, "unhandled nBlockXOff value : %d", nBlockXOff);
     162               0 :         return CE_Failure;
     163                 :     }
     164                 : 
     165               0 :     if((poGDS == NULL) || (poGDS->fpImage == NULL) || (poGDS->eAccess != GA_Update))
     166               0 :         return CE_Failure;
     167                 : 
     168               0 :     VSIFSeekL(poGDS->fpImage, nBlockYOff*nBlockXSize*2, SEEK_SET);
     169                 : 
     170                 : #ifdef CPL_LSB
     171               0 :     memcpy(poGDS->panBuffer, pImage, nBlockXSize*sizeof(GInt16));
     172               0 :     GDALSwapWords(poGDS->panBuffer, 2, nBlockXSize, 2);
     173               0 :     VSIFWriteL((unsigned char*)poGDS->panBuffer, nBlockXSize, 2, poGDS->fpImage);
     174                 : #else
     175                 :     VSIFWriteL((unsigned char*)pImage, nBlockXSize, 2, poGDS->fpImage);
     176                 : #endif
     177                 : 
     178               0 :     return CE_None;
     179                 : }
     180                 : /************************************************************************/
     181                 : /*                           GetNoDataValue()                           */
     182                 : /************************************************************************/
     183                 : 
     184               5 : double SRTMHGTRasterBand::GetNoDataValue( int * pbSuccess )
     185                 : 
     186                 : {
     187               5 :     if( pbSuccess )
     188               4 :         *pbSuccess = bNoDataSet;
     189                 : 
     190               5 :     return dfNoDataValue;
     191                 : }
     192                 : 
     193                 : /************************************************************************/
     194                 : /*                       GetColorInterpretation()                       */
     195                 : /************************************************************************/
     196                 : 
     197               2 : GDALColorInterp SRTMHGTRasterBand::GetColorInterpretation()
     198                 : {
     199               2 :   return GCI_Undefined;
     200                 : }
     201                 : 
     202                 : /************************************************************************/
     203                 : /* ==================================================================== */
     204                 : /*                             SRTMHGTDataset                               */
     205                 : /* ==================================================================== */
     206                 : /************************************************************************/
     207                 : 
     208                 : 
     209                 : /************************************************************************/
     210                 : /*                            SRTMHGTDataset()                              */
     211                 : /************************************************************************/
     212                 : 
     213               5 : SRTMHGTDataset::SRTMHGTDataset()
     214                 : {
     215               5 :   adfGeoTransform[0] = 0.0;
     216               5 :   adfGeoTransform[1] = 1.0;
     217               5 :   adfGeoTransform[2] = 0.0;
     218               5 :   adfGeoTransform[3] = 0.0;
     219               5 :   adfGeoTransform[4] = 0.0;
     220               5 :   adfGeoTransform[5] = 1.0;
     221               5 :   fpImage = NULL;
     222               5 :   panBuffer = NULL;
     223               5 : }
     224                 : 
     225                 : /************************************************************************/
     226                 : /*                           ~SRTMHGTDataset()                            */
     227                 : /************************************************************************/
     228                 : 
     229              10 : SRTMHGTDataset::~SRTMHGTDataset()
     230                 : {
     231               5 :   FlushCache();
     232               5 :   if(fpImage != NULL)
     233               5 :     VSIFCloseL(fpImage);
     234               5 :   CPLFree(panBuffer);
     235              10 : }
     236                 : 
     237                 : /************************************************************************/
     238                 : /*                          GetGeoTransform()                           */
     239                 : /************************************************************************/
     240                 : 
     241               4 : CPLErr SRTMHGTDataset::GetGeoTransform(double * padfTransform)
     242                 : {
     243               4 :   memcpy(padfTransform, adfGeoTransform, sizeof(double)*6);
     244               4 :   return CE_None;
     245                 : }
     246                 : 
     247                 : /************************************************************************/
     248                 : /*                          GetProjectionRef()                          */
     249                 : /************************************************************************/
     250                 : 
     251               6 : const char *SRTMHGTDataset::GetProjectionRef()
     252                 : 
     253                 : {
     254               6 :     return( SRS_WKT_WGS84 );
     255                 : }
     256                 : 
     257                 : /************************************************************************/
     258                 : /*                              Identify()                              */
     259                 : /************************************************************************/
     260                 : 
     261            9510 : int SRTMHGTDataset::Identify( GDALOpenInfo * poOpenInfo )
     262                 : 
     263                 : {
     264            9510 :   const char* fileName = CPLGetFilename(poOpenInfo->pszFilename);
     265            9510 :   if( strlen(fileName) < 11 || !EQUALN(&fileName[7], ".hgt", 4) )
     266            9503 :     return FALSE;
     267                 : 
     268                 : /* -------------------------------------------------------------------- */
     269                 : /*  We check the file size to see if it is 25,934,402 bytes         */
     270                 : /*  (SRTM 1) or 2,884,802 bytes (SRTM 3)        */    
     271                 : /* -------------------------------------------------------------------- */
     272                 :   VSIStatBufL fileStat;
     273                 : 
     274               7 :   if(VSIStatL(poOpenInfo->pszFilename, &fileStat) != 0)
     275               2 :       return FALSE;
     276               5 :   if(fileStat.st_size != 25934402 && fileStat.st_size != 2884802)
     277               0 :       return FALSE;
     278                 : 
     279               5 :   return TRUE;
     280                 : }
     281                 : 
     282                 : /************************************************************************/
     283                 : /*                                Open()                                */
     284                 : /************************************************************************/
     285                 : 
     286            1781 : GDALDataset* SRTMHGTDataset::Open(GDALOpenInfo* poOpenInfo)
     287                 : {
     288            1781 :   if (!Identify(poOpenInfo))
     289            1776 :       return NULL;
     290                 :   
     291               5 :   const char* fileName = CPLGetFilename(poOpenInfo->pszFilename);
     292                 : 
     293                 :   char latLonValueString[4];
     294               5 :   memset(latLonValueString, 0, 4);
     295               5 :   strncpy(latLonValueString, &fileName[1], 2);
     296               5 :   int southWestLat = atoi(latLonValueString);
     297               5 :   memset(latLonValueString, 0, 4);
     298               5 :   strncpy(latLonValueString, &fileName[4], 3);
     299               5 :   int southWestLon = atoi(latLonValueString);
     300                 : 
     301              10 :   if(fileName[0] == 'N' || fileName[0] == 'n')
     302               5 :     southWestLat = southWestLat;
     303               0 :   else if(fileName[0] == 'S' || fileName[0] == 's')
     304               0 :     southWestLat = southWestLat * -1;
     305                 :   else
     306               0 :     return NULL;
     307                 : 
     308               5 :   if(fileName[3] == 'E' || fileName[3] == 'e')
     309               0 :     southWestLon = southWestLon;
     310              10 :   else if(fileName[3] == 'W' || fileName[3] == 'w')
     311               5 :     southWestLon = southWestLon * -1;
     312                 :   else
     313               0 :     return NULL;
     314                 : 
     315                 : /* -------------------------------------------------------------------- */
     316                 : /*      Create a corresponding GDALDataset.                             */
     317                 : /* -------------------------------------------------------------------- */
     318                 :   SRTMHGTDataset* poDS;
     319                 : 
     320               5 :   poDS = new SRTMHGTDataset();
     321                 : 
     322                 : /* -------------------------------------------------------------------- */
     323                 : /*      Open the file using the large file api.                         */
     324                 : /* -------------------------------------------------------------------- */
     325               5 :   poDS->fpImage = VSIFOpenL(poOpenInfo->pszFilename, (poOpenInfo->eAccess == GA_Update) ? "rb+" : "rb");
     326               5 :   if(poDS->fpImage == NULL)
     327                 :   {
     328               0 :     CPLError(CE_Failure, CPLE_OpenFailed, "VSIFOpenL(%s) failed unexpectedly in srtmhgtdataset.cpp", poOpenInfo->pszFilename);
     329               0 :     return NULL;
     330                 :   }
     331                 : 
     332                 :   VSIStatBufL fileStat;
     333               5 :   if(VSIStatL(poOpenInfo->pszFilename, &fileStat) != 0)
     334                 :   {
     335               0 :       return NULL;
     336                 :   }
     337               5 :   int numPixels = (fileStat.st_size == 25934402) ? 3601 : /* 2884802 */ 1201;
     338                 : 
     339               5 :   poDS->eAccess = poOpenInfo->eAccess;
     340                 : #ifdef CPL_LSB
     341               5 :   if(poDS->eAccess == GA_Update)
     342                 :   {
     343               0 :       poDS->panBuffer = (GInt16*) CPLMalloc(numPixels * sizeof(GInt16));
     344                 :   }
     345                 : #endif
     346                 : 
     347                 : /* -------------------------------------------------------------------- */
     348                 : /*      Capture some information from the file that is of interest.     */
     349                 : /* -------------------------------------------------------------------- */
     350               5 :   poDS->nRasterXSize = numPixels;
     351               5 :   poDS->nRasterYSize = numPixels;
     352               5 :   poDS->nBands = 1;
     353                 : 
     354               5 :   poDS->adfGeoTransform[0] = southWestLon - 0.5 / (numPixels - 1);
     355               5 :   poDS->adfGeoTransform[1] = 1.0 / (numPixels-1);
     356               5 :   poDS->adfGeoTransform[2] = 0.0000000000;
     357               5 :   poDS->adfGeoTransform[3] = southWestLat + 1 + 0.5 / (numPixels - 1);
     358               5 :   poDS->adfGeoTransform[4] = 0.0000000000;
     359               5 :   poDS->adfGeoTransform[5] = -1.0 / (numPixels-1);
     360                 : 
     361               5 :   poDS->SetMetadataItem( GDALMD_AREA_OR_POINT, GDALMD_AOP_POINT );
     362                 :   
     363                 : /* -------------------------------------------------------------------- */
     364                 : /*      Create band information object.                                 */
     365                 : /* -------------------------------------------------------------------- */
     366               5 :   SRTMHGTRasterBand* tmpBand = new SRTMHGTRasterBand(poDS, 1);
     367               5 :   poDS->SetBand(1, tmpBand);
     368                 : 
     369                 : /* -------------------------------------------------------------------- */
     370                 : /*      Initialize any PAM information.                                 */
     371                 : /* -------------------------------------------------------------------- */
     372               5 :   poDS->SetDescription(poOpenInfo->pszFilename);
     373               5 :   poDS->TryLoadXML();
     374                 : 
     375                 : /* -------------------------------------------------------------------- */
     376                 : /*      Support overviews.                                              */
     377                 : /* -------------------------------------------------------------------- */
     378               5 :   poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename );
     379                 : 
     380               5 :   return poDS;
     381                 : }
     382                 : 
     383                 : /************************************************************************/
     384                 : /*                              CreateCopy()                            */
     385                 : /************************************************************************/
     386                 : 
     387              18 : GDALDataset * SRTMHGTDataset::CreateCopy( const char * pszFilename, GDALDataset *poSrcDS, 
     388                 :                                           int bStrict, char ** papszOptions, 
     389                 :                                           GDALProgressFunc pfnProgress, void * pProgressData )
     390                 : 
     391                 : {
     392              18 :     int  nBands = poSrcDS->GetRasterCount();
     393              18 :     int  nXSize = poSrcDS->GetRasterXSize();
     394              18 :     int  nYSize = poSrcDS->GetRasterYSize();
     395                 : 
     396              18 :     if( pfnProgress && !pfnProgress( 0.0, NULL, pProgressData ) )
     397               0 :         return NULL;
     398                 : 
     399                 : /* -------------------------------------------------------------------- */
     400                 : /*      Some some rudimentary checks                                    */
     401                 : /* -------------------------------------------------------------------- */
     402              18 :     if (nBands == 0)
     403                 :     {
     404                 :         CPLError( CE_Failure, CPLE_NotSupported, 
     405               1 :                   "SRTMHGT driver does not support source dataset with zero band.\n");
     406               1 :         return NULL;
     407                 :     }
     408              17 :     else if (nBands != 1)
     409                 :     {
     410                 :         CPLError( (bStrict) ? CE_Failure : CE_Warning, CPLE_NotSupported, 
     411               4 :                   "SRTMHGT driver only uses the first band of the dataset.\n");
     412               4 :         if (bStrict)
     413               4 :             return NULL;
     414                 :     }
     415                 : 
     416                 : /* -------------------------------------------------------------------- */
     417                 : /*      Checks the input SRS                                            */
     418                 : /* -------------------------------------------------------------------- */
     419              13 :     OGRSpatialReference ogrsr_input;
     420              13 :     OGRSpatialReference ogrsr_wgs84;
     421              13 :     char* c = (char*)poSrcDS->GetProjectionRef();
     422              13 :     ogrsr_input.importFromWkt(&c);
     423              13 :     ogrsr_wgs84.SetWellKnownGeogCS( "WGS84" );
     424              13 :     if ( ogrsr_input.IsSameGeogCS(&ogrsr_wgs84) == FALSE)
     425                 :     {
     426                 :         CPLError( CE_Warning, CPLE_AppDefined, 
     427                 :                   "The source projection coordinate system is %s. Only WGS 84 is supported.\n"
     428                 :                   "The SRTMHGT driver will generate a file as if the source was WGS 84 projection coordinate system.",
     429               0 :                   poSrcDS->GetProjectionRef() );
     430                 :     }
     431                 : 
     432                 : /* -------------------------------------------------------------------- */
     433                 : /*      Work out the LL origin.                                         */
     434                 : /* -------------------------------------------------------------------- */
     435                 :     int  nLLOriginLat, nLLOriginLong;
     436                 :     double adfGeoTransform[6];
     437                 : 
     438              13 :     if (poSrcDS->GetGeoTransform( adfGeoTransform ) != CE_None)
     439                 :     {
     440                 :         CPLError( CE_Failure, CPLE_AppDefined, 
     441               0 :                   "Source image must have a geo transform matrix.");
     442               0 :         return NULL;
     443                 :     }
     444                 : 
     445                 :     nLLOriginLat = (int) 
     446              13 :         floor(adfGeoTransform[3] 
     447              13 :               + poSrcDS->GetRasterYSize() * adfGeoTransform[5] + 0.5);
     448                 : 
     449              13 :     nLLOriginLong = (int) floor(adfGeoTransform[0] + 0.5);
     450                 : 
     451              28 :     if (fabs(nLLOriginLat - (adfGeoTransform[3] 
     452              13 :               + (poSrcDS->GetRasterYSize() - 0.5) * adfGeoTransform[5])) > 1e-10 ||
     453               2 :         fabs(nLLOriginLong - (adfGeoTransform[0] + 0.5 * adfGeoTransform[1])) > 1e-10)
     454                 :     {
     455                 :         CPLError( CE_Warning, CPLE_AppDefined, 
     456                 :                "The corner coordinates of the source are not properly "
     457              11 :                "aligned on plain latitude/longitude boundaries.");
     458                 :     }
     459                 : 
     460                 : /* -------------------------------------------------------------------- */
     461                 : /*      Check image dimensions.                                         */
     462                 : /* -------------------------------------------------------------------- */
     463              13 :     if (!((nXSize == 1201 && nYSize == 1201) || (nXSize == 3601 && nYSize == 3601)))
     464                 :     {
     465                 :         CPLError( CE_Failure, CPLE_AppDefined, 
     466              11 :                   "Image dimensions should be 1201x1201 or 3601x3601.");
     467              11 :         return NULL;
     468                 :     }
     469                 : 
     470                 : /* -------------------------------------------------------------------- */
     471                 : /*      Check filename.                                                 */
     472                 : /* -------------------------------------------------------------------- */
     473                 :     char expectedFileName[12];
     474                 :     snprintf(expectedFileName, sizeof(expectedFileName), "%c%02d%c%03d.HGT",
     475                 :              (nLLOriginLat >= 0) ? 'N' : 'S',
     476                 :              (nLLOriginLat >= 0) ? nLLOriginLat : -nLLOriginLat,
     477                 :              (nLLOriginLong >= 0) ? 'E' : 'W',
     478               2 :              (nLLOriginLong >= 0) ? nLLOriginLong : -nLLOriginLong);
     479               2 :     if (!EQUAL(expectedFileName, CPLGetFilename(pszFilename)))
     480                 :     {
     481                 :         CPLError( CE_Warning, CPLE_AppDefined, 
     482               0 :                   "Expected output filename is %s.", expectedFileName);
     483                 :     }
     484                 : 
     485                 : /* -------------------------------------------------------------------- */
     486                 : /*      Write output file.                                              */
     487                 : /* -------------------------------------------------------------------- */
     488               2 :     FILE* fp = VSIFOpenL(pszFilename, "wb");
     489                 : 
     490               2 :     GInt16* panData = (GInt16*) CPLMalloc(sizeof(GInt16) * nXSize);
     491               2 :     GDALRasterBand* poSrcBand = poSrcDS->GetRasterBand(1);
     492                 : 
     493                 :     int bSrcBandHasNoData;
     494               2 :     double srcBandNoData = poSrcBand->GetNoDataValue(&bSrcBandHasNoData);
     495                 : 
     496            2404 :     for( int iY = 0; iY < nYSize; iY++ )
     497                 :     {
     498                 :         poSrcBand->RasterIO( GF_Read, 0, iY, nXSize, 1,
     499                 :                             (void *) panData, nXSize, 1,
     500            2402 :                             GDT_Int16, 0, 0 );
     501                 : 
     502                 :         /* Translate nodata values */
     503            2402 :         if (bSrcBandHasNoData && srcBandNoData != SRTMHG_NODATA_VALUE)
     504                 :         {
     505               0 :             for( int iX = 0; iX < nXSize; iX++ )
     506                 :             {
     507               0 :                 if (panData[iX] == srcBandNoData)
     508               0 :                     panData[iX] = SRTMHG_NODATA_VALUE;
     509                 :             }
     510                 :         }
     511                 : 
     512                 : #ifdef CPL_LSB
     513            2402 :         GDALSwapWords(panData, 2, nXSize, 2);
     514                 : #endif
     515                 : 
     516            2402 :         if( VSIFWriteL( panData,sizeof(GInt16) * nXSize,1,fp ) != 1)
     517                 :         {
     518                 :             CPLError( CE_Failure, CPLE_FileIO,
     519                 :                       "Failed to write line %d in SRTMHGT dataset.\n",
     520               0 :                       iY );
     521               0 :             VSIFCloseL(fp);
     522               0 :             CPLFree( panData );
     523               0 :             return NULL;
     524                 :         }
     525                 : 
     526            2402 :         if( pfnProgress && !pfnProgress((iY+1) / (double) nYSize, NULL, pProgressData ) )
     527                 :         {
     528                 :             CPLError( CE_Failure, CPLE_UserInterrupt, 
     529               0 :                         "User terminated CreateCopy()" );
     530               0 :             VSIFCloseL(fp);
     531               0 :             CPLFree( panData );
     532               0 :             return NULL;
     533                 :         }
     534                 :     }
     535                 : 
     536               2 :     CPLFree( panData );
     537               2 :     VSIFCloseL(fp);
     538                 : 
     539                 : /* -------------------------------------------------------------------- */
     540                 : /*      Reopen and copy missing information into a PAM file.            */
     541                 : /* -------------------------------------------------------------------- */
     542                 :     GDALPamDataset *poDS = (GDALPamDataset *) 
     543               2 :         GDALOpen( pszFilename, GA_ReadOnly );
     544                 : 
     545               2 :     if( poDS )
     546               2 :         poDS->CloneInfo( poSrcDS, GCIF_PAM_DEFAULT);
     547                 : 
     548               2 :     return poDS;
     549                 : }
     550                 : 
     551                 : /************************************************************************/
     552                 : /*                         GDALRegister_SRTMHGT()                          */
     553                 : /************************************************************************/
     554             338 : void GDALRegister_SRTMHGT()
     555                 : {
     556                 :   GDALDriver*  poDriver;
     557                 : 
     558             338 :   if(GDALGetDriverByName("SRTMHGT") == NULL)
     559                 :   {
     560             336 :     poDriver = new GDALDriver();
     561             336 :     poDriver->SetDescription("SRTMHGT");
     562             336 :     poDriver->SetMetadataItem(GDAL_DMD_LONGNAME, "SRTMHGT File Format");
     563             336 :     poDriver->SetMetadataItem(GDAL_DMD_EXTENSION, "hgt");
     564                 :     poDriver->SetMetadataItem(GDAL_DMD_HELPTOPIC, 
     565             336 :                               "frmt_various.html#SRTMHGT" );
     566                 :     poDriver->SetMetadataItem( GDAL_DMD_CREATIONDATATYPES, 
     567             336 :                                    "Byte Int16 UInt16" );
     568                 : 
     569             336 :     poDriver->SetMetadataItem( GDAL_DCAP_VIRTUALIO, "YES" );
     570                 : 
     571             336 :     poDriver->pfnIdentify = SRTMHGTDataset::Identify;
     572             336 :     poDriver->pfnOpen = SRTMHGTDataset::Open;
     573             336 :     poDriver->pfnCreateCopy = SRTMHGTDataset::CreateCopy;
     574                 : 
     575             336 :     GetGDALDriverManager()->RegisterDriver(poDriver);
     576                 :   }
     577             338 : }
     578                 : 

Generated by: LCOV version 1.7