Opened 14 years ago

Last modified 13 years ago

#3576 new defect

WFS 1.1 : MapServer returns srsName="EPSG:xxxx" in GML geometries instead of srsName="urn:x-ogc:def:crs:EPSG:xxxx"

Reported by: rouault Owned by: assefa
Priority: normal Milestone:
Component: WFS Server Version: unspecified
Severity: normal Keywords:
Cc: warmerdam, assefa, dmorissette, tomkralidis, sdlime, aaime

Description

I've an issue to make the new OGR WFS driver work with both MapServer or GeoServer in WFS 1.1 with EPSG:4326 layers.

Basically the OGR GML driver relies on the srsName attribute of <gml:> elements to decide if it must do the axis swapping to always return long/lat to calling code. When srsName="urn:x-ogc:def:crs:EPSG:4326", it knows the coordinates are in lat/long order. When srsName="EPSG:4326", it assumes it is long/lat order. The reasoning behind this comes from http://geoserver.org/display/GEOSDOC/2.+WFS+-+Web+Feature+Service ("The axis order issue" section)

The issue with MapServer is that it always write srsName="EPSG:4326", even in WFS 1.1. In mapserver trunk, the <DefaultSRS>urn:x-ogc:def:crs:EPSG:4326</DefaultSRS> is advertized in GetCapabilities(), so I'd assume srsName to be set to that value when no &SRSNAME= is passed. Currently, even if I add &SRSNAME=urn:x-ogc:def:crs:EPSG:4326 to the GetFeature request, srsName="EPSG:4326" is also written in the GML result.

(Note: Ticket #3574 is about another related issue about axis ordering)

Basically, I think mapserver behaviour should be similar with geoserver behaviour, as demonstrated below :

http://sigma.openplans.org/geoserver/ows?SERVICE=WFS&VERSION=1.1.0&REQUEST=GetFeature&TYPENAME=tiger:poi

or

http://sigma.openplans.org/geoserver/ows?SERVICE=WFS&VERSION=1.1.0&REQUEST=GetFeature&TYPENAME=tiger:poi&SRSNAME=urn:x-ogc:def:crs:EPSG:4326

return

<wfs:FeatureCollection numberOfFeatures="18" 
timeStamp="2010-10-16T14:21:57.955-04:00" 
xsi:schemaLocation="[snip]">
<gml:boundedBy>
<gml:Envelope srsName="urn:x-ogc:def:crs:EPSG:4326">
<gml:lowerCorner>-8511855.707102032 -1.454822997613504E12</gml:lowerCorner>
<gml:upperCorner>4622911.470043941 37.265625</gml:upperCorner>
</gml:Envelope>
</gml:boundedBy>
<gml:featureMembers>
<tiger:poi gml:id="poi.1">
<gml:boundedBy>
<gml:Envelope srsName="urn:x-ogc:def:crs:EPSG:4326">
<gml:lowerCorner>40.707587626256554 -74.01046109936333</gml:lowerCorner>
<gml:upperCorner>40.707587626256554 -74.01046109936333</gml:upperCorner>
</gml:Envelope>
</gml:boundedBy>
<tiger:the_geom>
<gml:Point srsName="urn:x-ogc:def:crs:EPSG:4326">
<gml:pos>40.707587626256554 -74.01046109936333</gml:pos>
</gml:Point>
</tiger:the_geom>
<tiger:NAME>museam</tiger:NAME>
<tiger:THUMBNAIL>pics/22037827-Ti.jpg</tiger:THUMBNAIL>
<tiger:MAINPAGE>pics/22037827-L.jpg</tiger:MAINPAGE>
</tiger:poi>
[truncated]

whereas

http://sigma.openplans.org/geoserver/ows?SERVICE=WFS&VERSION=1.1.0&REQUEST=GetFeature&TYPENAME=tiger:poi&SRSNAME=EPSG:4326

return

<wfs:FeatureCollection numberOfFeatures="18" 
timeStamp="2010-10-16T14:22:46.401-04:00" 
xsi:schemaLocation="[snip]">
<gml:boundedBy>
<gml:Envelope srsName="http://www.opengis.net/gml/srs/epsg.xml#4326">
<gml:lowerCorner>-1.454822997613504E12 -8511855.707102032</gml:lowerCorner>
<gml:upperCorner>37.265625 4622911.470043941</gml:upperCorner>
</gml:Envelope>
</gml:boundedBy>
<gml:featureMembers>
<tiger:poi gml:id="poi.1">
<gml:boundedBy>
<gml:Envelope srsName="http://www.opengis.net/gml/srs/epsg.xml#4326">
<gml:lowerCorner>-74.01046109936333 40.707587626256554</gml:lowerCorner>
<gml:upperCorner>-74.01046109936333 40.707587626256554</gml:upperCorner>
</gml:Envelope>
</gml:boundedBy>
<tiger:the_geom>
<gml:Point>
<gml:pos>-74.01046109936333 40.707587626256554</gml:pos>
</gml:Point>
</tiger:the_geom>
<tiger:NAME>museam</tiger:NAME>
<tiger:THUMBNAIL>pics/22037827-Ti.jpg</tiger:THUMBNAIL>
<tiger:MAINPAGE>pics/22037827-L.jpg</tiger:MAINPAGE>
</tiger:poi>
[truncated]

Discussed with FrankW on IRC : http://logs.qgis.org/mapserver/%23mapserver.2010-10-16.log

Change History (6)

comment:1 by rouault, 14 years ago

CubeWerx has a behaviour somehow consistant with GeoServer, but not completely the same.

http://portal.cubewerx.com/cubewerx/cubeserv/cubeserv.cgi?CONFIG=haiti_vgi&DATASTORE=vgi&MAXFEATURES=1&SERVICE=WFS&VERSION=1.1.0&REQUEST=GetFeature&TYPENAME=cw:BUILDINGS

returns a <gml:Polygon srsName="EPSG:4326"> with long/lat order

and

http://portal.cubewerx.com/cubewerx/cubeserv/cubeserv.cgi?CONFIG=haiti_vgi&DATASTORE=vgi&MAXFEATURES=1&SERVICE=WFS&VERSION=1.1.0&REQUEST=GetFeature&TYPENAME=cw:BUILDINGS&SRSNAME=urn:ogc:def:crs:EPSG::4326

returns <gml:Polygon srsName="urn:ogc:def:crs:EPSG::4326"> with lat/long order

So the only difference with GeoServer is that they use EPSG:4326 as the default if SRSNAME is not specified. I imagine this is to keep backward compatibility with WFS 1.0 clients...

comment:2 by assefa, 14 years ago

Cc: dmorissette tomkralidis sdlime added
Component: MapServer C LibraryWFS Server
Owner: changed from sdlime to assefa

2 things here:

  • I believe that MapServer should effectively write out urn:x-ogc:def:crs:xxx for wfs 1.1.0
  • we had a discussion at the TO sprint code with Daniel and Tom on the behavior adopted by Geoserver, and the conclusion was that since It is assumed that if you use wfs 1.1.x and projections such as epsg:4326, the axis are be swapped, so we should consistently respect this regardless of the fact that the user sent epsg:4326 or the fill urn:..epsg:4326. That is what was implemented.

I can certainly go through the code and make sure that the full urn is returned with the WFS/GML request. On the 2nd point, although changes can be done fairly easily, I rather not have to do them unless every body strongly disagree with what is there.

comment:3 by rouault, 14 years ago

I agree with your 1st point. urn:x-ogc:def:crs:xxx for WFS 1.1.0 would be unambiguous.

Regarding the 2nd point, I'll leave it to your judgement. But that basically means that WFS clients cannot reliably know the actual axis order when they get EPSG:4326 as the srsName. If the server is GeoServer or Cuberwerx, the order is lon/lat whatever the requested WFS version is. If it's MapServer, it's lon/lat in WFS 1.0.0 and lat/lon in WFS 1.1.0. Where is the truth... ? I'm wondering if OGC CITE tests actually test that point and what is the correct behaviour they expect if it is tested. Would be good to have some "referee" on that interoperability point ;-)

