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

  rlon = 128 ;
  rlat = 64 ;
  lev = 18 ;
  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

  y = 228;
  x = 306;
  time = 41;

  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

  lat = 18 ;
  lon = 36 ;
  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

  lat = 18 ;
  lon = 36 ;
  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

  lat = 648 ;
  lon = 648 ;
  y = 18 ;
  x = 36 ;
  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 ;

5.6.1. Use of the CRS Well-known Text Format

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.

[1] This reference should be treated carefully because it is subject to change.