1.. _rfc-20:
2
3================================================================================
4RFC 20: OGRSpatialReference Axis Support
5================================================================================
6
7Author: Frank Warmerdam
8
9Contact: warmerdam@pobox.com
10
11Status: Adopted
12
13Summary
14-------
15
16The OGRSpatialReference and OGRCoordinateTransformation classes assume
17that all coordinate systems use (easting, northing) coordinate order (or
18in geographic terms (longitude, latitude)). In practice some coordinate
19systems use alternate axis orientations (such as the Krovak projection),
20and some standards (GML, WMS 1.3, WCS 1.1) require honouring the EPSG
21declaration that all it's geographic coordinates have (latitude,
22longitude) coordinate ordering.
23
24This RFC attempts to extend the OGRSpatialReference, and
25OGRCoordinateTransformation classes to support alternate axis
26orientations, and to update selected drivers (GML, WMS, WCS, GMLJP2) to
27properly support axis ordering.
28
29WKT Axis Representation
30-----------------------
31
32The OGC WKT SRS format (per OGC 01-???) already indicates a way of
33defining coordinate system axes as shown in this example:
34
35::
36
37   GEOGCS["WGS 84",
38       DATUM["WGS_1984",
39           SPHEROID["WGS 84",6378137,298.257223563,
40               AUTHORITY["EPSG","7030"]],
41           TOWGS84[0,0,0,0,0,0,0],
42           AUTHORITY["EPSG","6326"]],
43       PRIMEM["Greenwich",0,
44           AUTHORITY["EPSG","8901"]],
45       UNIT["degree",0.0174532925199433,
46           AUTHORITY["EPSG","9108"]],
47       AXIS["Lat",NORTH],
48       AXIS["Long",EAST],
49       AUTHORITY["EPSG","4326"]]
50
51There is one AXIS definition per axis with order relating to position
52within a tuple. The first argument is the user name for the axis and
53exact values are not specified. The second argument is a direction and
54may be one of NORTH, SOUTH, EAST or WEST.
55
56Dilemma
57-------
58
59The core challenge of this RFC is adding support for axes orders,
60including honouring EPSG desired axis order for geographic coordinate
61systems where appropriate without breaking existing files and code that
62make extensive use of EPSG coordinate systems but override axis
63orientations and assume they should be treated as long, lat regardless
64of what EPSG says.
65
66In particular, we come up with appropriate policies and mechanisms to
67decide when a file in a geographic coordinate system like EPSG:4326 is
68to be treated as lat/long and when it should be long/lat. Because of the
69extensive existing practice it behooves us to err on the side of past
70practice, and require "opting in" to honouring EPSG axis ordering.
71
72The Hack
73--------
74
75The main mechanism by I propose to work around the dilemma is to
76differentiate between geographic coordinate systems with the AXIS values
77set and those without. In particular, a WKT coordinate system with the
78EPSG authority code (ie. 4326) set, but no axis declarations will be
79assumed to be long, lat even though that is contrary to the definition
80from EPSG of 4326. Only in cases where we really *know* we want to
81honour EPSG's axis order will we actually populate the axis declarations
82indicating lat, long.
83
84The hope is that this will let us continue to (mis)use EPSG:4326
85definitions without necessary honouring the EPSG axis ordering except in
86specific circumstances.
87
88OGRSpatialReference
89-------------------
90
91New Enumeration
92~~~~~~~~~~~~~~~
93
94::
95
96
97   typedef enum {
98     OAO_Unknown = 0,
99     OAO_North = 1,
100     OAO_South = 2,
101     OAO_East = 3,
102     OAO_West = 4
103   } OGRAxisOrientation;
104
105New methods
106~~~~~~~~~~~
107
108::
109
110       const char *GetAxis( const char *pszTargetKey, int iAxis,
111                            OGRAxisOrientation *peOrientation );
112
113Fetch information about one axis (iAxis is zero based).
114
115::
116
117       OGRErr      SetAxes( const char *pszTargetKey,
118                            const char *pszXAxisName, OGRAxisOrientation eXAxisOrientation,
119                            const char *pszYAxisName, OGRAxisOrientation eYAxisOrientation,
120                            const char *pszZAxisName=NULL, OGRAxisOrientation eZAxisOrientation = OAO_Unknown );
121
122Defines the X and Y axes for a given target key (PROJCS or GEOGCS).
123
124::
125
126       int         EPSGTreatsAsLatLong();
127
128Returns true based on the EPSG code if EPSG would like this coordinate
129system to be treated as lat/long. This is useful in contexts like WMS
1301.3 where EPSG:4326 needs to be interpreted as lat/long due to the
131standard.
132
133::
134
135       OGRErr      importFromEPSGA( int );
136
137This works like importFromEPSG() but will assign the EPSG defined AXIS
138definition.
139
140Note that OGRSpatialReference::StripNodes( "AXIS" ); can be used to
141strip axis definitions where they are not desired.
142
143importFromURN
144~~~~~~~~~~~~~
145
146Modify importFromURN() to set AXIS values properly for EPSG and OGC
147geographic coordinate systems. So urn:...:EPSG: will be assumed to
148really honour EPSG conventions.
149
150SetWellKnownGeogCS()
151~~~~~~~~~~~~~~~~~~~~
152
153This method appears to be the only code
154
155-  Modify SetWellKnownGeogCS() to *not* set AXIS values, and strip AXIS
156   values out of any other hardcoded WKT definitions.
157
158importFromEPSG()
159~~~~~~~~~~~~~~~~
160
161-  importFromEPSG() will continue to *not* set AXIS values for GEOGCS
162   coordinate systems.
163-  importFromEPSG() will now set axis values for projected coordinate
164   systems (at least in cases like Krovak where it is a non-default axis
165   orientation).
166-  importFromEPSG() will be implemented by calling importFromEPSGA() and
167   stripping off axis definitions from the geographic portion of the
168   returned definition.
169
170SetFromUserInput()
171~~~~~~~~~~~~~~~~~~
172
173-  This method will have one new option which is a value prefixed by
174   EPSGA: will be passed to importFromEPSGA() (similarly to EPSG:n being
175   passed to importFromEPSG()).
176
177OGRCoordinateTransformation
178---------------------------
179
180If AXIS values are set on source and/or destination coordinate system,
181the OGRCoordinateTransformation code will take care of converting into
182normal easting/northing before calling PROJ.
183
184The CPL config option "GDAL_IGNORE_AXIS_ORIENTATION" may also be set to
185"TRUE" to disable OGRCoordinateTransformation's checking, and
186application of axis orientation changes. Effectively this is a backdoor
187to disable the core effects of the RFC.
188
189Drivers Affected
190----------------
191
192-  GMLJP2 (classes in gcore/gdalgmlcoverage.cpp and
193   gcore/gdaljp2metadata.cpp).
194-  WCS (based on interpretation of urns).
195-  WMS (maybe? actually, I suspect we don't actually get the coordinate
196   system from the capabalities)
197-  OGR GML (maybe? only GML3 affected?)
198-  BSB, SAR_CEOS, ENVISAT, HDF4, JDEM, L1B, LAN, SRTMHGT: Like
199   SetWellKnownGeogCS() these all include lat/long AXIS specifications
200   in their hardcoded WGS84 coordinate systems. These need to be removed
201   so they will default to being interpreted as long/lat.
202
203Versions
204--------
205
206Work will be in trunk for GDAL/OGR 1.6.0 with the following exceptions
207which will be address in 1.5.x:
208
209-  Existing use of AXIS specifier will for geographic coordinate systems
210   will be stripped from SetWellKnownGeogCS() and the various drivers
211   with hard coded WKT strings.
212-  Some sort of hack will need to be introduced into the GMLJP2 (and
213   possibly WCS) code to flip EPSG authority lat/long values (details to
214   be worked out).
215
216Implementation
217--------------
218
219Implementation would be done by Frank Warmerdam. Some aspects (such as
220properly capturing axis ordering for projected coordinate systems) might
221not be implemented immediately.
222
223Compatibility Issues
224--------------------
225
226The greatest concern is that any existing WKT coordinate systems with
227LAT/LONG axis ordering (in VRT files, or .aux.xml files for instance)
228will be interpreted differently by GDAL/OGR 1.6.0 than they were by
2291.5.0. This could easily occur if files in formats like BSB, or HDF4
230were copied to a format using WKT coordinate systems (such as JPEG with
231a .aux.xml file). To partially mitigate this I am proposing that AXIS
232definitions be removed from GDAL 1.5.1.
233
234Supporting Information
235----------------------
236
237-  OSGeo Wiki Summary:
238   `http://wiki.osgeo.org/index.php/Axis_Order_Confusion <http://wiki.osgeo.org/index.php/Axis_Order_Confusion>`__
239