When the coordinate variables for a horizontal grid are not
longitude and latitude, it is required that the true latitude and
longitude coordinates be supplied via the coordinates
attribute. If in addition it is desired to describe the mapping between
the given coordinate variables and the true latitude and longitude
coordinates, the attribute grid_mapping
may be used to
supply this description. This attribute is attached to data variables so
that variables with different mappings may be present in a single file.
The attribute takes a string value which is the name of another variable
in the file that provides the description of the mapping via a collection
of attached attributes. This variable is called a grid mapping
variable and is of arbitrary type since it contains no data.
Its purpose is to act as a container for the attributes that define the
mapping. The one attribute that all grid mapping variables must have is
grid_mapping_name
which takes a string value that
contains the mapping's name. The other attributes that define a specific
mapping depend on the value of grid_mapping_name
. The
valid values of grid_mapping_name
along with the
attributes that provide specific map parameter values are described in
Appendix F, Grid Mappings.
When the coordinate variables for a
horizontal grid are longitude and latitude, a grid mapping variable with
grid_mapping_name
of
latitude_longitude
may be used to specify the ellipsoid
and prime meridian.
In order to make use of a grid mapping to directly calculate
latitude and longitude values it is necessary to associate the coordinate
variables with the independent variables of the mapping. This is done by
assigning a standard_name
to the coordinate variable.
The appropriate values of the standard_name
depend on
the grid mapping and are given in Appendix F, Grid Mappings.
Example 5.6. Rotated pole grid
dimensions: rlon = 128 ; rlat = 64 ; lev = 18 ; variables: float T(lev,rlat,rlon) ; T:long_name = "temperature" ; T:units = "K" ; T:coordinates = "lon lat" ; T:grid_mapping = "rotated_pole" ; char rotated_pole rotated_pole:grid_mapping_name = "rotated_latitude_longitude" ; rotated_pole:grid_north_pole_latitude = 32.5 ; rotated_pole:grid_north_pole_longitude = 170. ; float rlon(rlon) ; rlon:long_name = "longitude in rotated pole grid" ; rlon:units = "degrees" ; rlon:standard_name = "grid_longitude"; float rlat(rlat) ; rlat:long_name = "latitude in rotated pole grid" ; rlat:units = "degrees" ; rlon:standard_name = "grid_latitude"; float lev(lev) ; lev:long_name = "pressure level" ; lev:units = "hPa" ; float lon(rlat,rlon) ; lon:long_name = "longitude" ; lon:units = "degrees_east" ; float lat(rlat,rlon) ; lat:long_name = "latitude" ; lat:units = "degrees_north" ;
A CF compliant application can determine that rlon and rlat are
longitude and latitude values in the rotated grid by recognizing the
standard names grid_longitude
and
grid_latitude
. Note that the units of the rotated
longitude and latitude axes are given as degrees
. This
should prevent a COARDS compliant application from mistaking the variables
rlon
and rlat
to be actual longitude
and latitude coordinates. The entries for these names in the standard name
table indicate the appropriate sign conventions for the units of
degrees
.
Example 5.7. Lambert conformal projection
dimensions: y = 228; x = 306; time = 41; variables: int Lambert_Conformal; Lambert_Conformal:grid_mapping_name = "lambert_conformal_conic"; Lambert_Conformal:standard_parallel = 25.0; Lambert_Conformal:longitude_of_central_meridian = 265.0; Lambert_Conformal:latitude_of_projection_origin = 25.0; double y(y); y:units = "km"; y:long_name = "y coordinate of projection"; y:standard_name = "projection_y_coordinate"; double x(x); x:units = "km"; x:long_name = "x coordinate of projection"; x:standard_name = "projection_x_coordinate"; double lat(y, x); lat:units = "degrees_north"; lat:long_name = "latitude coordinate"; lat:standard_name = "latitude"; double lon(y, x); lon:units = "degrees_east"; lon:long_name = "longitude coordinate"; lon:standard_name = "longitude"; int time(time); time:long_name = "forecast time"; time:units = "hours since 2004-06-23T22:00:00Z"; float Temperature(time, y, x); Temperature:units = "K"; Temperature:long_name = "Temperature @ surface"; Temperature:missing_value = 9999.0; Temperature:coordinates = "lat lon"; Temperature:grid_mapping = "Lambert_Conformal";
An application can determine that x
and
y
are the projection coordinates by recognizing the
standard names projection_x_coordinate
and
projection_y_coordinate
. The grid mapping variable
Lambert_Conformal
contains the mapping parameters as
attributes, and is associated with the Temperature
variable via its grid_mapping attribute
.
Example 5.8. Latitude and longitude on a spherical Earth
dimensions:
lat = 18 ;
lon = 36 ;
variables:
double lat(lat) ;
double lon(lon) ;
float temp(lat, lon) ;
temp:long_name = "temperature" ;
temp:units = "K" ;
temp:grid_mapping = "crs" ;
int crs ;
crs:grid_mapping_name = "latitude_longitude"
crs:semi_major_axis = 6371000.0 ;
crs:inverse_flattening = 0 ;
Example 5.9. Latitude and longitude on the WGS 1984 datum
dimensions:
lat = 18 ;
lon = 36 ;
variables:
double lat(lat) ;
double lon(lon) ;
float temp(lat, lon) ;
temp:long_name = "temperature" ;
temp:units = "K" ;
temp:grid_mapping = "crs" ;
int crs ;
crs:grid_mapping_name = "latitude_longitude";
crs:longitude_of_prime_meridian = 0.0 ;
crs:semi_major_axis = 6378137.0 ;
crs:inverse_flattening = 298.257223563 ;
Example 5.10. British National Grid
dimensions:
lat = 648 ;
lon = 648 ;
y = 18 ;
x = 36 ;
variables:
double x(x) ;
x:standard_name = "projection_x_coordinate" ;
x:units = "m" ;
double y(y) ;
y:standard_name = "projection_y_coordinate" ;
y:units = "m" ;
double lat(y, x) ;
double lon(y, x) ;
float temp(y, x) ;
temp:long_name = "temperature" ;
temp:units = "K" ;
temp:coordinates = "lat lon" ;
temp:grid_mapping = "crs" ;
int crs ;
crs:grid_mapping_name = "transverse_mercator";
crs:semi_major_axis = 6377563.396 ;
crs:semi_minor_axis = 6356256.910 ;
crs:inverse_flattening = 299.3249646 ;
crs:latitude_of_projection_origin = 49.0 ;
crs:longitude_of_projection_origin = -2.0 ;
crs:false_easting = 400000.0 ;
crs:false_northing = -100000.0 ;
crs:scale_factor_at_central_meridian = 0.9996012717 ;
An optional grid mapping attribute called
crs_wkt
may be used to specify multiple coordinate
system properties in so-called well-known text
format (usually abbreviated to CRS WKT or OGC WKT). The CRS WKT format
is widely recognised and used within the geoscience software community.
As such it represents a versatile mechanism for encoding information
about a variety of coordinate reference system parameters in a highly
compact notational form.
The crs_wkt
attribute
should comprise a text string that conforms to the WKT syntax as
specified in reference [[OGC_CTS]]. If desired the
text string may contain embedded newline characters to aid human
readability. However, any such characters are purely cosmetic and do not
alter the meaning of the attribute value. It is envisaged that the value
of the crs_wkt
attribute typically will be a single
line of text, one intended primarily for machine processing. Other than
the requirement to be a valid WKT string, the CF convention does not
prescribe the content of the crs_wkt
attribute since
it will necessarily be context-dependent.
The crs_wkt
attribute
is intended to act as a supplement to other single-property CF grid
mapping attributes (as described in Appendix F); it is not intended to
replace those attributes. If data producers omit the single-property
grid mapping attributes in favour of the compound
crs_wkt
attribute, software which cannot interpret
crs_wkt
will be unable to use the grid_mapping
information. Therefore the CRS should be described as thoroughly as
possible with the single-property attributes as well as by
crs_wkt
.
There will be occasions when a given CRS
property value is duplicated in both a single-property grid mapping
attribute and the crs_wkt
attribute. In such cases
the onus is on data producers to ensure that the property values are
consistent. However, in those situations where two values of a given
property are different, then the value specified by the single-property
attribute shall take precedence. For example, if the semi-major axis
length of the ellipsoid is defined by the grid mapping attribute
semi_major_axis
and also by the
crs_wkt
attribute (via the WKT
SPHEROID
[...] element) then the former, being the
more specific attribute, takes precedence. Naturally if the two values
are equal then no ambiguity arises.
Likewise, in those cases where the value of a CRS WKT element should be used consistently across the CF-netCDF community (names of projections and projection parameters, for example) then, the values shown in <https://cf-pcmdi.llnl.gov/trac/wiki/Cf2CrsWkt>[1] should be preferred; these are derived from the OGP/EPSG registry of geodetic parameters, which is considered to represent the definitive authority as regards CRS property names and values.
Example 5.11 illustrates how the
coordinate system properties specified via the crs
grid mapping variable in Example 5.10 might be expressed using a
crs_wkt
attribute (it also represents a slightly
modified version of the WKT example shown in section 7.4 of [[OGC_CTS]]). For brevity only the grid mapping variable is
included in this example; all other elements are as per the earlier
example. Names of projection PARAMETERs follow the spellings used in the
EPSG geodetic parameter registry. Example 5.11 illustrates how certain
WKT elements - all of which are optional - can be used to specify CRS
properties not covered by existing CF grid mapping attributes,
including:
use of the TOWGS84 element to specify horizontal datum transformation parameters (to WGS 1984 datum)
use of the VERT_DATUM element to specify vertical datum information
use of additional PARAMETER elements (albeit not essential ones in this example) to define the location of the false origin of the projection
use of AUTHORITY elements to specify object identifier codes assigned by an external authority, OGP/EPSG in this instance
Example 5.11. British National Grid + Newlyn Datum in CRS WKT format
...
int crs ;
crs:grid_mapping_name = "transverse_mercator" ;
crs:crs_wkt = "COMPD_CS ["OSGB 1936 / British National Grid + ODN",
PROJCS ["OSGB 1936 / British National Grid",
GEOGCS ["OSGB 1936",
DATUM ["OSGB 1936",
SPHEROID ["Airy 1830", 6377563.396, 299.3249646],
TOWGS84[375, -111, 431, 0, 0, 0, 0]
],
PRIMEM ["Greenwich", 0],
UNIT ["degree", 0.0174532925199433]
],
PROJECTION ["Transverse Mercator"],
PARAMETER ["False easting", 400000],
PARAMETER ["False northing", -100000],
PARAMETER ["Longitude of natural origin", -2.0],
PARAMETER ["Latitude of natural origin", 49.0],
PARAMETER ["Longitude of false origin", -7.556],
PARAMETER ["Latitude of false origin", 49.766],
PARAMETER ["Scale factor at natural origin", 0.9996012717],
UNIT ["metre", 1.0],
AUTHORITY ["EPSG", "27700"]
],
VERT_CS ["Newlyn",
VERT_DATUM ["Ordnance Datum Newlyn", 2005],
UNIT ["metre", 1.0]",
AXIS ["Gravity-related height", UP],
AUTHORITY ["EPSG", "5701"]
]]" ;
...
Note: To enhance readability the WKT value has been split across multiple lines and embedded quotation marks (") left unescaped - in real netCDF files such characters would need to be escaped. The WKT specification in [OGC_CTS] appears to silent be as regards which character(s) may be used to delimit text-valued properties; however, since all the examples in that specification use quotation marks, the use of that particular delimiting character is mandated by the CF convention.