LCOV - code coverage report
Current view: directory - frmts/netcdf - gmtdataset.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 216 167 77.3 %
Date: 2010-01-09 Functions: 11 11 100.0 %

       1                 : /******************************************************************************
       2                 :  * $Id: gmtdataset.cpp 17664 2009-09-21 21:16:45Z rouault $
       3                 :  *
       4                 :  * Project:  netCDF read/write Driver
       5                 :  * Purpose:  GDAL bindings over netCDF library for GMT Grids.
       6                 :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       7                 :  *
       8                 :  ******************************************************************************
       9                 :  * Copyright (c) 2004, Frank Warmerdam
      10                 :  *
      11                 :  * Permission is hereby granted, free of charge, to any person obtaining a
      12                 :  * copy of this software and associated documentation files (the "Software"),
      13                 :  * to deal in the Software without restriction, including without limitation
      14                 :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      15                 :  * and/or sell copies of the Software, and to permit persons to whom the
      16                 :  * Software is furnished to do so, subject to the following conditions:
      17                 :  *
      18                 :  * The above copyright notice and this permission notice shall be included
      19                 :  * in all copies or substantial portions of the Software.
      20                 :  *
      21                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      22                 :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      23                 :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      24                 :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      25                 :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      26                 :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      27                 :  * DEALINGS IN THE SOFTWARE.
      28                 :  ****************************************************************************/
      29                 : 
      30                 : #include "gdal_pam.h"
      31                 : #include "gdal_frmts.h"
      32                 : #include "netcdf.h"
      33                 : 
      34                 : CPL_CVSID("$Id: gmtdataset.cpp 17664 2009-09-21 21:16:45Z rouault $");
      35                 : 
      36                 : /************************************************************************/
      37                 : /* ==================================================================== */
      38                 : /*           GMTDataset               */
      39                 : /* ==================================================================== */
      40                 : /************************************************************************/
      41                 : 
      42                 : class GMTRasterBand;
      43                 : 
      44                 : class GMTDataset : public GDALPamDataset
      45               8 : {
      46                 :     int         z_id;
      47                 :     double      adfGeoTransform[6];
      48                 : 
      49                 :   public:
      50                 :     int         cdfid;
      51                 : 
      52                 :     ~GMTDataset();
      53                 :     
      54                 :     static GDALDataset *Open( GDALOpenInfo * );
      55                 : 
      56                 :     CPLErr  GetGeoTransform( double * padfTransform );
      57                 : };
      58                 : 
      59                 : /************************************************************************/
      60                 : /* ==================================================================== */
      61                 : /*                         GMTRasterBand                                */
      62                 : /* ==================================================================== */
      63                 : /************************************************************************/
      64                 : 
      65                 : class GMTRasterBand : public GDALPamRasterBand
      66              16 : {
      67                 :     nc_type nc_datatype;
      68                 :     int         nZId;
      69                 : 
      70                 :   public:
      71                 : 
      72                 :         GMTRasterBand( GMTDataset *poDS, int nZId, int nBand );
      73                 :     
      74                 :     virtual CPLErr IReadBlock( int, int, void * );
      75                 : };
      76                 : 
      77                 : 
      78                 : /************************************************************************/
      79                 : /*                           GMTRasterBand()                            */
      80                 : /************************************************************************/
      81                 : 
      82               8 : GMTRasterBand::GMTRasterBand( GMTDataset *poDS, int nZId, int nBand )
      83                 : 
      84                 : {
      85               8 :     this->poDS = poDS;
      86               8 :     this->nBand = nBand;
      87               8 :     this->nZId = nZId;
      88                 :     
      89               8 :     nBlockXSize = poDS->GetRasterXSize();
      90               8 :     nBlockYSize = 1;
      91                 : 
      92                 : /* -------------------------------------------------------------------- */
      93                 : /*      Get the type of the "z" variable, our target raster array.      */
      94                 : /* -------------------------------------------------------------------- */
      95               8 :     if( nc_inq_var( poDS->cdfid, nZId, NULL, &nc_datatype, NULL, NULL,
      96                 :                     NULL ) != NC_NOERR )
      97                 :     {
      98                 :         CPLError( CE_Failure, CPLE_AppDefined, 
      99               0 :                   "Error in nc_var_inq() on 'z'." );
     100               0 :         return;
     101                 :     }
     102                 : 
     103               8 :     if( nc_datatype == NC_BYTE )
     104               0 :         eDataType = GDT_Byte;
     105               8 :     else if( nc_datatype == NC_SHORT )
     106               4 :         eDataType = GDT_Int16;
     107               4 :     else if( nc_datatype == NC_INT )
     108               1 :         eDataType = GDT_Int32;
     109               3 :     else if( nc_datatype == NC_FLOAT )
     110               2 :         eDataType = GDT_Float32;
     111               1 :     else if( nc_datatype == NC_DOUBLE )
     112               1 :         eDataType = GDT_Float64;
     113                 :     else
     114                 :     {
     115               0 :         if( nBand == 1 )
     116                 :             CPLError( CE_Warning, CPLE_AppDefined, 
     117                 :                       "Unsupported GMT datatype (%d), treat as Float32.", 
     118               0 :                       (int) nc_datatype );
     119               0 :         eDataType = GDT_Float32;
     120                 :     }
     121               0 : }
     122                 : 
     123                 : /************************************************************************/
     124                 : /*                             IReadBlock()                             */
     125                 : /************************************************************************/
     126                 : 
     127              90 : CPLErr GMTRasterBand::IReadBlock( int nBlockXOff, int nBlockYOff,
     128                 :                                   void * pImage )
     129                 : 
     130                 : {
     131                 :     size_t start[2], edge[2];
     132                 :     int    nErr;
     133              90 :     int    cdfid = ((GMTDataset *) poDS)->cdfid;
     134                 : 
     135              90 :     start[0] = nBlockYOff * nBlockXSize;
     136              90 :     edge[0] = nBlockXSize;
     137                 : 
     138              90 :     if( eDataType == GDT_Byte )
     139                 :         nErr = nc_get_vara_uchar( cdfid, nZId, start, edge, 
     140               0 :                                   (unsigned char *) pImage );
     141              90 :     else if( eDataType == GDT_Int16 )
     142                 :         nErr = nc_get_vara_short( cdfid, nZId, start, edge, 
     143              40 :                                   (short int *) pImage );
     144              50 :     else if( eDataType == GDT_Int32 )
     145                 :     {
     146                 :         if( sizeof(long) == 4 )
     147                 :             nErr = nc_get_vara_long( cdfid, nZId, start, edge, 
     148               0 :                                      (long *) pImage );
     149                 :         else
     150                 :             nErr = nc_get_vara_int( cdfid, nZId, start, edge, 
     151                 :                                     (int *) pImage );
     152                 :     }
     153              50 :     else if( eDataType == GDT_Float32 )
     154                 :         nErr = nc_get_vara_float( cdfid, nZId, start, edge, 
     155              50 :                                   (float *) pImage );
     156               0 :     else if( eDataType == GDT_Float64 )
     157                 :         nErr = nc_get_vara_double( cdfid, nZId, start, edge, 
     158               0 :                                    (double *) pImage );
     159                 : 
     160              90 :     if( nErr != NC_NOERR )
     161                 :     {
     162                 :         CPLError( CE_Failure, CPLE_AppDefined, 
     163                 :                   "GMT scanline fetch failed: %s", 
     164               0 :                   nc_strerror( nErr ) );
     165               0 :         return CE_Failure;
     166                 :     }
     167                 :     else
     168              90 :         return CE_None;
     169                 : }
     170                 : 
     171                 : /************************************************************************/
     172                 : /* ==================================================================== */
     173                 : /*        GMTDataset        */
     174                 : /* ==================================================================== */
     175                 : /************************************************************************/
     176                 : 
     177                 : /************************************************************************/
     178                 : /*                            ~GMTDataset()                             */
     179                 : /************************************************************************/
     180                 : 
     181              16 : GMTDataset::~GMTDataset()
     182                 : 
     183                 : {
     184               8 :     FlushCache();
     185               8 :     nc_close (cdfid);
     186              16 : }
     187                 : 
     188                 : /************************************************************************/
     189                 : /*                          GetGeoTransform()                           */
     190                 : /************************************************************************/
     191                 : 
     192               7 : CPLErr GMTDataset::GetGeoTransform( double * padfTransform )
     193                 : 
     194                 : {
     195               7 :     memcpy( padfTransform, adfGeoTransform, sizeof(double) * 6 );
     196               7 :     return CE_None;
     197                 : }
     198                 : 
     199                 : /************************************************************************/
     200                 : /*                                Open()                                */
     201                 : /************************************************************************/
     202                 : 
     203            9504 : GDALDataset *GMTDataset::Open( GDALOpenInfo * poOpenInfo )
     204                 : 
     205                 : {
     206                 : /* -------------------------------------------------------------------- */
     207                 : /*      Does this file have the GMT magic number?                    */
     208                 : /* -------------------------------------------------------------------- */
     209            9504 :     if( poOpenInfo->fp == NULL || poOpenInfo->nHeaderBytes < 50 )
     210            8702 :         return NULL;
     211                 : 
     212             883 :     if( poOpenInfo->pabyHeader[0] != 'C' 
     213              29 :         || poOpenInfo->pabyHeader[1] != 'D' 
     214              26 :         || poOpenInfo->pabyHeader[2] != 'F' 
     215              26 :         || poOpenInfo->pabyHeader[3] != 1 )
     216             776 :         return NULL;
     217                 : 
     218                 : /* -------------------------------------------------------------------- */
     219                 : /*      Try opening the dataset.                                        */
     220                 : /* -------------------------------------------------------------------- */
     221                 :     int cdfid, nm_id, dim_count, z_id;
     222                 : 
     223              26 :     if( nc_open( poOpenInfo->pszFilename, NC_NOWRITE, &cdfid ) != NC_NOERR )
     224               0 :         return NULL;
     225                 : 
     226              26 :     if( nc_inq_varid( cdfid, "dimension", &nm_id ) != NC_NOERR 
     227                 :         || nc_inq_varid( cdfid, "z", &z_id ) != NC_NOERR )
     228                 :     {
     229                 : #ifdef notdef
     230                 :         CPLError( CE_Warning, CPLE_AppDefined, 
     231                 :                   "%s is a GMT file, but not in GMT configuration.",
     232                 :                   poOpenInfo->pszFilename );
     233                 : #endif
     234              18 :         nc_close( cdfid );
     235              18 :         return NULL;
     236                 :     }
     237                 : 
     238               8 :     if( nc_inq_ndims( cdfid, &dim_count ) != NC_NOERR || dim_count < 2 )
     239                 :     {
     240               0 :         nc_close( cdfid );
     241               0 :         return NULL;
     242                 :     }
     243                 :     
     244                 : /* -------------------------------------------------------------------- */
     245                 : /*      Confirm the requested access is supported.                      */
     246                 : /* -------------------------------------------------------------------- */
     247               8 :     if( poOpenInfo->eAccess == GA_Update )
     248                 :     {
     249               0 :         nc_close( cdfid );
     250                 :         CPLError( CE_Failure, CPLE_NotSupported, 
     251                 :                   "The GMT driver does not support update access to existing"
     252               0 :                   " datasets.\n" );
     253               0 :         return NULL;
     254                 :     }
     255                 :     
     256                 : /* -------------------------------------------------------------------- */
     257                 : /*      Create a corresponding GDALDataset.                             */
     258                 : /* -------------------------------------------------------------------- */
     259                 :     GMTDataset  *poDS;
     260                 : 
     261               8 :     poDS = new GMTDataset();
     262                 : 
     263               8 :     poDS->cdfid = cdfid;
     264               8 :     poDS->z_id = z_id;
     265                 :     
     266                 : /* -------------------------------------------------------------------- */
     267                 : /*      Get dimensions.  If we can't find this, then this is a          */
     268                 : /*      GMT file, but not a normal grid product.                     */
     269                 : /* -------------------------------------------------------------------- */
     270                 :     size_t start[2], edge[2];
     271                 :     int    nm[2];
     272                 : 
     273               8 :     start[0] = 0;
     274               8 :     edge[0] = 2;
     275                 : 
     276               8 :     nc_get_vara_int(cdfid, nm_id, start, edge, nm);
     277                 :     
     278               8 :     poDS->nRasterXSize = nm[0];
     279               8 :     poDS->nRasterYSize = nm[1];
     280                 : 
     281                 : /* -------------------------------------------------------------------- */
     282                 : /*      Fetch "z" attributes scale_factor, add_offset, and              */
     283                 : /*      node_offset.                                                    */
     284                 : /* -------------------------------------------------------------------- */
     285               8 :     double scale_factor=1.0, add_offset=0.0;
     286               8 :     int node_offset = 1;
     287                 : 
     288               8 :     nc_get_att_double( cdfid, z_id, "scale_factor", &scale_factor );
     289               8 :     nc_get_att_double( cdfid, z_id, "add_offset", &add_offset );
     290               8 :     nc_get_att_int( cdfid, z_id, "node_offset", &node_offset );
     291                 : 
     292                 : /* -------------------------------------------------------------------- */
     293                 : /*      Get x/y range information.                                      */
     294                 : /* -------------------------------------------------------------------- */
     295                 :     int x_range_id, y_range_id;
     296                 : 
     297              16 :     if( nc_inq_varid (cdfid, "x_range", &x_range_id) == NC_NOERR 
     298                 :         && nc_inq_varid (cdfid, "y_range", &y_range_id) == NC_NOERR )
     299                 :     {
     300                 :         double x_range[2], y_range[2];
     301                 : 
     302               8 :         nc_get_vara_double( cdfid, x_range_id, start, edge, x_range );
     303               8 :         nc_get_vara_double( cdfid, y_range_id, start, edge, y_range );
     304                 : 
     305                 :         // Pixel is area
     306               8 :         if( node_offset == 1 )
     307                 :         {
     308               8 :             poDS->adfGeoTransform[0] = x_range[0];
     309                 :             poDS->adfGeoTransform[1] = 
     310               8 :                 (x_range[1] - x_range[0]) / poDS->nRasterXSize;
     311               8 :             poDS->adfGeoTransform[2] = 0.0;
     312               8 :             poDS->adfGeoTransform[3] = y_range[1];
     313               8 :             poDS->adfGeoTransform[4] = 0.0;
     314                 :             poDS->adfGeoTransform[5] = 
     315               8 :                 (y_range[0] - y_range[1]) / poDS->nRasterYSize;
     316                 :         }
     317                 : 
     318                 :         // Pixel is point - offset by half pixel. 
     319                 :         else /* node_offset == 0 */ 
     320                 :         {
     321                 :             poDS->adfGeoTransform[1] = 
     322               0 :                 (x_range[1] - x_range[0]) / (poDS->nRasterXSize-1);
     323                 :             poDS->adfGeoTransform[0] = 
     324               0 :                 x_range[0] - poDS->adfGeoTransform[1]*0.5;
     325               0 :             poDS->adfGeoTransform[2] = 0.0;
     326               0 :             poDS->adfGeoTransform[4] = 0.0;
     327                 :             poDS->adfGeoTransform[5] = 
     328               0 :                 (y_range[0] - y_range[1]) / (poDS->nRasterYSize-1);
     329                 :             poDS->adfGeoTransform[3] = 
     330               0 :                 y_range[1] - poDS->adfGeoTransform[5]*0.5;
     331                 :         }
     332                 :     }
     333                 :     else
     334                 :     {
     335               0 :         poDS->adfGeoTransform[0] = 0.0;
     336               0 :         poDS->adfGeoTransform[1] = 1.0;
     337               0 :         poDS->adfGeoTransform[2] = 0.0;
     338               0 :         poDS->adfGeoTransform[3] = 0.0;
     339               0 :         poDS->adfGeoTransform[4] = 0.0;
     340               0 :         poDS->adfGeoTransform[5] = 1.0;
     341                 :     }
     342                 : 
     343                 : /* -------------------------------------------------------------------- */
     344                 : /*      Create band information objects.                                */
     345                 : /* -------------------------------------------------------------------- */
     346               8 :     poDS->nBands = 1;
     347               8 :     poDS->SetBand( 1, new GMTRasterBand( poDS, z_id, 1 ));
     348                 : 
     349              16 :     if( scale_factor != 1.0 || add_offset != 0.0 )
     350                 :     {
     351               0 :         poDS->GetRasterBand(1)->SetOffset( add_offset );
     352               0 :         poDS->GetRasterBand(1)->SetScale( scale_factor );
     353                 :     }
     354                 : 
     355                 : /* -------------------------------------------------------------------- */
     356                 : /*      Initialize any PAM information.                                 */
     357                 : /* -------------------------------------------------------------------- */
     358               8 :     poDS->SetDescription( poOpenInfo->pszFilename );
     359               8 :     poDS->TryLoadXML();
     360                 : 
     361               8 :     return( poDS );
     362                 : }
     363                 : 
     364                 : /************************************************************************/
     365                 : /*                           GMTCreateCopy()                            */
     366                 : /*                                                                      */
     367                 : /*      This code mostly cribbed from GMT's "gmt_cdf.c" module.         */
     368                 : /************************************************************************/
     369                 : 
     370                 : static GDALDataset *
     371              17 : GMTCreateCopy( const char * pszFilename, GDALDataset *poSrcDS, 
     372                 :                   int bStrict, char ** papszOptions, 
     373                 :                   GDALProgressFunc pfnProgress, void * pProgressData )
     374                 : 
     375                 : {
     376                 : /* -------------------------------------------------------------------- */
     377                 : /*      Figure out general characteristics.                             */
     378                 : /* -------------------------------------------------------------------- */
     379                 :     nc_type nc_datatype;
     380                 :     GDALRasterBand *poBand;
     381                 :     int nXSize, nYSize;
     382                 : 
     383              17 :     if( poSrcDS->GetRasterCount() != 1 )
     384                 :     {
     385                 :         CPLError( CE_Failure, CPLE_AppDefined, 
     386               5 :                   "Currently GMT export only supports 1 band datasets." );
     387               5 :         return NULL;
     388                 :     }
     389                 : 
     390              12 :     poBand = poSrcDS->GetRasterBand(1);
     391                 : 
     392              12 :     nXSize = poSrcDS->GetRasterXSize();
     393              12 :     nYSize = poSrcDS->GetRasterYSize();
     394                 :     
     395              12 :     if( poBand->GetRasterDataType() == GDT_Int16 )
     396               2 :         nc_datatype = NC_SHORT;
     397              10 :     else if( poBand->GetRasterDataType() == GDT_Int32 )
     398               1 :         nc_datatype = NC_INT;
     399               9 :     else if( poBand->GetRasterDataType() == GDT_Float32 )
     400               1 :         nc_datatype = NC_FLOAT;
     401               8 :     else if( poBand->GetRasterDataType() == GDT_Float64 )
     402               1 :         nc_datatype = NC_DOUBLE;
     403               7 :     else if( bStrict )
     404                 :     {
     405                 :         CPLError( CE_Failure, CPLE_AppDefined, 
     406                 :                   "Band data type %s not supported in GMT, giving up.",
     407               7 :                   GDALGetDataTypeName( poBand->GetRasterDataType() ) );
     408               7 :         return NULL;
     409                 :     }
     410               0 :     else if( poBand->GetRasterDataType() == GDT_Byte )
     411               0 :         nc_datatype = NC_SHORT;
     412               0 :     else if( poBand->GetRasterDataType() == GDT_UInt16 )
     413               0 :         nc_datatype = NC_INT;
     414               0 :     else if( poBand->GetRasterDataType() == GDT_UInt32 )
     415               0 :         nc_datatype = NC_INT;
     416                 :     else 
     417               0 :         nc_datatype = NC_FLOAT;
     418                 :     
     419                 : /* -------------------------------------------------------------------- */
     420                 : /*      Establish bounds from geotransform.                             */
     421                 : /* -------------------------------------------------------------------- */
     422                 :     double adfGeoTransform[6];
     423                 :     double dfXMax, dfYMin;
     424                 : 
     425               5 :     poSrcDS->GetGeoTransform( adfGeoTransform );
     426                 :     
     427               5 :     if( adfGeoTransform[2] != 0.0 || adfGeoTransform[4] != 0.0 )
     428                 :     {
     429                 :         CPLError( bStrict ? CE_Failure : CE_Warning, CPLE_AppDefined, 
     430               0 :                   "Geotransform has rotational coefficients not supported in GMT." );
     431               0 :         if( bStrict )
     432               0 :             return NULL;
     433                 :     }
     434                 : 
     435               5 :     dfXMax = adfGeoTransform[0] + adfGeoTransform[1] * nXSize;
     436               5 :     dfYMin = adfGeoTransform[3] + adfGeoTransform[5] * nYSize;
     437                 :     
     438                 : /* -------------------------------------------------------------------- */
     439                 : /*      Create base file.                                               */
     440                 : /* -------------------------------------------------------------------- */
     441                 :     int cdfid, err;
     442                 : 
     443               5 :     err = nc_create (pszFilename, NC_CLOBBER,&cdfid);
     444               5 :     if( err != NC_NOERR )
     445                 :     {
     446                 :         CPLError( CE_Failure, CPLE_AppDefined, 
     447                 :                   "nc_create(%s): %s", 
     448               0 :                   pszFilename, nc_strerror( err ) );
     449               0 :         return NULL;
     450                 :     }
     451                 : 
     452                 : /* -------------------------------------------------------------------- */
     453                 : /*      Define the dimensions and so forth.                             */
     454                 : /* -------------------------------------------------------------------- */
     455                 :     int side_dim, xysize_dim, dims[1];
     456                 :     int x_range_id, y_range_id, z_range_id, inc_id, nm_id, z_id;
     457                 : 
     458               5 :     nc_def_dim(cdfid, "side", 2, &side_dim);
     459               5 :     nc_def_dim(cdfid, "xysize", (int) (nXSize * nYSize), &xysize_dim);
     460                 : 
     461               5 :     dims[0]   = side_dim;
     462               5 :     nc_def_var (cdfid, "x_range", NC_DOUBLE, 1, dims, &x_range_id);
     463               5 :     nc_def_var (cdfid, "y_range", NC_DOUBLE, 1, dims, &y_range_id);
     464               5 :     nc_def_var (cdfid, "z_range", NC_DOUBLE, 1, dims, &z_range_id);
     465               5 :     nc_def_var (cdfid, "spacing", NC_DOUBLE, 1, dims, &inc_id);
     466               5 :     nc_def_var (cdfid, "dimension", NC_LONG, 1, dims, &nm_id);
     467                 : 
     468               5 :     dims[0]   = xysize_dim;
     469               5 :     nc_def_var (cdfid, "z", nc_datatype, 1, dims, &z_id);
     470                 : 
     471                 : /* -------------------------------------------------------------------- */
     472                 : /*      Assign attributes.                                              */
     473                 : /* -------------------------------------------------------------------- */
     474               5 :     double default_scale = 1.0;
     475               5 :     double default_offset = 0.0;
     476               5 :     int default_node_offset = 1; // pixel is area
     477                 : 
     478               5 :     nc_put_att_text (cdfid, x_range_id, "units", 7, "meters");
     479               5 :     nc_put_att_text (cdfid, y_range_id, "units", 7, "meters");
     480               5 :     nc_put_att_text (cdfid, z_range_id, "units", 7, "meters");
     481                 : 
     482                 :     nc_put_att_double (cdfid, z_id, "scale_factor", NC_DOUBLE, 1, 
     483               5 :                        &default_scale );
     484                 :     nc_put_att_double (cdfid, z_id, "add_offset", NC_DOUBLE, 1, 
     485               5 :                        &default_offset );
     486                 : 
     487                 :     nc_put_att_int (cdfid, z_id, "node_offset", NC_LONG, 1, 
     488               5 :                     &default_node_offset );
     489               5 :     nc_put_att_text (cdfid, NC_GLOBAL, "title", 1, "");
     490               5 :     nc_put_att_text (cdfid, NC_GLOBAL, "source", 1, "");
     491                 :   
     492                 :     /* leave define mode */
     493               5 :     nc_enddef (cdfid);
     494                 : 
     495                 : /* -------------------------------------------------------------------- */
     496                 : /*      Get raster min/max.                                             */
     497                 : /* -------------------------------------------------------------------- */
     498                 :     double adfMinMax[2];
     499               5 :     GDALComputeRasterMinMax( (GDALRasterBandH) poBand, FALSE, adfMinMax );
     500                 :   
     501                 : /* -------------------------------------------------------------------- */
     502                 : /*      Set range variables.                                            */
     503                 : /* -------------------------------------------------------------------- */
     504                 :     size_t start[2], edge[2];
     505                 :     double dummy[2];
     506                 :     int nm[2];
     507                 :   
     508               5 :     start[0] = 0;
     509               5 :     edge[0] = 2;
     510               5 :     dummy[0] = adfGeoTransform[0];
     511               5 :     dummy[1] = dfXMax;
     512               5 :     nc_put_vara_double(cdfid, x_range_id, start, edge, dummy);
     513                 : 
     514               5 :     dummy[0] = dfYMin;
     515               5 :     dummy[1] = adfGeoTransform[3];
     516               5 :     nc_put_vara_double(cdfid, y_range_id, start, edge, dummy);
     517                 : 
     518               5 :     dummy[0] = adfGeoTransform[1];
     519               5 :     dummy[1] = -adfGeoTransform[5];
     520               5 :     nc_put_vara_double(cdfid, inc_id, start, edge, dummy);
     521                 : 
     522               5 :     nm[0] = nXSize;
     523               5 :     nm[1] = nYSize;
     524               5 :     nc_put_vara_int(cdfid, nm_id, start, edge, nm);
     525                 : 
     526               5 :     nc_put_vara_double(cdfid, z_range_id, start, edge, adfMinMax);
     527                 : 
     528                 : /* -------------------------------------------------------------------- */
     529                 : /*      Write out the image one scanline at a time.                     */
     530                 : /* -------------------------------------------------------------------- */
     531                 :     double *padfData;
     532                 :     int  iLine;
     533                 : 
     534               5 :     padfData = (double *) CPLMalloc( sizeof(double) * nXSize );
     535                 : 
     536               5 :     edge[0] = nXSize;
     537              65 :     for( iLine = 0; iLine < nYSize; iLine++ )
     538                 :     {
     539              60 :         start[0] = iLine * nXSize;
     540                 :         poBand->RasterIO( GF_Read, 0, iLine, nXSize, 1, 
     541              60 :                           padfData, nXSize, 1, GDT_Float64, 0, 0 );
     542              60 :         err = nc_put_vara_double( cdfid, z_id, start, edge, padfData );
     543              60 :         if( err != NC_NOERR )
     544                 :         {
     545                 :             CPLError( CE_Failure, CPLE_AppDefined, 
     546                 :                       "nc_put_vara_double(%s): %s", 
     547               0 :                       pszFilename, nc_strerror( err ) );
     548               0 :             nc_close (cdfid);
     549               0 :             return( NULL );
     550                 :         }
     551                 :     }
     552                 :     
     553               5 :     CPLFree( padfData );
     554                 : 
     555                 : /* -------------------------------------------------------------------- */
     556                 : /*      Close file, and reopen.                                         */
     557                 : /* -------------------------------------------------------------------- */
     558               5 :     nc_close (cdfid);
     559                 : 
     560                 : /* -------------------------------------------------------------------- */
     561                 : /*      Re-open dataset, and copy any auxilary pam information.         */
     562                 : /* -------------------------------------------------------------------- */
     563                 :     GDALPamDataset *poDS = (GDALPamDataset *) 
     564               5 :         GDALOpen( pszFilename, GA_ReadOnly );
     565                 : 
     566               5 :     if( poDS )
     567               5 :         poDS->CloneInfo( poSrcDS, GCIF_PAM_DEFAULT );
     568                 : 
     569               5 :     return poDS;
     570                 : }
     571                 : 
     572                 : /************************************************************************/
     573                 : /*                          GDALRegister_GMT()                          */
     574                 : /************************************************************************/
     575                 : 
     576             338 : void GDALRegister_GMT()
     577                 : 
     578                 : {
     579                 :     GDALDriver  *poDriver;
     580                 :     
     581             338 :     if (! GDAL_CHECK_VERSION("GMT driver"))
     582               0 :         return;
     583                 : 
     584             338 :     if( GDALGetDriverByName( "GMT" ) == NULL )
     585                 :     {
     586             336 :         poDriver = new GDALDriver();
     587                 :         
     588             336 :         poDriver->SetDescription( "GMT" );
     589                 :         poDriver->SetMetadataItem( GDAL_DMD_LONGNAME, 
     590             336 :                                    "GMT NetCDF Grid Format" );
     591                 :         poDriver->SetMetadataItem( GDAL_DMD_HELPTOPIC, 
     592             336 :                                    "frmt_various.html#GMT" );
     593             336 :         poDriver->SetMetadataItem( GDAL_DMD_EXTENSION, "nc" );
     594                 : 
     595                 :         poDriver->SetMetadataItem( GDAL_DMD_CREATIONDATATYPES, 
     596             336 :                                    "Int16 Int32 Float32 Float64" );
     597                 : 
     598             336 :         poDriver->pfnOpen = GMTDataset::Open;
     599             336 :         poDriver->pfnCreateCopy = GMTCreateCopy;
     600                 : 
     601             336 :         GetGDALDriverManager()->RegisterDriver( poDriver );
     602                 :     }
     603                 : }

Generated by: LCOV version 1.7