comment:4 by aaime, 13 years ago

Hi all, interesting discussion. As far as I know nowhere in the WFS spec anything is said about the axis order (unlike, for example, the WMS 1.3 spec where the axis order is explicitly discussed in the spec). The GeoServer position stems from the fact that only for the urn form OGC explicitly says one has to follow the axis order of the authority. Also talking with OGC people we had the impression they consider EPSG:xywz as deprecated because its meaning was not clearly defined from the beginning, so in the end we adopted "legacy" behavior for it, and "new" behavior for the urn form instead. We also found it to be a practical choice, as people ask how the heck to get data in the "normal" order out of a WFS 1.1 service, our answer has been so far "you are not supposed to get data in that order, but if you really need to, use the legacy EPSG:xywz codes"

As for CITE tests checking the axis order, nope, they don't, in fact as far as I remember the implementors of the CITE tests used ordinates that are always below 90 to conveniently dodge the question altogheter (when WFS 1.1 came out the expected axis order was not clear at all, since you have to read a different spec, one talking about the srs URIs, to get any indication about it).

comment:5 by aaime, 13 years ago

Cc: aaime added

comment:6 by assefa, 13 years ago

Thanks Ardrea for detailing the Geoserver reasoning. I agree that the neither the specs not the cite tests clarify this point. I have also taken the same approach for wms 1.3.0 where EPSG:4326 is always interpreted to be lat/long (when parsing coordinates that can be given in the GetMap request), but I believe that wms 1.3.0 is more clear on that aspect and expects this convention.

Note: See TracTickets for help on using tickets.