From 1f2109a51f86e177f3994f97c3e8e1d93cfa1ac1 Mon Sep 17 00:00:00 2001 From: Alessandro Pasotti Date: Tue, 30 Jan 2018 17:02:08 +0100 Subject: [PATCH] [server][bugfix][wfs] Allow CRS in BBOX Fixes #17977 - QGIS server 2.99 doesn't handles BBOX parameter on WFS request --- src/server/services/wfs/qgswfsgetfeature.cpp | 31 +++++++++++++++++-- src/server/services/wfs/qgswfsparameters.cpp | 5 +-- tests/src/python/test_qgsserver_wfs.py | 25 +++++++++++++-- ...Feature_1_0_0_epsgbbox_1_feature_1_0_0.txt | 6 ++++ ...re_1_0_0_epsgbbox_1_feature_3857_1_0_0.txt | 6 ++++ ...Feature_1_0_0_epsgbbox_3_feature_1_0_0.txt | 6 ++++ ...re_1_0_0_epsgbbox_3_feature_3857_1_0_0.txt | 6 ++++ ...fs_getFeature_1_1_0_epsgbbox_1_feature.txt | 6 ++++ ...tFeature_1_1_0_epsgbbox_1_feature_3857.txt | 6 ++++ ...fs_getFeature_1_1_0_epsgbbox_3_feature.txt | 6 ++++ ...tFeature_1_1_0_epsgbbox_3_feature_3857.txt | 6 ++++ 11 files changed, 103 insertions(+), 6 deletions(-) create mode 100644 tests/testdata/qgis_server/wfs_getFeature_1_0_0_epsgbbox_1_feature_1_0_0.txt create mode 100644 tests/testdata/qgis_server/wfs_getFeature_1_0_0_epsgbbox_1_feature_3857_1_0_0.txt create mode 100644 tests/testdata/qgis_server/wfs_getFeature_1_0_0_epsgbbox_3_feature_1_0_0.txt create mode 100644 tests/testdata/qgis_server/wfs_getFeature_1_0_0_epsgbbox_3_feature_3857_1_0_0.txt create mode 100644 tests/testdata/qgis_server/wfs_getFeature_1_1_0_epsgbbox_1_feature.txt create mode 100644 tests/testdata/qgis_server/wfs_getFeature_1_1_0_epsgbbox_1_feature_3857.txt create mode 100644 tests/testdata/qgis_server/wfs_getFeature_1_1_0_epsgbbox_3_feature.txt create mode 100644 tests/testdata/qgis_server/wfs_getFeature_1_1_0_epsgbbox_3_feature_3857.txt diff --git a/src/server/services/wfs/qgswfsgetfeature.cpp b/src/server/services/wfs/qgswfsgetfeature.cpp index a7e43add489..30cef222b11 100644 --- a/src/server/services/wfs/qgswfsgetfeature.cpp +++ b/src/server/services/wfs/qgswfsgetfeature.cpp @@ -658,12 +658,39 @@ namespace QgsWfs if ( paramContainsBbox ) { - // get bbox corners - QString bbox = mWfsParameters.bbox(); // get bbox extent QgsRectangle extent = mWfsParameters.bboxAsRectangle(); + // handle WFS 1.1.0 optional CRS + if ( mWfsParameters.bbox().split( ',' ).size() == 5 && ! mWfsParameters.srsName().isEmpty() ) + { + QString crs( mWfsParameters.bbox().split( ',' )[4] ); + if ( crs != mWfsParameters.srsName() ) + { + QgsCoordinateReferenceSystem sourceCrs( crs ); + QgsCoordinateReferenceSystem destinationCrs( mWfsParameters.srsName() ); + if ( sourceCrs.isValid() && destinationCrs.isValid( ) ) + { + QgsGeometry extentGeom = QgsGeometry::fromRect( extent ); + QgsCoordinateTransform transform; + transform.setSourceCrs( sourceCrs ); + transform.setDestinationCrs( destinationCrs ); + try + { + if ( extentGeom.transform( transform ) == 0 ) + { + extent = QgsRectangle( extentGeom.boundingBox() ); + } + } + catch ( QgsException &cse ) + { + Q_UNUSED( cse ); + } + } + } + } + // set feature request filter rectangle QList::iterator qIt = request.queries.begin(); for ( ; qIt != request.queries.end(); ++qIt ) diff --git a/src/server/services/wfs/qgswfsparameters.cpp b/src/server/services/wfs/qgswfsparameters.cpp index 6de470e923c..0ce09c1650d 100644 --- a/src/server/services/wfs/qgswfsparameters.cpp +++ b/src/server/services/wfs/qgswfsparameters.cpp @@ -384,8 +384,8 @@ namespace QgsWfs if ( !bbox.isEmpty() ) { QStringList corners = bbox.split( ',' ); - - if ( corners.size() == 4 ) + // We need at least 4 elements, an optional fifth could be the CRS in WFS 1.1.0 BBOX + if ( corners.size() >= 4 ) { double d[4]; bool ok; @@ -402,6 +402,7 @@ namespace QgsWfs } extent = QgsRectangle( d[0], d[1], d[2], d[3] ); + } else { diff --git a/tests/src/python/test_qgsserver_wfs.py b/tests/src/python/test_qgsserver_wfs.py index f4b37d847e8..5b93c7354ff 100644 --- a/tests/src/python/test_qgsserver_wfs.py +++ b/tests/src/python/test_qgsserver_wfs.py @@ -44,18 +44,26 @@ class TestQgsServerWFS(QgsServerTestBase): """QGIS Server WFS Tests""" - def wfs_request_compare(self, request, version=''): + def wfs_request_compare(self, request, version='', extra_query_string='', reference_base_name=None): project = self.testdata_path + "test_project_wfs.qgs" assert os.path.exists(project), "Project file not found: " + project query_string = '?MAP=%s&SERVICE=WFS&REQUEST=%s' % (urllib.parse.quote(project), request) if version: query_string += '&VERSION=%s' % version + + if extra_query_string: + query_string += '&%s' % extra_query_string + header, body = self._execute_request(query_string) self.assert_headers(header, body) response = header + body - reference_name = 'wfs_' + request.lower() + if reference_base_name is not None: + reference_name = reference_base_name + else: + reference_name = 'wfs_' + request.lower() + if version == '1.0.0': reference_name += '_1_0_0' reference_name += '.txt' @@ -247,6 +255,19 @@ class TestQgsServerWFS(QgsServerTestBase): for id, req in tests: self.wfs_getfeature_post_compare(id, req) + def test_getFeatureBBOX(self): + """Test with (1.1.0) and without (1.0.0) CRS""" + + self.wfs_request_compare("GetFeature", '1.0.0', "SRSNAME=EPSG:4326&TYPENAME=testlayer&RESULTTYPE=hits&BBOX=8.20347,44.901471,8.2035354,44.901493,EPSG:4326", 'wfs_getFeature_1_0_0_epsgbbox_1_feature') + self.wfs_request_compare("GetFeature", '1.0.0', "SRSNAME=EPSG:4326&TYPENAME=testlayer&RESULTTYPE=hits&BBOX=8.203127,44.9012765,8.204138,44.901632,EPSG:4326", 'wfs_getFeature_1_0_0_epsgbbox_3_feature') + self.wfs_request_compare("GetFeature", '1.1.0', "SRSNAME=EPSG:4326&TYPENAME=testlayer&RESULTTYPE=hits&BBOX=8.20347,44.901471,8.2035354,44.901493,EPSG:4326", 'wfs_getFeature_1_1_0_epsgbbox_1_feature') + self.wfs_request_compare("GetFeature", '1.1.0', "SRSNAME=EPSG:4326&TYPENAME=testlayer&RESULTTYPE=hits&BBOX=8.203127,44.9012765,8.204138,44.901632,EPSG:4326", 'wfs_getFeature_1_1_0_epsgbbox_3_feature') + + self.wfs_request_compare("GetFeature", '1.0.0', "SRSNAME=EPSG:4326&TYPENAME=testlayer&RESULTTYPE=hits&BBOX=913144,5605992,913303,5606048,EPSG:3857", 'wfs_getFeature_1_0_0_epsgbbox_3_feature_3857') + self.wfs_request_compare("GetFeature", '1.0.0', "SRSNAME=EPSG:4326&TYPENAME=testlayer&RESULTTYPE=hits&BBOX=913206,5606024,913213,5606026,EPSG:3857", 'wfs_getFeature_1_0_0_epsgbbox_1_feature_3857') + self.wfs_request_compare("GetFeature", '1.1.0', "SRSNAME=EPSG:4326&TYPENAME=testlayer&RESULTTYPE=hits&BBOX=913144,5605992,913303,5606048,EPSG:3857", 'wfs_getFeature_1_1_0_epsgbbox_3_feature_3857') + self.wfs_request_compare("GetFeature", '1.1.0', "SRSNAME=EPSG:4326&TYPENAME=testlayer&RESULTTYPE=hits&BBOX=913206,5606024,913213,5606026,EPSG:3857", 'wfs_getFeature_1_1_0_epsgbbox_1_feature_3857') + if __name__ == '__main__': unittest.main() diff --git a/tests/testdata/qgis_server/wfs_getFeature_1_0_0_epsgbbox_1_feature_1_0_0.txt b/tests/testdata/qgis_server/wfs_getFeature_1_0_0_epsgbbox_1_feature_1_0_0.txt new file mode 100644 index 00000000000..4f442c74a03 --- /dev/null +++ b/tests/testdata/qgis_server/wfs_getFeature_1_0_0_epsgbbox_1_feature_1_0_0.txt @@ -0,0 +1,6 @@ +Content-Type: text/xml; subtype=gml/2.1.2; charset=utf-8 + + + \ No newline at end of file diff --git a/tests/testdata/qgis_server/wfs_getFeature_1_0_0_epsgbbox_1_feature_3857_1_0_0.txt b/tests/testdata/qgis_server/wfs_getFeature_1_0_0_epsgbbox_1_feature_3857_1_0_0.txt new file mode 100644 index 00000000000..4f442c74a03 --- /dev/null +++ b/tests/testdata/qgis_server/wfs_getFeature_1_0_0_epsgbbox_1_feature_3857_1_0_0.txt @@ -0,0 +1,6 @@ +Content-Type: text/xml; subtype=gml/2.1.2; charset=utf-8 + + + \ No newline at end of file diff --git a/tests/testdata/qgis_server/wfs_getFeature_1_0_0_epsgbbox_3_feature_1_0_0.txt b/tests/testdata/qgis_server/wfs_getFeature_1_0_0_epsgbbox_3_feature_1_0_0.txt new file mode 100644 index 00000000000..5a3cb2e19cb --- /dev/null +++ b/tests/testdata/qgis_server/wfs_getFeature_1_0_0_epsgbbox_3_feature_1_0_0.txt @@ -0,0 +1,6 @@ +Content-Type: text/xml; subtype=gml/2.1.2; charset=utf-8 + + + \ No newline at end of file diff --git a/tests/testdata/qgis_server/wfs_getFeature_1_0_0_epsgbbox_3_feature_3857_1_0_0.txt b/tests/testdata/qgis_server/wfs_getFeature_1_0_0_epsgbbox_3_feature_3857_1_0_0.txt new file mode 100644 index 00000000000..5a3cb2e19cb --- /dev/null +++ b/tests/testdata/qgis_server/wfs_getFeature_1_0_0_epsgbbox_3_feature_3857_1_0_0.txt @@ -0,0 +1,6 @@ +Content-Type: text/xml; subtype=gml/2.1.2; charset=utf-8 + + + \ No newline at end of file diff --git a/tests/testdata/qgis_server/wfs_getFeature_1_1_0_epsgbbox_1_feature.txt b/tests/testdata/qgis_server/wfs_getFeature_1_1_0_epsgbbox_1_feature.txt new file mode 100644 index 00000000000..abec008228d --- /dev/null +++ b/tests/testdata/qgis_server/wfs_getFeature_1_1_0_epsgbbox_1_feature.txt @@ -0,0 +1,6 @@ +Content-Type: text/xml; subtype=gml/3.1.1; charset=utf-8 + + + \ No newline at end of file diff --git a/tests/testdata/qgis_server/wfs_getFeature_1_1_0_epsgbbox_1_feature_3857.txt b/tests/testdata/qgis_server/wfs_getFeature_1_1_0_epsgbbox_1_feature_3857.txt new file mode 100644 index 00000000000..abec008228d --- /dev/null +++ b/tests/testdata/qgis_server/wfs_getFeature_1_1_0_epsgbbox_1_feature_3857.txt @@ -0,0 +1,6 @@ +Content-Type: text/xml; subtype=gml/3.1.1; charset=utf-8 + + + \ No newline at end of file diff --git a/tests/testdata/qgis_server/wfs_getFeature_1_1_0_epsgbbox_3_feature.txt b/tests/testdata/qgis_server/wfs_getFeature_1_1_0_epsgbbox_3_feature.txt new file mode 100644 index 00000000000..c5a67e329d8 --- /dev/null +++ b/tests/testdata/qgis_server/wfs_getFeature_1_1_0_epsgbbox_3_feature.txt @@ -0,0 +1,6 @@ +Content-Type: text/xml; subtype=gml/3.1.1; charset=utf-8 + + + \ No newline at end of file diff --git a/tests/testdata/qgis_server/wfs_getFeature_1_1_0_epsgbbox_3_feature_3857.txt b/tests/testdata/qgis_server/wfs_getFeature_1_1_0_epsgbbox_3_feature_3857.txt new file mode 100644 index 00000000000..c5a67e329d8 --- /dev/null +++ b/tests/testdata/qgis_server/wfs_getFeature_1_1_0_epsgbbox_3_feature_3857.txt @@ -0,0 +1,6 @@ +Content-Type: text/xml; subtype=gml/3.1.1; charset=utf-8 + + + \ No newline at end of file