LCOV - code coverage report
Current view: directory - frmts/netcdf - netcdfdataset.h (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 2 2 100.0 %
Date: 2012-12-26 Functions: 2 2 100.0 %

       1                 : /******************************************************************************
       2                 :  * $Id: netcdfdataset.h 24588 2012-06-16 16:31:05Z rouault $
       3                 :  *
       4                 :  * Project:  netCDF read/write Driver
       5                 :  * Purpose:  GDAL bindings over netCDF library.
       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                 : #ifndef _NETCDFDATASET_H_INCLUDED_
      31                 : #define _NETCDFATASET_H_INCLUDED_
      32                 : 
      33                 : #include <float.h>
      34                 : #include "gdal_pam.h"
      35                 : #include "gdal_priv.h"
      36                 : #include "gdal_frmts.h"
      37                 : #include "cpl_string.h"
      38                 : #include "ogr_spatialref.h"
      39                 : #include "netcdf.h"
      40                 : 
      41                 : 
      42                 : /************************************************************************/
      43                 : /* ==================================================================== */
      44                 : /*           defines                                        */
      45                 : /* ==================================================================== */
      46                 : /************************************************************************/
      47                 : 
      48                 : /* -------------------------------------------------------------------- */
      49                 : /*      Creation and Configuration Options                              */
      50                 : /* -------------------------------------------------------------------- */
      51                 : 
      52                 : /* Creation options
      53                 : 
      54                 :    FORMAT=NC/NC2/NC4/NC4C (COMPRESS=DEFLATE sets FORMAT=NC4C)
      55                 :    COMPRESS=NONE/DEFLATE (default: NONE)
      56                 :    ZLEVEL=[1-9] (default: 1)
      57                 :    WRITE_BOTTOMUP=YES/NO (default: YES)
      58                 :    WRITE_GDAL_TAGS=YES/NO (default: YES)
      59                 :    WRITE_LONLAT=YES/NO/IF_NEEDED (default: YES for geographic, NO for projected)
      60                 :    TYPE_LONLAT=float/double (default: double for geographic, float for projected)
      61                 :    PIXELTYPE=DEFAULT/SIGNEDBYTE (use SIGNEDBYTE to get a signed Byte Band)
      62                 : */
      63                 : 
      64                 : /* Config Options
      65                 : 
      66                 :    GDAL_NETCDF_BOTTOMUP=YES/NO overrides bottom-up value on import
      67                 :    GDAL_NETCDF_CONVERT_LAT_180=YES/NO convert longitude values from ]180,360] to [-180,180]
      68                 : */
      69                 : 
      70                 : /* -------------------------------------------------------------------- */
      71                 : /*      Driver-specific defines                                         */
      72                 : /* -------------------------------------------------------------------- */
      73                 : 
      74                 : /* NETCDF driver defs */
      75                 : #define NCDF_MAX_STR_LEN     8192
      76                 : #define NCDF_CONVENTIONS_CF  "CF-1.5"
      77                 : #define NCDF_SPATIAL_REF     "spatial_ref"
      78                 : #define NCDF_GEOTRANSFORM    "GeoTransform"
      79                 : #define NCDF_DIMNAME_X       "x"
      80                 : #define NCDF_DIMNAME_Y       "y"
      81                 : #define NCDF_DIMNAME_LON     "lon"
      82                 : #define NCDF_DIMNAME_LAT     "lat"
      83                 : #define NCDF_LONLAT          "lon lat"
      84                 : #define NCDF_PI              3.14159265358979323846
      85                 : 
      86                 : /* netcdf file types, as in libcdi/cdo and compat w/netcdf.h */
      87                 : #define NCDF_FORMAT_NONE            0   /* Not a netCDF file */
      88                 : #define NCDF_FORMAT_NC              1   /* netCDF classic format */
      89                 : #define NCDF_FORMAT_NC2             2   /* netCDF version 2 (64-bit)  */
      90                 : #define NCDF_FORMAT_NC4             3   /* netCDF version 4 */
      91                 : #define NCDF_FORMAT_NC4C            4   /* netCDF version 4 (classic) */
      92                 : #define NCDF_FORMAT_UNKNOWN         10  /* Format not determined (yet) */
      93                 : /* HDF files (HDF5 or HDF4) not supported because of lack of support */
      94                 : /* in libnetcdf installation or conflict with other drivers */
      95                 : #define NCDF_FORMAT_HDF5            5   /* HDF4 file, not supported */
      96                 : #define NCDF_FORMAT_HDF4            6   /* HDF4 file, not supported */
      97                 : 
      98                 : /* compression parameters */
      99                 : #define NCDF_COMPRESS_NONE            0   
     100                 : /* TODO */
     101                 : /* http://www.unidata.ucar.edu/software/netcdf/docs/BestPractices.html#Packed%20Data%20Values */
     102                 : #define NCDF_COMPRESS_PACKED          1  
     103                 : #define NCDF_COMPRESS_DEFLATE         2   
     104                 : #define NCDF_DEFLATE_LEVEL            1  /* best time/size ratio */  
     105                 : #define NCDF_COMPRESS_SZIP            3  /* no support for writting */ 
     106                 : 
     107                 : /* helper for libnetcdf errors */
     108                 : #define NCDF_ERR(status) if ( status != NC_NOERR ){ \
     109                 : CPLError( CE_Failure,CPLE_AppDefined, \
     110                 : "netcdf error #%d : %s .\nat (%s,%s,%d)\n",status, nc_strerror(status), \
     111                 : __FILE__, __FUNCTION__, __LINE__ ); }
     112                 : 
     113                 : /* check for NC2 support in case it wasn't enabled at compile time */
     114                 : /* NC4 has to be detected at compile as it requires a special build of netcdf-4 */
     115                 : #ifndef NETCDF_HAS_NC2
     116                 : #ifdef NC_64BIT_OFFSET
     117                 : #define NETCDF_HAS_NC2 1
     118                 : #endif
     119                 : #endif
     120                 : 
     121                 : 
     122                 : /* -------------------------------------------------------------------- */
     123                 : /*       CF-1 or NUG (NetCDF User's Guide) defs                         */
     124                 : /* -------------------------------------------------------------------- */
     125                 : 
     126                 : /* CF: http://cf-pcmdi.llnl.gov/documents/cf-conventions/1.5/cf-conventions.html */
     127                 : /* NUG: http://www.unidata.ucar.edu/software/netcdf/docs/netcdf.html#Variables */
     128                 : #define CF_STD_NAME          "standard_name"
     129                 : #define CF_LNG_NAME          "long_name"
     130                 : #define CF_UNITS             "units"
     131                 : #define CF_ADD_OFFSET        "add_offset"
     132                 : #define CF_SCALE_FACTOR      "scale_factor"
     133                 : /* should be SRS_UL_METER but use meter now for compat with gtiff files */
     134                 : #define CF_UNITS_M           "metre"
     135                 : #define CF_UNITS_D           SRS_UA_DEGREE
     136                 : #define CF_PROJ_X_COORD      "projection_x_coordinate"
     137                 : #define CF_PROJ_Y_COORD      "projection_y_coordinate"
     138                 : #define CF_PROJ_X_COORD_LONG_NAME "x coordinate of projection"
     139                 : #define CF_PROJ_Y_COORD_LONG_NAME "y coordinate of projection"
     140                 : #define CF_GRD_MAPPING_NAME  "grid_mapping_name"
     141                 : #define CF_GRD_MAPPING       "grid_mapping"
     142                 : #define CF_COORDINATES       "coordinates"
     143                 : /* #define CF_AXIS            "axis" */
     144                 : /* #define CF_BOUNDS          "bounds" */
     145                 : /* #define CF_ORIG_UNITS      "original_units" */
     146                 : 
     147                 : 
     148                 : /* -------------------------------------------------------------------- */
     149                 : /*      CF-1 convention standard variables related to                   */
     150                 : /*      mapping & projection - see http://cf-pcmdi.llnl.gov/            */
     151                 : /* -------------------------------------------------------------------- */
     152                 : 
     153                 : /* projection types */
     154                 : #define CF_PT_AEA                    "albers_conical_equal_area"
     155                 : #define CF_PT_AE                     "azimuthal_equidistant"
     156                 : #define CF_PT_CEA                    "cylindrical_equal_area"
     157                 : #define CF_PT_LAEA                   "lambert_azimuthal_equal_area"
     158                 : #define CF_PT_LCEA                   "lambert_cylindrical_equal_area"
     159                 : #define CF_PT_LCC                    "lambert_conformal_conic"
     160                 : #define CF_PT_TM                     "transverse_mercator"
     161                 : #define CF_PT_LATITUDE_LONGITUDE     "latitude_longitude"
     162                 : #define CF_PT_MERCATOR               "mercator"
     163                 : #define CF_PT_ORTHOGRAPHIC           "orthographic"
     164                 : #define CF_PT_POLAR_STEREO           "polar_stereographic"
     165                 : #define CF_PT_STEREO                 "stereographic"
     166                 : 
     167                 : /* projection parameters */
     168                 : #define CF_PP_STD_PARALLEL           "standard_parallel"
     169                 : /* CF uses only "standard_parallel" */
     170                 : #define CF_PP_STD_PARALLEL_1         "standard_parallel_1"
     171                 : #define CF_PP_STD_PARALLEL_2         "standard_parallel_2"
     172                 : #define CF_PP_CENTRAL_MERIDIAN       "central_meridian"
     173                 : #define CF_PP_LONG_CENTRAL_MERIDIAN  "longitude_of_central_meridian"
     174                 : #define CF_PP_LON_PROJ_ORIGIN        "longitude_of_projection_origin"
     175                 : #define CF_PP_LAT_PROJ_ORIGIN        "latitude_of_projection_origin"
     176                 : /* #define PROJ_X_ORIGIN             "projection_x_coordinate_origin" */
     177                 : /* #define PROJ_Y_ORIGIN             "projection_y_coordinate_origin" */
     178                 : #define CF_PP_EARTH_SHAPE            "GRIB_earth_shape"
     179                 : #define CF_PP_EARTH_SHAPE_CODE       "GRIB_earth_shape_code"
     180                 : /* scale_factor is not CF, there are two possible translations  */
     181                 : /* for WKT scale_factor : SCALE_FACTOR_MERIDIAN and SCALE_FACTOR_ORIGIN */
     182                 : #define CF_PP_SCALE_FACTOR_MERIDIAN  "scale_factor_at_central_meridian"
     183                 : #define CF_PP_SCALE_FACTOR_ORIGIN    "scale_factor_at_projection_origin"
     184                 : #define CF_PP_VERT_LONG_FROM_POLE    "straight_vertical_longitude_from_pole"
     185                 : #define CF_PP_FALSE_EASTING          "false_easting"
     186                 : #define CF_PP_FALSE_NORTHING         "false_northing"
     187                 : #define CF_PP_EARTH_RADIUS           "earth_radius"
     188                 : #define CF_PP_EARTH_RADIUS_OLD       "spherical_earth_radius_meters"
     189                 : #define CF_PP_INVERSE_FLATTENING     "inverse_flattening"
     190                 : #define CF_PP_LONG_PRIME_MERIDIAN    "longitude_of_prime_meridian"
     191                 : #define CF_PP_SEMI_MAJOR_AXIS        "semi_major_axis"
     192                 : #define CF_PP_SEMI_MINOR_AXIS        "semi_minor_axis"
     193                 : #define CF_PP_VERT_PERSP             "vertical_perspective" /*not used yet */
     194                 : 
     195                 : 
     196                 : /* -------------------------------------------------------------------- */
     197                 : /*         CF-1 Coordinate Type Naming (Chapter 4.  Coordinate Types )  */
     198                 : /* -------------------------------------------------------------------- */
     199                 : static const char* papszCFLongitudeVarNames[] = { "lon", "longitude", NULL };
     200                 : static const char* papszCFLongitudeAttribNames[] = { "units", CF_STD_NAME, "axis", NULL };
     201                 : static const char* papszCFLongitudeAttribValues[] = { "degrees_east", "longitude", "X", NULL };
     202                 : static const char* papszCFLatitudeVarNames[] = { "lat", "latitude", NULL };
     203                 : static const char* papszCFLatitudeAttribNames[] = { "units", CF_STD_NAME, "axis", NULL };
     204                 : static const char* papszCFLatitudeAttribValues[] = { "degrees_north", "latitude", "Y", NULL };
     205                 :  
     206                 : static const char* papszCFProjectionXVarNames[] = { "x", "xc", NULL };
     207                 : static const char* papszCFProjectionXAttribNames[] = { CF_STD_NAME, NULL };
     208                 : static const char* papszCFProjectionXAttribValues[] = { CF_PROJ_X_COORD, NULL };
     209                 : static const char* papszCFProjectionYVarNames[] = { "y", "yc", NULL };
     210                 : static const char* papszCFProjectionYAttribNames[] = { CF_STD_NAME, NULL };
     211                 : static const char* papszCFProjectionYAttribValues[] = { CF_PROJ_Y_COORD, NULL };
     212                 : 
     213                 : static const char* papszCFVerticalAttribNames[] = { "axis", "positive", "positive", NULL };
     214                 : static const char* papszCFVerticalAttribValues[] = { "Z", "up", "down", NULL };
     215                 : static const char* papszCFVerticalUnitsValues[] = { 
     216                 :     /* units of pressure */
     217                 :     "bar", "bars", "millibar", "millibars", "decibar", "decibars", 
     218                 :     "atmosphere", "atmospheres", "atm", "pascal", "pascals", "Pa", "hPa",
     219                 :     /* units of length */
     220                 :     "meter", "meters", "m", "kilometer", "kilometers", "km", 
     221                 :     /* dimensionless vertical coordinates */
     222                 :     "level", "layer", "sigma_level",
     223                 :     NULL };
     224                 : /* dimensionless vertical coordinates */
     225                 : static const char* papszCFVerticalStandardNameValues[] = { 
     226                 :     "atmosphere_ln_pressure_coordinate", "atmosphere_sigma_coordinate",
     227                 :     "atmosphere_hybrid_sigma_pressure_coordinate", 
     228                 :     "atmosphere_hybrid_height_coordinate",
     229                 :     "atmosphere_sleve_coordinate", "ocean_sigma_coordinate",
     230                 :     "ocean_s_coordinate", "ocean_sigma_z_coordinate",
     231                 :     "ocean_double_sigma_coordinate", "atmosphere_ln_pressure_coordinate",
     232                 :     "atmosphere_sigma_coordinate", 
     233                 :     "atmosphere_hybrid_sigma_pressure_coordinate",
     234                 :     "atmosphere_hybrid_height_coordinate",
     235                 :     "atmosphere_sleve_coordinate", "ocean_sigma_coordinate",
     236                 :     "ocean_s_coordinate", "ocean_sigma_z_coordinate",
     237                 :     "ocean_double_sigma_coordinate", NULL };
     238                 : 
     239                 : static const char* papszCFTimeAttribNames[] = { "axis", NULL };
     240                 : static const char* papszCFTimeAttribValues[] = { "T", NULL };
     241                 : static const char* papszCFTimeUnitsValues[] = { 
     242                 :     "days since", "day since", "d since", 
     243                 :     "hours since", "hour since", "h since", "hr since", 
     244                 :     "minutes since", "minute since", "min since", 
     245                 :     "seconds since", "second since", "sec since", "s since", 
     246                 :     NULL };
     247                 : 
     248                 : 
     249                 : /* -------------------------------------------------------------------- */
     250                 : /*         CF-1 to GDAL mappings                                        */
     251                 : /* -------------------------------------------------------------------- */
     252                 : 
     253                 : /* Following are a series of mappings from CF-1 convention parameters
     254                 :  * for each projection, to the equivalent in OGC WKT used internally by GDAL.
     255                 :  * See: http://cf-pcmdi.llnl.gov/documents/cf-conventions/1.5/apf.html
     256                 :  */
     257                 : 
     258                 : /* A struct allowing us to map between GDAL(OGC WKT) and CF-1 attributes */
     259                 : typedef struct {
     260                 :     const char *CF_ATT;
     261                 :     const char *WKT_ATT; 
     262                 :     // TODO: mappings may need default values, like scale factor?
     263                 :     //double defval;
     264                 : } oNetcdfSRS_PP;
     265                 : 
     266                 : // default mappings, for the generic case
     267                 : /* These 'generic' mappings are based on what was previously in the  
     268                 :    poNetCDFSRS struct. They will be used as a fallback in case none 
     269                 :    of the others match (ie you are exporting a projection that has 
     270                 :    no CF-1 equivalent). 
     271                 :    They are not used for known CF-1 projections since there is not a 
     272                 :    unique 2-way projection-independent 
     273                 :    mapping between OGC WKT params and CF-1 ones: it varies per-projection. 
     274                 : */ 
     275                 : 
     276                 : static const oNetcdfSRS_PP poGenericMappings[] = {
     277                 :     /* scale_factor is handled as a special case, write 2 values */
     278                 :     {CF_PP_STD_PARALLEL_1, SRS_PP_STANDARD_PARALLEL_1 }, 
     279                 :     {CF_PP_STD_PARALLEL_2, SRS_PP_STANDARD_PARALLEL_2 }, 
     280                 :     {CF_PP_LONG_CENTRAL_MERIDIAN, SRS_PP_CENTRAL_MERIDIAN }, 
     281                 :     {CF_PP_LONG_CENTRAL_MERIDIAN, SRS_PP_LONGITUDE_OF_CENTER }, 
     282                 :     {CF_PP_LON_PROJ_ORIGIN, SRS_PP_LONGITUDE_OF_ORIGIN },  
     283                 :     //Multiple mappings to LAT_PROJ_ORIGIN 
     284                 :     {CF_PP_LAT_PROJ_ORIGIN, SRS_PP_LATITUDE_OF_ORIGIN },  
     285                 :     {CF_PP_LAT_PROJ_ORIGIN, SRS_PP_LATITUDE_OF_CENTER },  
     286                 :     {CF_PP_FALSE_EASTING, SRS_PP_FALSE_EASTING },   
     287                 :     {CF_PP_FALSE_NORTHING, SRS_PP_FALSE_NORTHING },        
     288                 :     {NULL, NULL },
     289                 : };
     290                 : 
     291                 : // Albers equal area 
     292                 : //
     293                 : // grid_mapping_name = albers_conical_equal_area
     294                 : // WKT: Albers_Conic_Equal_Area
     295                 : // ESPG:9822 
     296                 : //
     297                 : // Map parameters:
     298                 : //
     299                 : //    * standard_parallel - There may be 1 or 2 values.
     300                 : //    * longitude_of_central_meridian
     301                 : //    * latitude_of_projection_origin
     302                 : //    * false_easting
     303                 : //    * false_northing
     304                 : //
     305                 : static const oNetcdfSRS_PP poAEAMappings[] = {
     306                 :     {CF_PP_STD_PARALLEL_1, SRS_PP_STANDARD_PARALLEL_1},
     307                 :     {CF_PP_STD_PARALLEL_2, SRS_PP_STANDARD_PARALLEL_2},
     308                 :     {CF_PP_LAT_PROJ_ORIGIN, SRS_PP_LATITUDE_OF_CENTER},
     309                 :     {CF_PP_LONG_CENTRAL_MERIDIAN, SRS_PP_LONGITUDE_OF_CENTER},
     310                 :     {CF_PP_FALSE_EASTING, SRS_PP_FALSE_EASTING },  
     311                 :     {CF_PP_FALSE_NORTHING, SRS_PP_FALSE_NORTHING },
     312                 :     {NULL, NULL}
     313                 :  };
     314                 : 
     315                 : // Azimuthal equidistant
     316                 : //
     317                 : // grid_mapping_name = azimuthal_equidistant
     318                 : // WKT: Azimuthal_Equidistant
     319                 : //
     320                 : // Map parameters:
     321                 : //
     322                 : //    * longitude_of_projection_origin
     323                 : //    * latitude_of_projection_origin
     324                 : //    * false_easting
     325                 : //    * false_northing
     326                 : //
     327                 : static const oNetcdfSRS_PP poAEMappings[] = {
     328                 :     {CF_PP_LAT_PROJ_ORIGIN, SRS_PP_LATITUDE_OF_CENTER},
     329                 :     {CF_PP_LON_PROJ_ORIGIN, SRS_PP_LONGITUDE_OF_CENTER},
     330                 :     {CF_PP_FALSE_EASTING, SRS_PP_FALSE_EASTING },  
     331                 :     {CF_PP_FALSE_NORTHING, SRS_PP_FALSE_NORTHING },
     332                 :     {NULL, NULL}
     333                 :  };
     334                 : 
     335                 : // Lambert azimuthal equal area
     336                 : //
     337                 : // grid_mapping_name = lambert_azimuthal_equal_area
     338                 : // WKT: Lambert_Azimuthal_Equal_Area
     339                 : //
     340                 : // Map parameters:
     341                 : //
     342                 : //    * longitude_of_projection_origin
     343                 : //    * latitude_of_projection_origin
     344                 : //    * false_easting
     345                 : //    * false_northing
     346                 : //
     347                 : static const oNetcdfSRS_PP poLAEAMappings[] = {
     348                 :     {CF_PP_LAT_PROJ_ORIGIN, SRS_PP_LATITUDE_OF_CENTER},
     349                 :     {CF_PP_LON_PROJ_ORIGIN, SRS_PP_LONGITUDE_OF_CENTER},
     350                 :     {CF_PP_FALSE_EASTING, SRS_PP_FALSE_EASTING },  
     351                 :     {CF_PP_FALSE_NORTHING, SRS_PP_FALSE_NORTHING },
     352                 :     {NULL, NULL}
     353                 :  };
     354                 : 
     355                 : // Lambert conformal
     356                 : //
     357                 : // grid_mapping_name = lambert_conformal_conic
     358                 : // WKT: Lambert_Conformal_Conic_1SP / Lambert_Conformal_Conic_2SP
     359                 : //
     360                 : // Map parameters:
     361                 : //
     362                 : //    * standard_parallel - There may be 1 or 2 values.
     363                 : //    * longitude_of_central_meridian
     364                 : //    * latitude_of_projection_origin
     365                 : //    * false_easting
     366                 : //    * false_northing
     367                 : //
     368                 : // See http://www.remotesensing.org/geotiff/proj_list/lambert_conic_conformal_1sp.html 
     369                 : 
     370                 : // Lambert conformal conic - 1SP
     371                 : /* See bug # 3324
     372                 :    It seems that the missing scale factor can be computed from standard_parallel1 and latitude_of_projection_origin.
     373                 :    If both are equal (the common case) then scale factor=1, else use Snyder eq. 15-4.
     374                 :    We save in the WKT standard_parallel1 for export to CF, but do not export scale factor.
     375                 :    If a WKT has a scale factor != 1 and no standard_parallel1 then export is not CF, but we output scale factor for compat.
     376                 :      is there a formula for that?
     377                 : */
     378                 : static const oNetcdfSRS_PP poLCC1SPMappings[] = {
     379                 :     {CF_PP_STD_PARALLEL_1, SRS_PP_STANDARD_PARALLEL_1},
     380                 :     {CF_PP_LAT_PROJ_ORIGIN, SRS_PP_LATITUDE_OF_ORIGIN},
     381                 :     {CF_PP_LONG_CENTRAL_MERIDIAN, SRS_PP_CENTRAL_MERIDIAN},
     382                 :     {CF_PP_SCALE_FACTOR_ORIGIN, SRS_PP_SCALE_FACTOR}, /* special case */
     383                 :     {CF_PP_FALSE_EASTING, SRS_PP_FALSE_EASTING },  
     384                 :     {CF_PP_FALSE_NORTHING, SRS_PP_FALSE_NORTHING },
     385                 :     {NULL, NULL}
     386                 :  };
     387                 : 
     388                 : // Lambert conformal conic - 2SP
     389                 : static const oNetcdfSRS_PP poLCC2SPMappings[] = {
     390                 :     {CF_PP_STD_PARALLEL_1, SRS_PP_STANDARD_PARALLEL_1},
     391                 :     {CF_PP_STD_PARALLEL_2, SRS_PP_STANDARD_PARALLEL_2},
     392                 :     {CF_PP_LAT_PROJ_ORIGIN, SRS_PP_LATITUDE_OF_ORIGIN},
     393                 :     {CF_PP_LONG_CENTRAL_MERIDIAN, SRS_PP_CENTRAL_MERIDIAN},
     394                 :     {CF_PP_FALSE_EASTING, SRS_PP_FALSE_EASTING },  
     395                 :     {CF_PP_FALSE_NORTHING, SRS_PP_FALSE_NORTHING },
     396                 :     {NULL, NULL}
     397                 :  };
     398                 : 
     399                 : // Lambert cylindrical equal area
     400                 : //
     401                 : // grid_mapping_name = lambert_cylindrical_equal_area
     402                 : // WKT: Cylindrical_Equal_Area
     403                 : // EPSG:9834 (Spherical) and EPSG:9835 
     404                 : //
     405                 : // Map parameters:
     406                 : //
     407                 : //    * longitude_of_central_meridian
     408                 : //    * either standard_parallel or scale_factor_at_projection_origin
     409                 : //    * false_easting
     410                 : //    * false_northing
     411                 : //
     412                 : // NB: CF-1 specifies a 'scale_factor_at_projection' alternative  
     413                 : //  to std_parallel ... but no reference to this in EPSG/remotesensing.org 
     414                 : //  ignore for now. 
     415                 : //
     416                 : static const oNetcdfSRS_PP poLCEAMappings[] = {
     417                 :     {CF_PP_STD_PARALLEL_1, SRS_PP_STANDARD_PARALLEL_1},
     418                 :     {CF_PP_LONG_CENTRAL_MERIDIAN, SRS_PP_CENTRAL_MERIDIAN},
     419                 :     {CF_PP_FALSE_EASTING, SRS_PP_FALSE_EASTING },  
     420                 :     {CF_PP_FALSE_NORTHING, SRS_PP_FALSE_NORTHING },
     421                 :     {NULL, NULL}
     422                 :  };
     423                 : 
     424                 : // Latitude-Longitude
     425                 : //
     426                 : // grid_mapping_name = latitude_longitude
     427                 : //
     428                 : // Map parameters:
     429                 : //
     430                 : //    * None
     431                 : //
     432                 : // NB: handled as a special case - !isProjected()
     433                 : 
     434                 : 
     435                 : // Mercator
     436                 : //
     437                 : // grid_mapping_name = mercator
     438                 : // WKT: Mercator_1SP / Mercator_2SP
     439                 : //
     440                 : // Map parameters:
     441                 : //
     442                 : //    * longitude_of_projection_origin
     443                 : //    * either standard_parallel or scale_factor_at_projection_origin
     444                 : //    * false_easting
     445                 : //    * false_northing
     446                 : 
     447                 : // Mercator 1 Standard Parallel (EPSG:9804) 
     448                 : static const oNetcdfSRS_PP poM1SPMappings[] = {
     449                 :     {CF_PP_LON_PROJ_ORIGIN, SRS_PP_CENTRAL_MERIDIAN},
     450                 :     //LAT_PROJ_ORIGIN is always equator (0) in CF-1 
     451                 :     {CF_PP_SCALE_FACTOR_ORIGIN, SRS_PP_SCALE_FACTOR},
     452                 :     {CF_PP_FALSE_EASTING, SRS_PP_FALSE_EASTING },  
     453                 :     {CF_PP_FALSE_NORTHING, SRS_PP_FALSE_NORTHING },
     454                 :     {NULL, NULL}
     455                 :  };
     456                 : 
     457                 : // Mercator 2 Standard Parallel
     458                 : static const oNetcdfSRS_PP poM2SPMappings[] = {
     459                 :     {CF_PP_LON_PROJ_ORIGIN, SRS_PP_CENTRAL_MERIDIAN},
     460                 :     {CF_PP_STD_PARALLEL_1, SRS_PP_STANDARD_PARALLEL_1},
     461                 :     //From best understanding of this projection, only  
     462                 :   // actually specify one SP - it is the same N/S of equator. 
     463                 :     //{CF_PP_STD_PARALLEL_2, SRS_PP_LATITUDE_OF_ORIGIN}, 
     464                 :     {CF_PP_FALSE_EASTING, SRS_PP_FALSE_EASTING },  
     465                 :     {CF_PP_FALSE_NORTHING, SRS_PP_FALSE_NORTHING },
     466                 :     {NULL, NULL}
     467                 :  };
     468                 : 
     469                 : // Orthographic
     470                 : // grid_mapping_name = orthographic
     471                 : // WKT: Orthographic
     472                 : //
     473                 : // Map parameters:
     474                 : //
     475                 : //    * longitude_of_projection_origin
     476                 : //    * latitude_of_projection_origin
     477                 : //    * false_easting
     478                 : //    * false_northing
     479                 : //
     480                 : static const oNetcdfSRS_PP poOrthoMappings[] = {
     481                 :     {CF_PP_LAT_PROJ_ORIGIN, SRS_PP_LATITUDE_OF_ORIGIN},
     482                 :     {CF_PP_LON_PROJ_ORIGIN, SRS_PP_CENTRAL_MERIDIAN},
     483                 :     {CF_PP_FALSE_EASTING, SRS_PP_FALSE_EASTING },  
     484                 :     {CF_PP_FALSE_NORTHING, SRS_PP_FALSE_NORTHING },
     485                 :     {NULL, NULL}
     486                 :  }; 
     487                 : 
     488                 : // Polar stereographic
     489                 : //
     490                 : // grid_mapping_name = polar_stereographic
     491                 : // WKT: Polar_Stereographic
     492                 : //
     493                 : // Map parameters:
     494                 : //
     495                 : //    * straight_vertical_longitude_from_pole
     496                 : //    * latitude_of_projection_origin - Either +90. or -90.
     497                 : //    * Either standard_parallel or scale_factor_at_projection_origin
     498                 : //    * false_easting
     499                 : //    * false_northing
     500                 : 
     501                 : /* 
     502                 :    (http://www.remotesensing.org/geotiff/proj_list/polar_stereographic.html)
     503                 : 
     504                 :    Note: Projection parameters for this projection are quite different in CF-1 from
     505                 :      OGC WKT/GeoTiff (for the latter, see above).
     506                 :    From our best understanding, this projection requires more than a straight mapping:
     507                 :      - As defined below, 'latitude_of_origin' (WKT) -> 'standard_parallel' (CF-1)
     508                 :        and 'central_meridian' (WKT) -> 'straight_vertical_longitude_from_pole' (CF-1)
     509                 :      - Then the 'latitude_of_projection_origin' in CF-1 must be set to either +90 or -90,
     510                 :        depending on the sign of 'latitude_of_origin' in WKT.
     511                 :    CF allows the use of standard_parallel (lat_ts in proj4) OR scale_factor (k0 in proj4).
     512                 :    This is analogous to the B and A variants (resp.) in EPSG guidelines.
     513                 :    When importing a CF file with scale_factor, we compute standard_parallel using 
     514                 :      Snyder eq. 22-7 with k=1 and lat=standard_parallel.
     515                 :    Currently OGR does NOT relate the scale factor with the standard parallel, so we 
     516                 :    use the default. It seems that proj4 uses lat_ts (standard_parallel) and not k0.
     517                 : */
     518                 : static const oNetcdfSRS_PP poPSmappings[] = {
     519                 :     {CF_PP_STD_PARALLEL_1, SRS_PP_LATITUDE_OF_ORIGIN},
     520                 :     /* {CF_PP_SCALE_FACTOR_ORIGIN, SRS_PP_SCALE_FACTOR},   */
     521                 :     {CF_PP_VERT_LONG_FROM_POLE, SRS_PP_CENTRAL_MERIDIAN},
     522                 :     {CF_PP_FALSE_EASTING, SRS_PP_FALSE_EASTING },  
     523                 :     {CF_PP_FALSE_NORTHING, SRS_PP_FALSE_NORTHING },
     524                 :     {NULL, NULL}
     525                 : };
     526                 : 
     527                 : // Rotated Pole
     528                 : //
     529                 : // grid_mapping_name = rotated_latitude_longitude
     530                 : // WKT: N/A
     531                 : //
     532                 : // Map parameters:
     533                 : //
     534                 : //    * grid_north_pole_latitude
     535                 : //    * grid_north_pole_longitude
     536                 : //    * north_pole_grid_longitude - This parameter is optional (default is 0.).
     537                 : 
     538                 : /* TODO: No GDAL equivalent of rotated pole? Doesn't seem to have an EPSG
     539                 :    code or WKT ... so unless some advanced proj4 features can be used 
     540                 :    seems to rule out.
     541                 :    see GDAL bug #4285 for a possible fix or workaround
     542                 : */
     543                 : 
     544                 : // Stereographic
     545                 : //
     546                 : // grid_mapping_name = stereographic
     547                 : // WKT: Stereographic (and/or Oblique_Stereographic??)
     548                 : //
     549                 : // Map parameters:
     550                 : //
     551                 : //    * longitude_of_projection_origin
     552                 : //    * latitude_of_projection_origin
     553                 : //    * scale_factor_at_projection_origin
     554                 : //    * false_easting
     555                 : //    * false_northing
     556                 : //
     557                 : // NB: see bug#4267 Stereographic vs. Oblique_Stereographic
     558                 : //
     559                 : static const oNetcdfSRS_PP poStMappings[] = {
     560                 :     {CF_PP_LAT_PROJ_ORIGIN, SRS_PP_LATITUDE_OF_ORIGIN},
     561                 :     {CF_PP_LON_PROJ_ORIGIN, SRS_PP_CENTRAL_MERIDIAN},
     562                 :     {CF_PP_SCALE_FACTOR_ORIGIN, SRS_PP_SCALE_FACTOR},  
     563                 :     {CF_PP_FALSE_EASTING, SRS_PP_FALSE_EASTING },  
     564                 :     {CF_PP_FALSE_NORTHING, SRS_PP_FALSE_NORTHING },
     565                 :     {NULL, NULL}
     566                 :   };
     567                 : 
     568                 : // Transverse Mercator
     569                 : //
     570                 : // grid_mapping_name = transverse_mercator
     571                 : // WKT: Transverse_Mercator
     572                 : //
     573                 : // Map parameters:
     574                 : //
     575                 : //    * scale_factor_at_central_meridian
     576                 : //    * longitude_of_central_meridian
     577                 : //    * latitude_of_projection_origin
     578                 : //    * false_easting
     579                 : //    * false_northing
     580                 : //
     581                 : static const oNetcdfSRS_PP poTMMappings[] = {
     582                 :     {CF_PP_SCALE_FACTOR_MERIDIAN, SRS_PP_SCALE_FACTOR},  
     583                 :     {CF_PP_LONG_CENTRAL_MERIDIAN, SRS_PP_CENTRAL_MERIDIAN},
     584                 :     {CF_PP_LAT_PROJ_ORIGIN, SRS_PP_LATITUDE_OF_ORIGIN},
     585                 :     {CF_PP_FALSE_EASTING, SRS_PP_FALSE_EASTING },  
     586                 :     {CF_PP_FALSE_NORTHING, SRS_PP_FALSE_NORTHING },
     587                 :     {NULL, NULL}
     588                 :   };
     589                 : 
     590                 : // Vertical perspective
     591                 : //
     592                 : // grid_mapping_name = vertical_perspective
     593                 : // WKT: ???
     594                 : //
     595                 : // Map parameters:
     596                 : //
     597                 : //    * latitude_of_projection_origin
     598                 : //    * longitude_of_projection_origin
     599                 : //    * perspective_point_height
     600                 : //    * false_easting
     601                 : //    * false_northing
     602                 : //
     603                 : // TODO: see how to map this to OGR
     604                 : 
     605                 : 
     606                 : /* Mappings for various projections, including netcdf and GDAL projection names 
     607                 :    and corresponding oNetcdfSRS_PP mapping struct. 
     608                 :    A NULL mappings value means that the projection is not included in the CF
     609                 :    standard and the generic mapping (poGenericMappings) will be used. */
     610                 : typedef struct {
     611                 :     const char *CF_SRS;
     612                 :     const char *WKT_SRS; 
     613                 :     const oNetcdfSRS_PP* mappings;
     614                 : } oNetcdfSRS_PT;
     615                 : 
     616                 : static const oNetcdfSRS_PT poNetcdfSRS_PT[] = {
     617                 :     {CF_PT_AEA, SRS_PT_ALBERS_CONIC_EQUAL_AREA, poAEAMappings },
     618                 :     {CF_PT_AE, SRS_PT_AZIMUTHAL_EQUIDISTANT, poAEMappings },
     619                 :     {"cassini_soldner", SRS_PT_CASSINI_SOLDNER, NULL },
     620                 :     {CF_PT_LCEA, SRS_PT_CYLINDRICAL_EQUAL_AREA, poLCEAMappings },
     621                 :     {"eckert_iv", SRS_PT_ECKERT_IV, NULL },      
     622                 :     {"eckert_vi", SRS_PT_ECKERT_VI, NULL },  
     623                 :     {"equidistant_conic", SRS_PT_EQUIDISTANT_CONIC, NULL },
     624                 :     {"equirectangular", SRS_PT_EQUIRECTANGULAR, NULL },
     625                 :     {"gall_stereographic", SRS_PT_GALL_STEREOGRAPHIC, NULL },
     626                 :     {"geostationary_satellite", SRS_PT_GEOSTATIONARY_SATELLITE, NULL },
     627                 :     {"goode_homolosine", SRS_PT_GOODE_HOMOLOSINE, NULL },
     628                 :     {"gnomonic", SRS_PT_GNOMONIC, NULL },
     629                 :     {"hotine_oblique_mercator", SRS_PT_HOTINE_OBLIQUE_MERCATOR, NULL },
     630                 :     {"hotine_oblique_mercator_2P", 
     631                 :      SRS_PT_HOTINE_OBLIQUE_MERCATOR_TWO_POINT_NATURAL_ORIGIN, NULL },
     632                 :     {"laborde_oblique_mercator", SRS_PT_LABORDE_OBLIQUE_MERCATOR, NULL },
     633                 :     {CF_PT_LCC, SRS_PT_LAMBERT_CONFORMAL_CONIC_1SP, poLCC1SPMappings },
     634                 :     {CF_PT_LCC, SRS_PT_LAMBERT_CONFORMAL_CONIC_2SP, poLCC2SPMappings },
     635                 :     {CF_PT_LAEA, SRS_PT_LAMBERT_AZIMUTHAL_EQUAL_AREA, poLAEAMappings },
     636                 :     {CF_PT_MERCATOR, SRS_PT_MERCATOR_1SP, poM1SPMappings },
     637                 :     {CF_PT_MERCATOR, SRS_PT_MERCATOR_2SP, poM2SPMappings },
     638                 :     {"miller_cylindrical", SRS_PT_MILLER_CYLINDRICAL, NULL },
     639                 :     {"mollweide", SRS_PT_MOLLWEIDE, NULL },
     640                 :     {"new_zealand_map_grid", SRS_PT_NEW_ZEALAND_MAP_GRID, NULL },
     641                 :     /* for now map to STEREO, see bug #4267 */
     642                 :     {"oblique_stereographic", SRS_PT_OBLIQUE_STEREOGRAPHIC, NULL }, 
     643                 :     /* {STEREO, SRS_PT_OBLIQUE_STEREOGRAPHIC, poStMappings },  */
     644                 :     {CF_PT_ORTHOGRAPHIC, SRS_PT_ORTHOGRAPHIC, poOrthoMappings },
     645                 :     {CF_PT_POLAR_STEREO, SRS_PT_POLAR_STEREOGRAPHIC, poPSmappings },
     646                 :     {"polyconic", SRS_PT_POLYCONIC, NULL },
     647                 :     {"robinson", SRS_PT_ROBINSON, NULL }, 
     648                 :     {"sinusoidal", SRS_PT_SINUSOIDAL, NULL },  
     649                 :     {CF_PT_STEREO, SRS_PT_STEREOGRAPHIC, poStMappings },
     650                 :     {"swiss_oblique_cylindrical", SRS_PT_SWISS_OBLIQUE_CYLINDRICAL, NULL },
     651                 :     {CF_PT_TM, SRS_PT_TRANSVERSE_MERCATOR, poTMMappings },
     652                 :     {"TM_south_oriented", SRS_PT_TRANSVERSE_MERCATOR_SOUTH_ORIENTED, NULL },
     653                 :     {NULL, NULL, NULL },
     654                 : };
     655                 : 
     656                 : /************************************************************************/
     657                 : /* ==================================================================== */
     658                 : /*           netCDFDataset                                    */
     659                 : /* ==================================================================== */
     660                 : /************************************************************************/
     661                 : 
     662                 : class netCDFRasterBand;
     663                 : 
     664                 : class netCDFDataset : public GDALPamDataset
     665                 : {
     666                 :     friend class netCDFRasterBand; //TMP
     667                 : 
     668                 :     /* basic dataset vars */
     669                 :     CPLString     osFilename;
     670                 :     int           cdfid;
     671                 :     char          **papszSubDatasets;
     672                 :     char          **papszMetadata;
     673                 :     CPLStringList papszDimName;
     674                 :     bool          bBottomUp;
     675                 :     int           nFormat;
     676                 :     int           bIsGdalFile; /* was this file created by GDAL? */
     677                 :     int           bIsGdalCfFile; /* was this file created by the (new) CF-compliant driver? */
     678                 :     char         *pszCFProjection;
     679                 :     char         *pszCFCoordinates;
     680                 : 
     681                 :     /* projection/GT */
     682                 :     double       adfGeoTransform[6];
     683                 :     char         *pszProjection;
     684                 :     int          nXDimID;
     685                 :     int          nYDimID;
     686                 :     int          bIsProjected;
     687                 :     int          bIsGeographic;
     688                 : 
     689                 :     /* state vars */
     690                 :     int          status;
     691                 :     int          bDefineMode;
     692                 :     int          bSetProjection; 
     693                 :     int          bSetGeoTransform;
     694                 :     int          bAddedProjectionVars;
     695                 :     int          bAddedGridMappingRef;
     696                 : 
     697                 :     /* create vars */
     698                 :     char         **papszCreationOptions;
     699                 :     int          nCompress;
     700                 :     int          nZLevel;
     701                 :     int          nCreateMode;
     702                 :     int          bSignedData;
     703                 : 
     704                 :     double       rint( double );
     705                 : 
     706                 :     double       FetchCopyParm( const char *pszGridMappingValue, 
     707                 :                                 const char *pszParm, double dfDefault );
     708                 : 
     709                 :     char **      FetchStandardParallels( const char *pszGridMappingValue );
     710                 : 
     711                 :     void ProcessCreationOptions( );
     712                 :     int DefVarDeflate( int nVarId, int bChunking=TRUE );
     713                 :     CPLErr AddProjectionVars( GDALProgressFunc pfnProgress=GDALDummyProgress, 
     714                 :                               void * pProgressData=NULL );
     715                 :     void AddGridMappingRef(); 
     716                 : 
     717              80 :     int GetDefineMode() { return bDefineMode; }
     718                 :     int SetDefineMode( int bNewDefineMode );
     719                 : 
     720                 :     CPLErr      ReadAttributes( int, int );
     721                 : 
     722                 :     void  CreateSubDatasetList( );
     723                 : 
     724                 :     void  SetProjectionFromVar( int );
     725                 : 
     726                 :     int ProcessCFGeolocation( int );
     727                 :     CPLErr Set1DGeolocation( int nVarId, const char *szDimName );
     728                 :     double * Get1DGeolocation( const char *szDimName, int &nVarLen );
     729                 : 
     730                 :   protected:
     731                 : 
     732                 :     CPLXMLNode *SerializeToXML( const char *pszVRTPath );
     733                 : 
     734                 :   public:
     735                 : 
     736                 :     netCDFDataset( );
     737                 :     ~netCDFDataset( );
     738                 :     
     739                 :     /* Projection/GT */
     740                 :     CPLErr  GetGeoTransform( double * );    
     741                 :     CPLErr  SetGeoTransform (double *);
     742                 :     const char * GetProjectionRef();
     743                 :     CPLErr  SetProjection (const char *);
     744                 : 
     745                 :     char ** GetMetadata( const char * );
     746                 : 
     747             420 :     int GetCDFID() { return cdfid; }
     748                 : 
     749                 :     /* static functions */
     750                 :     static int Identify( GDALOpenInfo * );
     751                 :     static int IdentifyFormat( GDALOpenInfo *, bool );
     752                 :     static GDALDataset *Open( GDALOpenInfo * );
     753                 : 
     754                 :     static netCDFDataset *CreateLL( const char * pszFilename,
     755                 :                                     int nXSize, int nYSize, int nBands,
     756                 :                                     char ** papszOptions );
     757                 :     static GDALDataset *Create( const char * pszFilename,
     758                 :                                 int nXSize, int nYSize, int nBands,
     759                 :                                 GDALDataType eType,
     760                 :                                 char ** papszOptions );
     761                 :     static GDALDataset* CreateCopy( const char * pszFilename, GDALDataset *poSrcDS, 
     762                 :                                     int bStrict, char ** papszOptions, 
     763                 :                                     GDALProgressFunc pfnProgress, void * pProgressData );
     764                 :         
     765                 : };
     766                 : 
     767                 : #endif

Generated by: LCOV version 1.7