Skip to content

Commit

Permalink
Server WFS 1.1: honor srsName and axis order
Browse files Browse the repository at this point in the history
Fixes #45216
  • Loading branch information
elpaso committed Sep 27, 2021
1 parent 5b68dc5 commit 8acfeca
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 8 deletions.
42 changes: 34 additions & 8 deletions src/server/services/wfs/qgswfsgetfeature.cpp
Expand Up @@ -61,6 +61,10 @@ namespace QgsWfs
const QgsCoordinateReferenceSystem &outputCrs;

bool forceGeomToMulti;

const QString &srsName;

bool hasAxisInverted;
};

QString createFeatureGeoJSON( const QgsFeature &feature, const createFeatureParams &params, const QgsAttributeList &pkAttributes );
Expand Down Expand Up @@ -424,14 +428,23 @@ namespace QgsWfs
}
else
{

// For WFS 1.1 we honor requested CRS and axis order
const QString srsName {request.serverParameters().value( QStringLiteral( "SRSNAME" ) )};
const bool invertAxis { mWfsParameters.versionAsNumber() >= QgsProjectVersion( 1, 1, 0 ) &&
outputCrs.hasAxisInverted() &&
! srsName.startsWith( QLatin1String( "EPSG:" ) ) };

const createFeatureParams cfp = { layerPrecision,
layerCrs,
attrIndexes,
typeName,
withGeom,
geometryName,
outputCrs,
forceGeomToMulti
forceGeomToMulti,
srsName,
invertAxis
};
while ( fit.nextFeature( feature ) && ( aRequest.maxFeatures == -1 || sentFeatures < aRequest.maxFeatures ) )
{
Expand Down Expand Up @@ -1156,7 +1169,8 @@ namespace QgsWfs
else
query.addQueryItem( QStringLiteral( "VERSION" ), QStringLiteral( "1.0.0" ) );

for ( auto param : query.queryItems() )
const auto queryItems {query.queryItems()};
for ( auto param : std::as_const( queryItems ) )
{
if ( sParamFilter.contains( param.first.toUpper() ) )
query.removeAllQueryItems( param.first );
Expand Down Expand Up @@ -1203,12 +1217,24 @@ namespace QgsWfs
QDomElement bbElem = doc.createElement( QStringLiteral( "gml:boundedBy" ) );
if ( format == QgsWfsParameters::Format::GML3 )
{
QDomElement envElem = QgsOgcUtils::rectangleToGMLEnvelope( rect, doc, prec );
// For WFS 1.1 we honor requested CRS and axis order
const QString srsName {request.serverParameters().value( QStringLiteral( "SRSNAME" ) )};
const bool invertAxis { mWfsParameters.versionAsNumber() >= QgsProjectVersion( 1, 1, 0 ) &&
crs.hasAxisInverted() &&
! srsName.startsWith( QLatin1String( "EPSG:" ) ) };
QDomElement envElem = QgsOgcUtils::rectangleToGMLEnvelope( rect, doc, srsName, invertAxis, prec );
if ( !envElem.isNull() )
{
if ( crs.isValid() )
{
envElem.setAttribute( QStringLiteral( "srsName" ), crs.authid() );
if ( mWfsParameters.versionAsNumber() >= QgsProjectVersion( 1, 1, 0 ) )
{
envElem.setAttribute( QStringLiteral( "srsName" ), srsName );
}
else
{
envElem.setAttribute( QStringLiteral( "srsName" ), crs.authid() );
}
}
bbElem.appendChild( envElem );
doc.appendChild( bbElem );
Expand Down Expand Up @@ -1473,19 +1499,19 @@ namespace QgsWfs
const QgsAbstractGeometry *abstractGeom = cloneGeom.constGet();
if ( abstractGeom )
{
gmlElem = abstractGeom->asGml3( doc, prec, "http://www.opengis.net/gml" );
gmlElem = abstractGeom->asGml3( doc, prec, "http://www.opengis.net/gml", params.hasAxisInverted ? QgsAbstractGeometry::AxisOrder::YX : QgsAbstractGeometry::AxisOrder::XY );
}

if ( !gmlElem.isNull() )
{
QgsRectangle box = geom.boundingBox();
QDomElement bbElem = doc.createElement( QStringLiteral( "gml:boundedBy" ) );
QDomElement boxElem = QgsOgcUtils::rectangleToGMLEnvelope( &box, doc, prec );
QDomElement boxElem = QgsOgcUtils::rectangleToGMLEnvelope( &box, doc, params.srsName, params.hasAxisInverted, prec );

if ( crs.isValid() )
{
boxElem.setAttribute( QStringLiteral( "srsName" ), crs.authid() );
gmlElem.setAttribute( QStringLiteral( "srsName" ), crs.authid() );
boxElem.setAttribute( QStringLiteral( "srsName" ), params.srsName );
gmlElem.setAttribute( QStringLiteral( "srsName" ), params.srsName );
}

bbElem.appendChild( boxElem );
Expand Down
6 changes: 6 additions & 0 deletions tests/src/python/test_qgsserver_wfs.py
Expand Up @@ -506,6 +506,12 @@ def test_getFeatureFeatureId(self):
self.wfs_request_compare(
"GetFeature", '1.0.0', "SRSNAME=EPSG:4326&TYPENAME=testlayer&FEATUREID=testlayer.0", 'wfs_getFeature_1_0_0_featureid_0')

def test_getFeatureFeature11urn(self):
"""Test GetFeature with SRSNAME urn:ogc:def:crs:EPSG::4326"""

self.wfs_request_compare(
"GetFeature", '1.1.0', "SRSNAME=urn:ogc:def:crs:EPSG::4326&TYPENAME=testlayer&FEATUREID=testlayer.0", 'wfs_getFeature_1_1_0_featureid_0_1_1_0')

def test_getFeature_EXP_FILTER_regression_20927(self):
"""Test expressions with EXP_FILTER"""

Expand Down
@@ -0,0 +1,28 @@
Content-Type: text/xml; subtype=gml/3.1.1; charset=utf-8

<wfs:FeatureCollection xmlns:wfs="http://www.opengis.net/wfs" xmlns:ogc="http://www.opengis.net/ogc" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:qgs="http://www.qgis.org/gml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.1.0/wfs.xsd http://www.qgis.org/gml ?MAP=/home/ale/dev/QGIS/tests/testdata/qgis_server/test_project_wfs.qgs&amp;SERVICE=WFS&amp;VERSION=1.1.0&amp;REQUEST=DescribeFeatureType&amp;TYPENAME=testlayer&amp;OUTPUTFORMAT=text/xml; subtype%3Dgml/3.1.1">
<gml:boundedBy>
<gml:Envelope srsName="urn:ogc:def:crs:EPSG::4326">
<gml:lowerCorner>44.90139484 8.20345931</gml:lowerCorner>
<gml:upperCorner>44.90148253 8.20354699</gml:upperCorner>
</gml:Envelope>
</gml:boundedBy>
<gml:featureMember>
<qgs:testlayer gml:id="testlayer.0">
<gml:boundedBy>
<gml:Envelope srsName="urn:ogc:def:crs:EPSG::4326">
<gml:lowerCorner>44.90148253 8.20349634</gml:lowerCorner>
<gml:upperCorner>44.90148253 8.20349634</gml:upperCorner>
</gml:Envelope>
</gml:boundedBy>
<qgs:geometry>
<Point xmlns="http://www.opengis.net/gml" srsName="urn:ogc:def:crs:EPSG::4326">
<pos xmlns="http://www.opengis.net/gml" srsDimension="2">44.90148253 8.20349634</pos>
</Point>
</qgs:geometry>
<qgs:id>1</qgs:id>
<qgs:name>one</qgs:name>
<qgs:utf8nameè>one èé</qgs:utf8nameè>
</qgs:testlayer>
</gml:featureMember>
</wfs:FeatureCollection>

0 comments on commit 8acfeca

Please sign in to comment.