Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge pull request #39373 from elpaso/bugfix-gh39371-server-wfst-igno…
…re-srsname

Server WFST: use srsName when needed
  • Loading branch information
elpaso committed Oct 16, 2020
2 parents 6cd8d89 + dd2b56a commit 9808897
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 6 deletions.
9 changes: 6 additions & 3 deletions src/server/services/wfs/qgswfstransaction.cpp
Expand Up @@ -711,7 +711,7 @@ namespace QgsWfs
QgsFeatureList featureList;
try
{
featureList = featuresFromGML( action.featureNodeList, provider );
featureList = featuresFromGML( action.featureNodeList, vlayer );
}
catch ( QgsOgcServiceException &ex )
{
Expand Down Expand Up @@ -786,11 +786,13 @@ namespace QgsWfs
filterRestorer.reset();
}

QgsFeatureList featuresFromGML( QDomNodeList featureNodeList, QgsVectorDataProvider *provider )
QgsFeatureList featuresFromGML( QDomNodeList featureNodeList, QgsVectorLayer *layer )
{
// Store the inserted features
QgsFeatureList featList;

const QgsVectorDataProvider *provider { layer->dataProvider() };

// Get Layer Field Information
QgsFields fields = provider->fields();
const QMap<QString, int> fieldMap = provider->fieldNameMap();
Expand Down Expand Up @@ -839,7 +841,8 @@ namespace QgsWfs
}
else //a geometry attribute
{
QgsGeometry g = QgsOgcUtils::geometryFromGML( currentAttributeElement );
const QgsOgcUtils::Context context { layer, provider->transformContext() };
QgsGeometry g = QgsOgcUtils::geometryFromGML( currentAttributeElement, context );
if ( g.isNull() )
{
throw QgsRequestNotWellFormedException( QStringLiteral( "Geometry from GML error on layer insert" ) );
Expand Down
2 changes: 1 addition & 1 deletion src/server/services/wfs/qgswfstransaction.h
Expand Up @@ -112,7 +112,7 @@ namespace QgsWfs
/**
* Transform GML feature nodes to features
*/
QgsFeatureList featuresFromGML( QDomNodeList featureNodeList, QgsVectorDataProvider *provider );
QgsFeatureList featuresFromGML( QDomNodeList featureNodeList, QgsVectorLayer *layer );

/**
* Perform the transaction
Expand Down
4 changes: 3 additions & 1 deletion src/server/services/wfs/qgswfstransaction_1_0_0.cpp
Expand Up @@ -461,7 +461,9 @@ namespace QgsWfs

if ( !geometryElem.isNull() )
{
QgsGeometry g = QgsOgcUtils::geometryFromGML( geometryElem );
const QgsOgcUtils::Context context { vlayer, provider->transformContext() };
QgsGeometry g = QgsOgcUtils::geometryFromGML( geometryElem, context );

if ( g.isNull() )
{
action.error = true;
Expand Down
76 changes: 75 additions & 1 deletion tests/src/python/test_qgsserver_wfs.py
Expand Up @@ -28,7 +28,15 @@

from qgis.testing import unittest
from qgis.PyQt.QtCore import QSize
from qgis.core import QgsVectorLayer
from qgis.core import (
QgsVectorLayer,
QgsFeatureRequest,
QgsExpression,
QgsCoordinateReferenceSystem,
QgsCoordinateTransform,
QgsCoordinateTransformContext,
QgsGeometry,
)

import osgeo.gdal # NOQA

Expand Down Expand Up @@ -96,11 +104,13 @@ def test_operation_not_supported(self):

def test_project_wfs(self):
"""Test some WFS request"""

for request in ('GetCapabilities', 'DescribeFeatureType'):
self.wfs_request_compare(request)
self.wfs_request_compare(request, '1.0.0')

def wfs_getfeature_compare(self, requestid, request):

project = self.testdata_path + "test_project_wfs.qgs"
assert os.path.exists(project), "Project file not found: " + project

Expand All @@ -122,6 +132,7 @@ def wfs_getfeature_compare(self, requestid, request):
)

def test_getfeature(self):

tests = []
tests.append(('nobbox', 'GetFeature&TYPENAME=testlayer'))
tests.append(
Expand All @@ -139,6 +150,7 @@ def test_getfeature(self):

def test_wfs_getcapabilities_100_url(self):
"""Check that URL in GetCapabilities response is complete"""

# empty url in project
project = os.path.join(
self.testdata_path, "test_project_without_urls.qgs")
Expand Down Expand Up @@ -190,6 +202,7 @@ def test_wfs_getcapabilities_100_url(self):
"onlineResource=\"my_wfs_advertised_url\"" in item, True)

def result_compare(self, file_name, error_msg_header, header, body):

self.assert_headers(header, body)
response = header + body
reference_path = self.testdata_path + file_name
Expand All @@ -203,6 +216,7 @@ def result_compare(self, file_name, error_msg_header, header, body):
(error_msg_header))

def wfs_getfeature_post_compare(self, requestid, request):

project = self.testdata_path + "test_project_wfs.qgs"
assert os.path.exists(project), "Project file not found: " + project

Expand Down Expand Up @@ -488,6 +502,7 @@ def test_getFeatureBBOX(self):

def test_getFeatureFeatureId(self):
"""Test GetFeature with featureid"""

self.wfs_request_compare(
"GetFeature", '1.0.0', "SRSNAME=EPSG:4326&TYPENAME=testlayer&FEATUREID=testlayer.0", 'wfs_getFeature_1_0_0_featureid_0')

Expand Down Expand Up @@ -628,6 +643,65 @@ def test_getFeatureFeatureIdJson(self):
+ "&SRSNAME=EPSG:4326&TYPENAME=testlayer&FEATUREID=testlayer.0",
'wfs_getFeature_1_0_0_featureid_0_json')

def test_insert_srsName(self):
"""Test srsName is respected when insering"""

post_data = """
<Transaction xmlns="http://www.opengis.net/wfs" xsi:schemaLocation="http://www.qgis.org/gml http://localhost:8000/?SERVICE=WFS&amp;REQUEST=DescribeFeatureType&amp;VERSION=1.0.0&amp;TYPENAME=as_symbols" service="WFS" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="{version}" xmlns:gml="http://www.opengis.net/gml">
<Insert xmlns="http://www.opengis.net/wfs">
<as_symbols xmlns="http://www.qgis.org/gml">
<name xmlns="http://www.qgis.org/gml">{name}</name>
<geometry xmlns="http://www.qgis.org/gml">
<gml:Point srsName="{srsName}">
<gml:coordinates cs="," ts=" ">{coordinates}</gml:coordinates>
</gml:Point>
</geometry>
</as_symbols>
</Insert>
</Transaction>
"""

project = self.testdata_path + \
"test_project_wms_grouped_layers.qgs"
assert os.path.exists(project), "Project file not found: " + project

query_string = '?SERVICE=WFS&MAP={}'.format(
urllib.parse.quote(project))
request = post_data.format(
name='4326-test1',
version='1.1.0',
srsName='EPSG:4326',
coordinates='10.67,52.48'
)
header, body = self._execute_request(
query_string, requestMethod=QgsServerRequest.PostMethod, data=request.encode('utf-8'))

# Verify
vl = QgsVectorLayer(self.testdata_path + 'test_project_wms_grouped_layers.gpkg|layername=as_symbols', 'as_symbols')
self.assertTrue(vl.isValid())
feature = next(vl.getFeatures(QgsFeatureRequest(QgsExpression('"name" = \'4326-test1\''))))
geom = feature.geometry()

tr = QgsCoordinateTransform(QgsCoordinateReferenceSystem.fromEpsgId(4326), vl.crs(), QgsCoordinateTransformContext())

geom_4326 = QgsGeometry.fromWkt('point( 10.67 52.48)')
geom_4326.transform(tr)
self.assertEqual(geom.asWkt(0), geom_4326.asWkt(0))

# Now: insert a feature in layer's CRS
request = post_data.format(
name='25832-test1',
version='1.1.0',
srsName='EPSG:25832',
coordinates='613412,5815738'
)
header, body = self._execute_request(
query_string, requestMethod=QgsServerRequest.PostMethod, data=request.encode('utf-8'))

feature = next(vl.getFeatures(QgsFeatureRequest(QgsExpression('"name" = \'25832-test1\''))))
geom = feature.geometry()
self.assertEqual(geom.asWkt(0), geom_4326.asWkt(0))


if __name__ == '__main__':
unittest.main()
Binary file modified tests/testdata/qgis_server/test_project_wms_grouped_layers.gpkg
Binary file not shown.

0 comments on commit 9808897

Please sign in to comment.