Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Fix axis for QGIS server
  • Loading branch information
elpaso committed Oct 16, 2020
1 parent 27b64a0 commit 9edf482
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 14 deletions.
5 changes: 4 additions & 1 deletion src/providers/wfs/qgswfsprovider.cpp
Expand Up @@ -806,7 +806,10 @@ QDomElement QgsWFSProvider::geometryElement( const QgsGeometry &geometry, QDomDo
{
gmlVersion = QgsOgcUtils::GML_2_1_2;
}
applyAxisInversion = ( crs().hasAxisInverted() && ! mShared->mURI.ignoreAxisOrientation() )
// For servers like Geomedia and QGIS Server that advertise EPSG:XXXX in capabilities even in WFS 1.1 or 2.0
// cpabilities useEPSGColumnFormat is set.
// We follow GeoServer convention here which is to treat EPSG:4326 as lon/lat
applyAxisInversion = ( crs().hasAxisInverted() && ! mShared->mURI.ignoreAxisOrientation() && ! mShared->mCaps.useEPSGColumnFormat )
|| mShared->mURI.invertAxisOrientation();
}
else // 1.0
Expand Down
70 changes: 57 additions & 13 deletions tests/src/python/test_qgsserver_wfst.py
Expand Up @@ -60,9 +60,12 @@

class TestWFST(unittest.TestCase):

VERSION = '1.0.0'

@classmethod
def setUpClass(cls):
"""Run before all tests"""

cls.port = QGIS_SERVER_PORT
# Create tmp folder
cls.temp_path = tempfile.mkdtemp()
Expand Down Expand Up @@ -92,11 +95,13 @@ def setUpClass(cls):
cls.port = int(re.findall(br':(\d+)', line)[0])
assert cls.port != 0
# Wait for the server process to start
assert waitServer('http://127.0.0.1:%s' % cls.port), "Server is not responding!"
assert waitServer('http://127.0.0.1:%s' %
cls.port), "Server is not responding!"

@classmethod
def tearDownClass(cls):
"""Run after all tests"""

cls.server.terminate()
cls.server.wait()
del cls.server
Expand All @@ -107,17 +112,20 @@ def tearDownClass(cls):

def setUp(self):
"""Run before each test."""

pass

def tearDown(self):
"""Run after each test."""

pass

@classmethod
def _clearLayer(cls, layer_name):
"""
Delete all features from a vector layer
"""

layer = cls._getLayer(layer_name)
layer.startEditing()
layer.deleteFeatures([f.id() for f in layer.getFeatures()])
Expand All @@ -129,6 +137,7 @@ def _getLayer(cls, layer_name):
"""
OGR Layer factory
"""

path = cls.testdata_path + layer_name + '.shp'
layer = QgsVectorLayer(path, layer_name, "ogr")
assert layer.isValid()
Expand All @@ -139,14 +148,15 @@ def _getWFSLayer(cls, type_name, layer_name=None):
"""
WFS layer factory
"""

if layer_name is None:
layer_name = 'wfs_' + type_name
parms = {
'srsname': 'EPSG:4326',
'typename': type_name,
'url': 'http://127.0.0.1:%s/?map=%s' % (cls.port,
cls.project_path),
'version': 'auto',
'version': cls.VERSION,
'table': '',
# 'sql': '',
}
Expand All @@ -160,6 +170,7 @@ def _getFeatureByAttribute(cls, layer, attr_name, attr_value):
"""
Find the feature and return it, raise exception if not found
"""

request = QgsFeatureRequest(QgsExpression("%s=%s" % (attr_name,
attr_value)))
try:
Expand All @@ -172,21 +183,36 @@ def _checkAddFeatures(self, wfs_layer, layer, features):
"""
Check features were added
"""

wfs_layer.dataProvider().addFeatures(features)
layer = self._getLayer(layer.name())
self.assertTrue(layer.isValid())
self.assertEqual(layer.featureCount(), len(features))
self.assertEqual(wfs_layer.dataProvider().featureCount(), len(features))
self.assertEqual(
wfs_layer.dataProvider().featureCount(), len(features))

ogr_features = [f for f in layer.dataProvider().getFeatures()]

# Verify features from the layers
for f in ogr_features:
geom = next(wfs_layer.dataProvider().getFeatures(QgsFeatureRequest(
QgsExpression('"id" = %s' % f.attribute('id'))))).geometry()
self.assertEqual(geom.boundingBox(), f.geometry().boundingBox())

def _checkUpdateFeatures(self, wfs_layer, old_features, new_features):
"""
Check features can be updated
"""

for i in range(len(old_features)):
f = self._getFeatureByAttribute(wfs_layer, 'id', old_features[i]['id'])
self.assertTrue(wfs_layer.dataProvider().changeGeometryValues({f.id(): new_features[i].geometry()}))
self.assertTrue(wfs_layer.dataProvider().changeAttributeValues({f.id(): {0: new_features[i]['id']}}))
self.assertTrue(wfs_layer.dataProvider().changeAttributeValues({f.id(): {1: new_features[i]['name']}}))
f = self._getFeatureByAttribute(
wfs_layer, 'id', old_features[i]['id'])
self.assertTrue(wfs_layer.dataProvider().changeGeometryValues(
{f.id(): new_features[i].geometry()}))
self.assertTrue(wfs_layer.dataProvider().changeAttributeValues(
{f.id(): {0: new_features[i]['id']}}))
self.assertTrue(wfs_layer.dataProvider().changeAttributeValues(
{f.id(): {1: new_features[i]['name']}}))

