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
|