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