def _checkMatchFeatures(self, wfs_layer, features):
"""
Expand All @@ -202,6 +228,7 @@ def _checkDeleteFeatures(self, layer, features):
"""
Delete features
"""

ids = []
for f in features:
wf = self._getFeatureByAttribute(layer, 'id', f['id'])
Expand All @@ -212,6 +239,7 @@ def _testLayer(self, wfs_layer, layer, old_features, new_features):
"""
Perform all test steps on the layer.
"""

self.assertEqual(wfs_layer.featureCount(), 0)
self._checkAddFeatures(wfs_layer, layer, old_features)
self._checkMatchFeatures(wfs_layer, old_features)
Expand All @@ -226,6 +254,7 @@ def testWFSPoints(self):
"""
Adds some points, then check and clear all
"""

layer_name = 'test_point'
layer = self._getLayer(layer_name)
wfs_layer = self._getWFSLayer(layer_name)
Expand All @@ -248,6 +277,7 @@ def testWFSPointsMultipleEdits(self):
Adds some points, then check.
Modify 2 points, then checks and clear all
"""

layer_name = 'test_point'
layer = self._getLayer(layer_name)
wfs_layer = self._getWFSLayer(layer_name)
Expand Down Expand Up @@ -276,50 +306,64 @@ def testWFSPolygons(self):
"""
Adds some polygons, then check and clear all
"""

layer_name = 'test_polygon'
layer = self._getLayer(layer_name)
wfs_layer = self._getWFSLayer(layer_name)
feat1 = QgsFeature(wfs_layer.fields())
feat1['id'] = 11
feat1['name'] = 'name 11'
feat1.setGeometry(QgsGeometry.fromRect(QgsRectangle(QgsPointXY(9, 45), QgsPointXY(10, 46))))
feat1.setGeometry(QgsGeometry.fromRect(
QgsRectangle(QgsPointXY(9, 45), QgsPointXY(10, 46))))
feat2 = QgsFeature(wfs_layer.fields())
feat2.setGeometry(QgsGeometry.fromRect(QgsRectangle(QgsPointXY(9.5, 45.5), QgsPointXY(10.5, 46.5))))
feat2.setGeometry(QgsGeometry.fromRect(QgsRectangle(
QgsPointXY(9.5, 45.5), QgsPointXY(10.5, 46.5))))
feat2['id'] = 12
feat2['name'] = 'name 12'
old_features = [feat1, feat2]
# Change feat1
new_feat1 = QgsFeature(wfs_layer.fields())
new_feat1['id'] = 121
new_feat1['name'] = 'name 121'
new_feat1.setGeometry(QgsGeometry.fromRect(QgsRectangle(QgsPointXY(10, 46), QgsPointXY(11.5, 47.5))))
new_feat1.setGeometry(QgsGeometry.fromRect(
QgsRectangle(QgsPointXY(10, 46), QgsPointXY(11.5, 47.5))))
new_features = [new_feat1, feat2]
self._testLayer(wfs_layer, layer, old_features, new_features)

def testWFSLineStrings(self):
"""
Adds some lines, then check and clear all
"""

layer_name = 'test_linestring'
layer = self._getLayer(layer_name)
wfs_layer = self._getWFSLayer(layer_name)
feat1 = QgsFeature(wfs_layer.fields())
feat1['id'] = 11
feat1['name'] = 'name 11'
feat1.setGeometry(QgsGeometry.fromPolylineXY([QgsPointXY(9, 45), QgsPointXY(10, 46)]))
feat1.setGeometry(QgsGeometry.fromPolylineXY(
[QgsPointXY(9, 45), QgsPointXY(10, 46)]))
feat2 = QgsFeature(wfs_layer.fields())
feat2.setGeometry(QgsGeometry.fromPolylineXY([QgsPointXY(9.5, 45.5), QgsPointXY(10.5, 46.5)]))
feat2.setGeometry(QgsGeometry.fromPolylineXY(
[QgsPointXY(9.5, 45.5), QgsPointXY(10.5, 46.5)]))
feat2['id'] = 12
feat2['name'] = 'name 12'
old_features = [feat1, feat2]
# Change feat1
new_feat1 = QgsFeature(wfs_layer.fields())
new_feat1['id'] = 121
new_feat1['name'] = 'name 121'
new_feat1.setGeometry(QgsGeometry.fromPolylineXY([QgsPointXY(9.8, 45.8), QgsPointXY(10.8, 46.8)]))
new_feat1.setGeometry(QgsGeometry.fromPolylineXY(
[QgsPointXY(9.8, 45.8), QgsPointXY(10.8, 46.8)]))
new_features = [new_feat1, feat2]
self._testLayer(wfs_layer, layer, old_features, new_features)


class TestWFST11(TestWFST):
"""Same tests for WFS 1.1"""

VERSION = '1.1.0'


if __name__ == '__main__':
unittest.main()

0 comments on commit 9edf482

Please sign in to comment.