[Geoserver-users] lat-lon vs lon-lat coordinate ordering in WFS BBOX and XML filter encoding

I have a WFS (using app-schema) which seems to expect coordinates in lat-lon order if I send them in a KVP BBOX query but in lon-lat order if I send them in an XML Filter request. I'm not entirely sure what the expected behaviour according to OGC standards should be but is it really to use the opposite ordering in the two versions or does this behaviour suggest there is some misconfiguration in my service or a bug?

I include an example of each type of request below together with the GeoServer log extracts for each and the spatial part of the generated PostGIS SQL queries sent to the PostGIS data store underlying the service. The GeoServer abstract selection clauses are subtly different ("bbox" vs "gsml:shape bbox") but give rise to opposite ordering of the coordinates in the generated SQL queries.

Any ideas?

Marcus Sen

Query 1 - KVP BBOX
------------------

http://ogc.bgs.ac.uk/digmap625k_gsml32_gs/wfs?SERVICE=WFS&VERSION=2.0.0&REQUEST=GetFeature&TYPENAMES=gsml:MappedFeature&BBOX=56.08643859340388,-4.0004826736994445,56.165510496146474,-3.8381055732299343&

returns 20 features

In the GeoServer logs this request appears as:

Request: getFeature
    service = WFS
    version = 2.0.0
    baseUrl = http://ogc.bgs.ac.uk:80/digmap625k_gsml32_gs/
    outputFormat = text/xml; subtype=gml/3.2
    resolve = none
    resolveDepth = *
    resolveTimeout = 300
    resultType = results
    abstractQueryExpressionGroup[0] = wfs:abstractQueryExpression=net.opengis.wfs20.impl.QueryTypeImpl@...5927... (handle: null) (abstractProjectionClause: null, abstractSelectionClause: [ bbox POLYGON ((56.08643859340388 -4.0004826736994445, 56.08643859340388 -3.8381055732299343, 56.165510496146474 -3.8381055732299343, 56.165510496146474 -4.0004826736994445, 56.08643859340388 -4.0004826736994445)) ], abstractSortingClause: null, aliases: null, typeNames: [{http://xmlns.geosciml.org/GeoSciML-Core/3.2\}MappedFeature]) (featureVersion: null, srsName: null, filter: null, propertyNames: null, sortBy: null)
    abstractQueryExpression[0]:
        abstractSelectionClause = [ bbox POLYGON ((56.08643859340388 -4.0004826736994445, 56.08643859340388 -3.8381055732299343, 56.165510496146474 -3.8381055732299343, 56.165510496146474 -4.0004826736994445, 56.08643859340388 -4.0004826736994445)) ]
        typeNames[0] = {http://xmlns.geosciml.org/GeoSciML-Core/3.2\}MappedFeature
        filter = [ bbox POLYGON ((56.08643859340388 -4.0004826736994445, 56.08643859340388 -3.8381055732299343, 56.165510496146474 -3.8381055732299343, 56.165510496146474 -4.0004826736994445, 56.08643859340388 -4.0004826736994445)) ]

and in the data source PostGIS database it generates a number of queries with the following WHERE clause:

WHERE "the_geom" && ST_GeomFromText('POLYGON ((-4.0004826736994445 56.08643859340388, -4.0004826736994445 56.165510496146474, -3.8381055732299343 56.165510496146474, -3.8381055732299343 56.08643859340388, -4.0004826736994445 56.08643859340388))', 4326) )

Query 2 - XML Filter

If I encode the equivalent (I presume) query in XML format as:

    <fes:Filter xmlns:fes="http://www.opengis.net/fes/2.0&quot;
      xmlns:gml="http://www.opengis.net/gml/3.2&quot;&gt;
        <fes:BBOX>
          <fes:ValueReference>gsml:shape</fes:ValueReference>
          <gml:Envelope srsName="EPSG:4326">
            <gml:lowerCorner>56.08643859340388
              -4.0004826736994445</gml:lowerCorner>
            <gml:upperCorner>56.165510496146474
              -3.8381055732299343</gml:upperCorner>
          </gml:Envelope>
        </fes:BBOX>
    </fes:Filter>

and pass this in the FILTER parameter as below:

http://ogc.bgs.ac.uk/digmap625k_gsml32_gs/wfs?SERVICE=WFS&VERSION=2.0.0&REQUEST=GetFeature&TYPENAMES=gsml:MappedFeature&FILTER=<fes%3AFilter%20xmlns%3Afes%3D"http%3A%2F%2Fwww.opengis.net%2Ffes%2F2.0"%20xmlns%3Agml%3D"http%3A%2F%2Fwww.opengis.net%2Fgml%2F3.2"><fes%3ABBOX><fes%3AValueReference>gsml%3Ashape<%2Ffes%3AValueReference><gml%3AEnvelope%20srsName%3D"EPSG%3A4326"><gml%3AlowerCorner>56.08643859340388%20-4.0004826736994445<%2Fgml%3AlowerCorner><gml%3AupperCorner>56.165510496146474%20-3.8381055732299343<%2Fgml%3AupperCorner><%2Fgml%3AEnvelope><%2Ffes%3ABBOX><%2Ffes%3AFilter%3

then I get 0 features returned.

This second query is logged in the GeoServer logs as:

Request: getFeature
    service = WFS
    version = 2.0.0
    baseUrl = http://ogc.bgs.ac.uk:80/digmap625k_gsml32_gs/
    outputFormat = text/xml; subtype=gml/3.2
    resolve = none
    resolveDepth = *
    resolveTimeout = 300
    resultType = results
    abstractQueryExpressionGroup[0] = wfs:abstractQueryExpression=net.opengis.wfs20.impl.QueryTypeImpl@...5928... (handle: null) (abstractProjectionClause: null, abstractSelectionClause: [ gsml:shape bbox POLYGON ((56.08643859340388 -4.0004826736994445, 56.08643859340388 -3.8381055732299343, 56.165510496146474 -3.8381055732299343, 56.165510496146474 -4.0004826736994445, 56.08643859340388 -4.0004826736994445)) ], abstractSortingClause: null, aliases: null, typeNames: [{http://xmlns.geosciml.org/GeoSciML-Core/3.2\}MappedFeature]) (featureVersion: null, srsName: null, filter: null, propertyNames: null, sortBy: null)
    abstractQueryExpression[0]:
        abstractSelectionClause = [ gsml:shape bbox POLYGON ((56.08643859340388 -4.0004826736994445, 56.08643859340388 -3.8381055732299343, 56.165510496146474 -3.8381055732299343, 56.165510496146474 -4.0004826736994445, 56.08643859340388 -4.0004826736994445)) ]
        typeNames[0] = {http://xmlns.geosciml.org/GeoSciML-Core/3.2\}MappedFeature
        filter = [ gsml:shape bbox POLYGON ((56.08643859340388 -4.0004826736994445, 56.08643859340388 -3.8381055732299343, 56.165510496146474 -3.8381055732299343, 56.165510496146474 -4.0004826736994445, 56.08643859340388 -4.0004826736994445)) ]

and gives rise to PostGIS queries with a WHERE clause like:

WHERE "the_geom" && ST_GeomFromText('POLYGON ((56.08643859340388 -4.0004826736994445, 56.08643859340388 -3.8381055732299343, 56.165510496146474 -3.8381055732299343, 56.165510496146474 -4.0004826736994445, 56.08643859340388 -4.0004826736994445))', 4326) )

If I swap lat-lon to lon-lat ordering in the second query then I get 20 features back again.

This message (and any attachments) is for the recipient only. NERC is subject to the Freedom of Information Act 2000 and the contents of this email and any reply you make may be disclosed by NERC unless it is exempt from release under the Act. Any material supplied to NERC may be stored in an electronic records management system.

Hi,
it’s pretty simple, in the KVP reqeust you did not specify the SRS as the fifth parameter of the bbox, so the axis order
defaults to the declared in the caps document, which uses the urn syntax and it’s ordered lat/lon, but in the XML request
you did specify the srs and used the legacy syntax, which is instead ordered lon/lat.

See also:
http://docs.geoserver.org/latest/en/user/services/wfs/basics.html#axis-ordering

Cheers
Andrea

···

On Tue, Oct 15, 2013 at 6:07 PM, Sen, Marcus A. <mase@anonymised.com> wrote:

I have a WFS (using app-schema) which seems to expect coordinates in lat-lon order if I send them in a KVP BBOX query but in lon-lat order if I send them in an XML Filter request. I’m not entirely sure what the expected behaviour according to OGC standards should be but is it really to use the opposite ordering in the two versions or does this behaviour suggest there is some misconfiguration in my service or a bug?

I include an example of each type of request below together with the GeoServer log extracts for each and the spatial part of the generated PostGIS SQL queries sent to the PostGIS data store underlying the service. The GeoServer abstract selection clauses are subtly different (“bbox” vs “gsml:shape bbox”) but give rise to opposite ordering of the coordinates in the generated SQL queries.

Any ideas?

Marcus Sen

Query 1 - KVP BBOX

http://ogc.bgs.ac.uk/digmap625k_gsml32_gs/wfs?SERVICE=WFS&VERSION=2.0.0&REQUEST=GetFeature&TYPENAMES=gsml:MappedFeature&BBOX=56.08643859340388,-4.0004826736994445,56.165510496146474,-3.8381055732299343&

returns 20 features

In the GeoServer logs this request appears as:

Request: getFeature
service = WFS
version = 2.0.0
baseUrl = http://ogc.bgs.ac.uk:80/digmap625k_gsml32_gs/
outputFormat = text/xml; subtype=gml/3.2
resolve = none
resolveDepth = *
resolveTimeout = 300
resultType = results
abstractQueryExpressionGroup[0] = wfs:abstractQueryExpression=net.opengis.wfs20.impl.QueryTypeImpl@anonymised.com (handle: null) (abstractProjectionClause: null, abstractSelectionClause: [ bbox POLYGON ((56.08643859340388 -4.0004826736994445, 56.08643859340388 -3.8381055732299343, 56.165510496146474 -3.8381055732299343, 56.165510496146474 -4.0004826736994445, 56.08643859340388 -4.0004826736994445)) ], abstractSortingClause: null, aliases: null, typeNames: [{http://xmlns.geosciml.org/GeoSciML-Core/3.2}MappedFeature]) (featureVersion: null, srsName: null, filter: null, propertyNames: null, sortBy: null)
abstractQueryExpression[0]:
abstractSelectionClause = [ bbox POLYGON ((56.08643859340388 -4.0004826736994445, 56.08643859340388 -3.8381055732299343, 56.165510496146474 -3.8381055732299343, 56.165510496146474 -4.0004826736994445, 56.08643859340388 -4.0004826736994445)) ]
typeNames[0] = {http://xmlns.geosciml.org/GeoSciML-Core/3.2}MappedFeature
filter = [ bbox POLYGON ((56.08643859340388 -4.0004826736994445, 56.08643859340388 -3.8381055732299343, 56.165510496146474 -3.8381055732299343, 56.165510496146474 -4.0004826736994445, 56.08643859340388 -4.0004826736994445)) ]

and in the data source PostGIS database it generates a number of queries with the following WHERE clause:

WHERE “the_geom” && ST_GeomFromText(‘POLYGON ((-4.0004826736994445 56.08643859340388, -4.0004826736994445 56.165510496146474, -3.8381055732299343 56.165510496146474, -3.8381055732299343 56.08643859340388, -4.0004826736994445 56.08643859340388))’, 4326) )

Query 2 - XML Filter

If I encode the equivalent (I presume) query in XML format as:

<fes:Filter xmlns:fes=“http://www.opengis.net/fes/2.0
xmlns:gml=“http://www.opengis.net/gml/3.2”>
fes:BBOX
fes:ValueReferencegsml:shape</fes:ValueReference>
<gml:Envelope srsName=“EPSG:4326”>
gml:lowerCorner56.08643859340388
-4.0004826736994445</gml:lowerCorner>
gml:upperCorner56.165510496146474
-3.8381055732299343</gml:upperCorner>
</gml:Envelope>
</fes:BBOX>
</fes:Filter>

and pass this in the FILTER parameter as below:

http://ogc.bgs.ac.uk/digmap625k_gsml32_gs/wfs?SERVICE=WFS&VERSION=2.0.0&REQUEST=GetFeature&TYPENAMES=gsml:MappedFeature&FILTER=%3Cfes%3AFilter%20xmlns%3Afes%3D%22http%3A%2F%2Fwww.opengis.net%2Ffes%2F2.0%22%20xmlns%3Agml%3D%22http%3A%2F%2Fwww.opengis.net%2Fgml%2F3.2%22%3E%3Cfes%3ABBOX%3E%3Cfes%3AValueReference%3Egsml%3Ashape%3C%2Ffes%3AValueReference%3E%3Cgml%3AEnvelope%20srsName%3D%22EPSG%3A4326%22%3E%3Cgml%3AlowerCorner%3E56.08643859340388%20-4.0004826736994445%3C%2Fgml%3AlowerCorner%3E%3Cgml%3AupperCorner%3E56.165510496146474%20-3.8381055732299343%3C%2Fgml%3AupperCorner%3E%3C%2Fgml%3AEnvelope%3E%3C%2Ffes%3ABBOX%3E%3C%2Ffes%3AFilter%3

then I get 0 features returned.

This second query is logged in the GeoServer logs as:

Request: getFeature
service = WFS
version = 2.0.0
baseUrl = http://ogc.bgs.ac.uk:80/digmap625k_gsml32_gs/
outputFormat = text/xml; subtype=gml/3.2
resolve = none
resolveDepth = *
resolveTimeout = 300
resultType = results
abstractQueryExpressionGroup[0] = wfs:abstractQueryExpression=net.opengis.wfs20.impl.QueryTypeImpl@anonymised.com (handle: null) (abstractProjectionClause: null, abstractSelectionClause: [ gsml:shape bbox POLYGON ((56.08643859340388 -4.0004826736994445, 56.08643859340388 -3.8381055732299343, 56.165510496146474 -3.8381055732299343, 56.165510496146474 -4.0004826736994445, 56.08643859340388 -4.0004826736994445)) ], abstractSortingClause: null, aliases: null, typeNames: [{http://xmlns.geosciml.org/GeoSciML-Core/3.2}MappedFeature]) (featureVersion: null, srsName: null, filter: null, propertyNames: null, sortBy: null)
abstractQueryExpression[0]:
abstractSelectionClause = [ gsml:shape bbox POLYGON ((56.08643859340388 -4.0004826736994445, 56.08643859340388 -3.8381055732299343, 56.165510496146474 -3.8381055732299343, 56.165510496146474 -4.0004826736994445, 56.08643859340388 -4.0004826736994445)) ]
typeNames[0] = {http://xmlns.geosciml.org/GeoSciML-Core/3.2}MappedFeature
filter = [ gsml:shape bbox POLYGON ((56.08643859340388 -4.0004826736994445, 56.08643859340388 -3.8381055732299343, 56.165510496146474 -3.8381055732299343, 56.165510496146474 -4.0004826736994445, 56.08643859340388 -4.0004826736994445)) ]

and gives rise to PostGIS queries with a WHERE clause like:

WHERE “the_geom” && ST_GeomFromText(‘POLYGON ((56.08643859340388 -4.0004826736994445, 56.08643859340388 -3.8381055732299343, 56.165510496146474 -3.8381055732299343, 56.165510496146474 -4.0004826736994445, 56.08643859340388 -4.0004826736994445))’, 4326) )

If I swap lat-lon to lon-lat ordering in the second query then I get 20 features back again.

This message (and any attachments) is for the recipient only. NERC is subject to the Freedom of Information Act 2000 and the contents of this email and any reply you make may be disclosed by NERC unless it is exempt from release under the Act. Any material supplied to NERC may be stored in an electronic records management system.

October Webinars: Code for Performance
Free Intel webinars can help you accelerate application performance.
Explore tips for MPI, OpenMP, advanced profiling, and more. Get the most from
the latest Intel processors and coprocessors. See abstracts and register >
http://pubads.g.doubleclick.net/gampad/clk?id=60135031&iu=/4140/ostg.clktrk


Geoserver-users mailing list
Geoserver-users@anonymised.comsts.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/geoserver-users

==
Our support, Your Success! Visit http://opensdi.geo-solutions.it for more information.

Ing. Andrea Aime

@geowolf
Technical Lead

GeoSolutions S.A.S.
Via Poggio alle Viti 1187
55054 Massarosa (LU)
Italy
phone: +39 0584 962313
fax: +39 0584 1660272
mob: +39 339 8844549

http://www.geo-solutions.it
http://twitter.com/geosolutions_it


-----Original Message-----
From: andrea.aime@...84... [mailto:andrea.aime@…84…] On Behalf Of
Andrea Aime
Sent: 15 October 2013 18:24

it's pretty simple,

Doesn't seem so simple in my case ... :frowning:

See also:
http://docs.geoserver.org/latest/en/user/services/wfs/basics.html#axis-
ordering

I hadn't read that documentation page (sorry) but I had guessed it might be worth experimenting with the style of specifying the EPSG code between short form and URN (and HTTP-URI) and it didn't change the result.

However, knowing that it _should_ work I did some more experiments setting up a simple feature WFS based on the same spatial table that I'm using with my app-schema complex WFS. It seems that changing the EPSG URI style does work with the simple WFS but not the app-schema complex one.

I edited the manually created featuretype.xml file in my app-schema configuration so that the srs, crs and bounding box information were the same as those in the featuretype.xml created by the web UI for my corresponding simple WFS as I thought that might be important but it didn't help either.

Maybe an app-schema person can comment?

Marcus

For reference I have experimented with sending the basic example query below in a number of variations:

1 - Set typenames attribute to gsml:MappedFeature and fes:ValueReference for querying the app-schema complex feature
or
  - set typenames to test:UK_625K_BEDROCK_WGS84 and fes:ValueReference to test:the_geom for querying the simple feature based on the same geometry table.

2 - Set srsName attribute (on both the Query element and gml:Envelope just to be safe) to EPSG:4326 or urn:ogc:def:crs:EPSG::4326

3 - Specify the envelope coordinates in lat-lon:

<gml:lowerCorner>56.08643859340388 -4.0004826736994445</gml:lowerCorner>
<gml:upperCorner>56.165510496146474 -3.8381055732299343</gml:upperCorner>

or

lon-lat:

<gml:lowerCorner>-4.0004826736994445 56.08643859340388</gml:lowerCorner>
<gml:upperCorner>-3.8381055732299343 56.165510496146474</gml:upperCorner>

Example query:

<?xml version="1.0" encoding="UTF-8"?>
<GetFeature
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance&quot;
  xsi:schemaLocation="http://www.opengis.net/wfs/2.0 http://schemas.opengis.net/wfs/2.0/wfs.xsd
  http://www.opengis.net/gml/3.2 http://schemas.opengis.net/gml/3.2.1/gml.xsd&quot;
  xmlns="http://www.opengis.net/wfs/2.0&quot;
  xmlns:gsml="http://xmlns.geosciml.org/GeoSciML-Core/3.2&quot;
  xmlns:fes="http://www.opengis.net/fes/2.0&quot;
  xmlns:xlink="http://www.w3.org/1999/xlink&quot;
  xmlns:gml="http://www.opengis.net/gml/3.2&quot;
  version="2.0.0" service="WFS" count="100">
  <Query typeNames="gsml:MappedFeature" srsName="urn:ogc:def:crs:EPSG::4326">
    <fes:Filter>
      <fes:BBOX>
        <fes:ValueReference>gsml:shape</fes:ValueReference>
        <gml:Envelope srsName="urn:ogc:def:crs:EPSG::4326">
          <gml:lowerCorner>56.08643859340388 -4.0004826736994445</gml:lowerCorner>
          <gml:upperCorner>56.165510496146474 -3.8381055732299343</gml:upperCorner>
        </gml:Envelope>
      </fes:BBOX>
    </fes:Filter>
  </Query>
</GetFeature>

Querying the simple feature behaves as documented expecting coordinates in lon-lat if I use EPSG:4326 and lat-lon if I use urn:ogc:def:crs:EPSG::4326. Querying the app-schema feature, however, always expects lon-lat whethere I specify EPSG:4326 or urn:ogc:def:crs:EPSG::4326

This message (and any attachments) is for the recipient only. NERC is subject to the Freedom of Information Act 2000 and the contents of this email and any reply you make may be disclosed by NERC unless it is exempt from release under the Act. Any material supplied to NERC may be stored in an electronic records management system.