From 186a5eb5071d0d4f31a22a29a63cac2633f85af8 Mon Sep 17 00:00:00 2001 From: Blottiere Paul Date: Thu, 13 Sep 2018 15:31:20 +0100 Subject: [PATCH 1/3] [server] Add support for OGC FE version 2 in GetMap request --- src/server/services/wms/qgswmsparameters.cpp | 40 ++++++++++++++------ src/server/services/wms/qgswmsparameters.h | 20 +++++++++- src/server/services/wms/qgswmsrenderer.cpp | 20 +++++----- src/server/services/wms/qgswmsrenderer.h | 2 +- 4 files changed, 58 insertions(+), 24 deletions(-) diff --git a/src/server/services/wms/qgswmsparameters.cpp b/src/server/services/wms/qgswmsparameters.cpp index dc237dabf231..2993b2c37d0e 100644 --- a/src/server/services/wms/qgswmsparameters.cpp +++ b/src/server/services/wms/qgswmsparameters.cpp @@ -1248,16 +1248,32 @@ namespace QgsWms return style << styles; } - QMultiMap QgsWmsParameters::getLayerFilters( const QStringList &layers ) const + QMultiMap QgsWmsParameters::layerFilters( const QStringList &layers ) const { + const QString nsWfs2 = QStringLiteral( "http://www.opengis.net/fes/2.0" ); + const QString prefixWfs2 = QStringLiteral( " layerFilters; + QMultiMap filters; for ( int i = 0; i < rawFilters.size(); i++ ) { const QString f = rawFilters[i]; - if ( f.startsWith( QLatin1String( "<" ) ) && f.endsWith( QLatin1String( "Filter>" ) ) && i < layers.size() ) + if ( f.startsWith( QLatin1String( "<" ) ) \ + && f.endsWith( QLatin1String( "Filter>" ) ) \ + && i < layers.size() ) { - layerFilters.insert( layers[i], f ); + QgsWmsParametersFilter filter; + filter.mFilter = f; + filter.mType = QgsWmsParametersFilter::OGC_FE; + filter.mVersion = QgsOgcUtils::FILTER_OGC_1_0; + + if ( filter.mFilter.contains( nsWfs2 ) \ + || filter.mFilter.contains( prefixWfs2 ) ) + { + filter.mVersion = QgsOgcUtils::FILTER_FES_2_0; + } + + filters.insert( layers[i], filter ); } else if ( !f.isEmpty() ) { @@ -1266,7 +1282,10 @@ namespace QgsWms const QStringList splits = f.split( ':' ); if ( splits.size() == 2 ) { - layerFilters.insert( splits[0], splits[1] ); + QgsWmsParametersFilter filter; + filter.mFilter = splits[1]; + filter.mType = QgsWmsParametersFilter::SQL; + filters.insert( splits[0], filter ); } else { @@ -1275,7 +1294,7 @@ namespace QgsWms } } } - return layerFilters; + return filters; } QList QgsWmsParameters::layersParameters() const @@ -1284,7 +1303,7 @@ namespace QgsWms const QStringList styles = allStyles(); const QStringList selection = selections(); const QList opacities = opacitiesAsInt(); - const QMultiMap layerFilters = getLayerFilters( layers ); + const QMultiMap filters = layerFilters( layers ); // selection format: "LayerName:id0,id1;LayerName2:id0,id1;..." // several filters can be defined for one layer @@ -1316,11 +1335,10 @@ namespace QgsWms if ( i < opacities.count() ) param.mOpacity = opacities[i]; - if ( layerFilters.contains( layer ) ) + if ( filters.contains( layer ) ) { - QMultiMap::const_iterator it; - it = layerFilters.find( layer ); - while ( it != layerFilters.end() && it.key() == layer ) + auto it = filters.find( layer ); + while ( it != filters.end() && it.key() == layer ) { param.mFilter.append( it.value() ); ++it; diff --git a/src/server/services/wms/qgswmsparameters.h b/src/server/services/wms/qgswmsparameters.h index 7fc2fec987d9..7c8cf32352e3 100644 --- a/src/server/services/wms/qgswmsparameters.h +++ b/src/server/services/wms/qgswmsparameters.h @@ -28,15 +28,31 @@ #include "qgsserverrequest.h" #include "qgslegendsettings.h" #include "qgsprojectversion.h" +#include "qgsogcutils.h" #include "qgsserverparameters.h" namespace QgsWms { + struct QgsWmsParametersFilter + { + //! Filter type + enum Type + { + UNKNOWN, + SQL, + OGC_FE + }; + + QString mFilter; + QgsWmsParametersFilter::Type mType = QgsWmsParametersFilter::UNKNOWN; + QgsOgcUtils::FilterVersion mVersion = QgsOgcUtils::FILTER_OGC_1_0; // only if FE + }; + struct QgsWmsParametersLayer { QString mNickname; // name, id or short name int mOpacity = -1; - QStringList mFilter; // list of filter + QList mFilter; // list of filter QStringList mSelection; // list of string fid QString mStyle; }; @@ -1125,7 +1141,7 @@ namespace QgsWms void raiseError( const QString &msg ) const; void log( const QString &msg ) const; - QMultiMap getLayerFilters( const QStringList &layers ) const; + QMultiMap layerFilters( const QStringList &layers ) const; QMap mWmsParameters; QMap > mExternalWMSParameters; diff --git a/src/server/services/wms/qgswmsrenderer.cpp b/src/server/services/wms/qgswmsrenderer.cpp index e454e7a8380a..37cbb937a26a 100644 --- a/src/server/services/wms/qgswmsrenderer.cpp +++ b/src/server/services/wms/qgswmsrenderer.cpp @@ -2795,35 +2795,35 @@ namespace QgsWms } } - void QgsRenderer::setLayerFilter( QgsMapLayer *layer, const QStringList &filters ) + void QgsRenderer::setLayerFilter( QgsMapLayer *layer, const QList &filters ) { if ( layer->type() == QgsMapLayer::VectorLayer ) { QgsVectorLayer *filteredLayer = qobject_cast( layer ); - for ( const QString &filter : filters ) + for ( const QgsWmsParametersFilter &filter : filters ) { - if ( filter.startsWith( QLatin1String( "<" ) ) && filter.endsWith( QLatin1String( "Filter>" ) ) ) + if ( filter.mType == QgsWmsParametersFilter::OGC_FE ) { // OGC filter QDomDocument filterXml; QString errorMsg; - if ( !filterXml.setContent( filter, true, &errorMsg ) ) + if ( !filterXml.setContent( filter.mFilter, true, &errorMsg ) ) { throw QgsBadRequestException( QStringLiteral( "Filter string rejected" ), - QStringLiteral( "error message: %1. The XML string was: %2" ).arg( errorMsg, filter ) ); + QStringLiteral( "error message: %1. The XML string was: %2" ).arg( errorMsg, filter.mFilter ) ); } QDomElement filterElem = filterXml.firstChildElement(); - std::unique_ptr expression( QgsOgcUtils::expressionFromOgcFilter( filterElem, filteredLayer ) ); + std::unique_ptr expression( QgsOgcUtils::expressionFromOgcFilter( filterElem, filter.mVersion, filteredLayer ) ); if ( expression ) { mFeatureFilter.setFilter( filteredLayer, *expression ); } } - else + else if ( filter.mType == QgsWmsParametersFilter::SQL ) { // QGIS (SQL) filter - if ( !testFilterStringSafety( filter ) ) + if ( !testFilterStringSafety( filter.mFilter ) ) { throw QgsBadRequestException( QStringLiteral( "Filter string rejected" ), QStringLiteral( "The filter string %1" @@ -2833,10 +2833,10 @@ namespace QgsWms " Allowed Keywords and special characters are " " AND,OR,IN,<,>=,>,>=,!=,',',(,),DMETAPHONE,SOUNDEX." " Not allowed are semicolons in the filter expression." ).arg( - filter ) ); + filter.mFilter ) ); } - QString newSubsetString = filter; + QString newSubsetString = filter.mFilter; if ( !filteredLayer->subsetString().isEmpty() ) { newSubsetString.prepend( ") AND (" ); diff --git a/src/server/services/wms/qgswmsrenderer.h b/src/server/services/wms/qgswmsrenderer.h index cbce08f4e606..a2ded0424285 100644 --- a/src/server/services/wms/qgswmsrenderer.h +++ b/src/server/services/wms/qgswmsrenderer.h @@ -162,7 +162,7 @@ namespace QgsWms void setLayerOpacity( QgsMapLayer *layer, int opacity ) const; // Set layer filter - void setLayerFilter( QgsMapLayer *layer, const QStringList &filter ); + void setLayerFilter( QgsMapLayer *layer, const QList &filters ); // Set layer python filter void setLayerAccessControlFilter( QgsMapLayer *layer ) const; From af9f3166fc31123bcb86a697099df6c914d7ff63 Mon Sep 17 00:00:00 2001 From: Blottiere Paul Date: Thu, 13 Sep 2018 15:31:51 +0100 Subject: [PATCH 2/3] Fixes segfault --- src/core/qgsogcutils.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/qgsogcutils.cpp b/src/core/qgsogcutils.cpp index a80872f1d63d..a1e9386fe760 100644 --- a/src/core/qgsogcutils.cpp +++ b/src/core/qgsogcutils.cpp @@ -3172,7 +3172,6 @@ QgsExpressionNodeBinaryOperator *QgsOgcUtilsExpressionFromFilter::nodeBinaryOper QDomElement operandElem = element.firstChildElement(); std::unique_ptr expr( nodeFromOgcFilter( operandElem ) ); - std::unique_ptr leftOp( expr->clone() ); if ( !expr ) { @@ -3180,6 +3179,7 @@ QgsExpressionNodeBinaryOperator *QgsOgcUtilsExpressionFromFilter::nodeBinaryOper return nullptr; } + std::unique_ptr leftOp( expr->clone() ); for ( operandElem = operandElem.nextSiblingElement(); !operandElem.isNull(); operandElem = operandElem.nextSiblingElement() ) { std::unique_ptr opRight( nodeFromOgcFilter( operandElem ) ); From d30f93ffe9d59d3dc358f41a810b0fd0adfed0f8 Mon Sep 17 00:00:00 2001 From: Blottiere Paul Date: Thu, 13 Sep 2018 15:32:13 +0100 Subject: [PATCH 3/3] Add unit tests --- tests/src/python/test_qgsserver_wms_getmap.py | 53 ++++++++++++++++++ .../WMS_GetMap_Filter_OGC_V2.png | Bin 0 -> 32766 bytes 2 files changed, 53 insertions(+) create mode 100644 tests/testdata/control_images/qgis_server/WMS_GetMap_Filter_OGC_V2/WMS_GetMap_Filter_OGC_V2.png diff --git a/tests/src/python/test_qgsserver_wms_getmap.py b/tests/src/python/test_qgsserver_wms_getmap.py index 53b5db6a378b..fb0ba9fa2824 100644 --- a/tests/src/python/test_qgsserver_wms_getmap.py +++ b/tests/src/python/test_qgsserver_wms_getmap.py @@ -866,6 +866,59 @@ def test_wms_getmap_filter_ogc_with_empty(self): r, h = self._result(self._execute_request(qs)) self._img_diff_error(r, h, "WMS_GetMap_Filter_OGC3") + def test_wms_getmap_filter_ogc_v2(self): + # with namespace + filter = ('' + '' + 'name' + 'eurasia' + '' + '') + + qs = "?" + "&".join(["%s=%s" % i for i in list({ + "MAP": urllib.parse.quote(self.projectPath), + "SERVICE": "WMS", + "VERSION": "1.1.1", + "REQUEST": "GetMap", + "LAYERS": "Country,Hello", + "STYLES": "", + "FORMAT": "image/png", + "BBOX": "-16817707,-4710778,5696513,14587125", + "HEIGHT": "500", + "WIDTH": "500", + "CRS": "EPSG:3857", + "FILTER": filter + }.items())]) + + r, h = self._result(self._execute_request(qs)) + self._img_diff_error(r, h, "WMS_GetMap_Filter_OGC_V2") + + # without namespace (only with prefix) + filter = ('' + '' + 'name' + 'eurasia' + '' + '') + + qs = "?" + "&".join(["%s=%s" % i for i in list({ + "MAP": urllib.parse.quote(self.projectPath), + "SERVICE": "WMS", + "VERSION": "1.1.1", + "REQUEST": "GetMap", + "LAYERS": "Country,Hello", + "STYLES": "", + "FORMAT": "image/png", + "BBOX": "-16817707,-4710778,5696513,14587125", + "HEIGHT": "500", + "WIDTH": "500", + "CRS": "EPSG:3857", + "FILTER": filter + }.items())]) + + r, h = self._result(self._execute_request(qs)) + self._img_diff_error(r, h, "WMS_GetMap_Filter_OGC_V2") + def test_wms_getmap_selection(self): qs = "?" + "&".join(["%s=%s" % i for i in list({ "MAP": urllib.parse.quote(self.projectPath), diff --git a/tests/testdata/control_images/qgis_server/WMS_GetMap_Filter_OGC_V2/WMS_GetMap_Filter_OGC_V2.png b/tests/testdata/control_images/qgis_server/WMS_GetMap_Filter_OGC_V2/WMS_GetMap_Filter_OGC_V2.png new file mode 100644 index 0000000000000000000000000000000000000000..12da8bb0ee552e85f18e200f43f3bb78db78df67 GIT binary patch literal 32766 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