Skip to content

Commit b494858

Browse files
authored
Merge pull request #7776 from pvalsecc/empty_filter
[Server] Add support for empty OGC WMS filters
2 parents a80117b + da58c1d commit b494858

File tree

2 files changed

+60
-22
lines changed

2 files changed

+60
-22
lines changed

src/server/services/wms/qgswmsparameters.cpp

+39-22
Original file line numberDiff line numberDiff line change
@@ -1167,29 +1167,46 @@ namespace QgsWms
11671167
QStringList QgsWmsParameters::filters() const
11681168
{
11691169
const QString filter = mWmsParameters[ QgsWmsParameter::FILTER ].toString();
1170-
if ( filter.startsWith( QStringLiteral( "(<" ) ) && filter.endsWith( QStringLiteral( "Filter>)" ) ) )
1170+
QStringList results;
1171+
int pos = 0;
1172+
while ( pos < filter.size() )
11711173
{
1172-
// OGC filter on multiple layers
1173-
// remove the "(<" at the beginning and the "Filter>)" at the end
1174-
const QString toSplit = filter.mid( 2, filter.length() - 10 );
1175-
1176-
QStringList result;
1177-
for ( const QString &cur : toSplit.split( QStringLiteral( "Filter>)(<" ), QString::SkipEmptyParts ) )
1174+
if ( pos + 1 < filter.size() && filter[pos] == '(' && filter[pos + 1] == '<' )
11781175
{
1179-
result.append( QStringLiteral( "<" ) + cur + QStringLiteral( "Filter>" ) );
1176+
// OGC filter on multiple layers
1177+
int posEnd = filter.indexOf( "Filter>)", pos );
1178+
if ( posEnd < 0 )
1179+
{
1180+
posEnd = filter.size();
1181+
}
1182+
results.append( filter.mid( pos + 1, posEnd - pos + 6 ) );
1183+
pos = posEnd + 8;
1184+
}
1185+
else if ( pos + 1 < filter.size() && filter[pos] == '(' && filter[pos + 1] == ')' )
1186+
{
1187+
// empty OGC filter
1188+
results.append( "" );
1189+
pos += 2;
1190+
}
1191+
else if ( filter[pos] == '<' )
1192+
{
1193+
// Single OGC filter
1194+
results.append( filter.mid( pos ) );
1195+
break;
1196+
}
1197+
else
1198+
{
1199+
// QGIS specific filter
1200+
int posEnd = filter.indexOf( ';', pos + 1 );
1201+
if ( posEnd < 0 )
1202+
{
1203+
posEnd = filter.size();
1204+
}
1205+
results.append( filter.mid( pos, posEnd - pos ) );
1206+
pos = posEnd + 1;
11801207
}
1181-
return result;
1182-
}
1183-
else if ( filter.startsWith( QStringLiteral( "<" ) ) && filter.endsWith( QStringLiteral( "Filter>" ) ) )
1184-
{
1185-
// single OGC filter
1186-
return QStringList( filter );
1187-
}
1188-
else
1189-
{
1190-
// QGIS specific filter
1191-
return filter.split( ';', QString::SkipEmptyParts );
11921208
}
1209+
return results;
11931210
}
11941211

11951212
QString QgsWmsParameters::filterGeom() const
@@ -1233,8 +1250,6 @@ namespace QgsWms
12331250

12341251
QMultiMap<QString, QString> QgsWmsParameters::getLayerFilters( const QStringList &layers ) const
12351252
{
1236-
// filter format: "LayerName:filterString;LayerName2:filterString2;..."
1237-
// several filters can be defined for one layer
12381253
const QStringList rawFilters = filters();
12391254
QMultiMap<QString, QString> layerFilters;
12401255
for ( int i = 0; i < rawFilters.size(); i++ )
@@ -1244,8 +1259,10 @@ namespace QgsWms
12441259
{
12451260
layerFilters.insert( layers[i], f );
12461261
}
1247-
else
1262+
else if ( !f.isEmpty() )
12481263
{
1264+
// filter format: "LayerName:filterString;LayerName2:filterString2;..."
1265+
// several filters can be defined for one layer
12491266
const QStringList splits = f.split( ':' );
12501267
if ( splits.size() == 2 )
12511268
{

tests/src/python/test_qgsserver_wms_getmap.py

+21
Original file line numberDiff line numberDiff line change
@@ -800,6 +800,27 @@ def test_wms_getmap_filter_ogc(self):
800800
r, h = self._result(self._execute_request(qs))
801801
self._img_diff_error(r, h, "WMS_GetMap_Filter_OGC")
802802

803+
def test_wms_getmap_filter_ogc_with_empty(self):
804+
filter = "(<Filter><PropertyIsEqualTo><PropertyName>name</PropertyName>" + \
805+
"<Literal>eurasia</Literal></PropertyIsEqualTo></Filter>)()"
806+
qs = "?" + "&".join(["%s=%s" % i for i in list({
807+
"MAP": urllib.parse.quote(self.projectPath),
808+
"SERVICE": "WMS",
809+
"VERSION": "1.1.1",
810+
"REQUEST": "GetMap",
811+
"LAYERS": "Country,Hello",
812+
"STYLES": "",
813+
"FORMAT": "image/png",
814+
"BBOX": "-16817707,-4710778,5696513,14587125",
815+
"HEIGHT": "500",
816+
"WIDTH": "500",
817+
"CRS": "EPSG:3857",
818+
"FILTER": filter
819+
}.items())])
820+
821+
r, h = self._result(self._execute_request(qs))
822+
self._img_diff_error(r, h, "WMS_GetMap_Filter_OGC")
823+
803824
def test_wms_getmap_selection(self):
804825
qs = "?" + "&".join(["%s=%s" % i for i in list({
805826
"MAP": urllib.parse.quote(self.projectPath),

0 commit comments

Comments
 (0)