Skip to content

Commit 59e68d9

Browse files
committed
[server][bugfix] accept getfeatureinfo filter without h/w
When INFO_FORMAT is not an image format there is no need to make image WIDTH and HEIGHT mandatory. 2.x accepted that, 3.x raised an exception. This is a partial fix: SRS is still mandatory because fixing this would require a deeper refactoring and I believe we can live with it, because SRS will be required if filters are combined with geometry filters, while passing a WIDTH/HEIGHT when we don't want an image back is always useless. A test was also added.
1 parent 5281c84 commit 59e68d9

File tree

4 files changed

+81
-48
lines changed

4 files changed

+81
-48
lines changed

src/server/services/wms/qgswmsparameters.cpp

+5
Original file line numberDiff line numberDiff line change
@@ -1209,6 +1209,11 @@ namespace QgsWms
12091209
return value( ParameterName::INFO_FORMAT ).toString();
12101210
}
12111211

1212+
bool QgsWmsParameters::infoFormatIsImage() const
1213+
{
1214+
return infoFormat() == Format::PNG || infoFormat() == Format::JPG;
1215+
}
1216+
12121217
QgsWmsParameters::Format QgsWmsParameters::infoFormat() const
12131218
{
12141219
QString fStr = infoFormatAsString();

src/server/services/wms/qgswmsparameters.h

+6
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,12 @@ namespace QgsWms
333333
*/
334334
QString infoFormatAsString() const;
335335

336+
/**
337+
* Check if INFO_FORMAT parameter is one of the image formats (PNG, JPG).
338+
* \returns true if the INFO_FORMAT is an image format
339+
*/
340+
bool infoFormatIsImage() const;
341+
336342
/**
337343
* Returns infoFormat. If the INFO_FORMAT parameter is not used, then the
338344
* default value is text/plain.

src/server/services/wms/qgswmsrenderer.cpp

+19-9
Original file line numberDiff line numberDiff line change
@@ -882,6 +882,13 @@ namespace QgsWms
882882
QStringLiteral( "I/J parameters are required for GetFeatureInfo" ) );
883883
}
884884

885+
QgsWmsParameters::Format infoFormat = mWmsParameters.infoFormat();
886+
if ( infoFormat == QgsWmsParameters::Format::NONE )
887+
{
888+
throw QgsBadRequestException( QStringLiteral( "InvalidFormat" ),
889+
QStringLiteral( "Invalid INFO_FORMAT parameter" ) );
890+
}
891+
885892
// get layers parameters
886893
QList<QgsMapLayer *> layers;
887894
QList<QgsWmsParametersLayer> params = mWmsParameters.layersParameters();
@@ -908,8 +915,18 @@ namespace QgsWms
908915
}
909916

910917
// create the mapSettings and the output image
918+
int imageWidth = mWmsParameters.widthAsInt();
919+
int imageHeight = mWmsParameters.heightAsInt();
920+
921+
// Provide default image width/height values if format is not image
922+
if ( !( imageWidth && imageHeight ) && ! mWmsParameters.infoFormatIsImage() )
923+
{
924+
imageWidth = 10;
925+
imageHeight = 10;
926+
}
927+
911928
QgsMapSettings mapSettings;
912-
std::unique_ptr<QImage> outputImage( createImage() );
929+
std::unique_ptr<QImage> outputImage( createImage( imageWidth, imageHeight ) );
913930

914931
// configure map settings (background, DPI, ...)
915932
configureMapSettings( outputImage.get(), mapSettings );
@@ -953,14 +970,7 @@ namespace QgsWms
953970

954971
QByteArray ba;
955972

956-
QgsWmsParameters::Format infoFormat = mWmsParameters.infoFormat();
957-
958-
if ( infoFormat == QgsWmsParameters::Format::NONE )
959-
{
960-
throw QgsBadRequestException( QStringLiteral( "InvalidFormat" ),
961-
QStringLiteral( "Invalid INFO_FORMAT parameter" ) );
962-
}
963-
else if ( infoFormat == QgsWmsParameters::Format::TEXT )
973+
if ( infoFormat == QgsWmsParameters::Format::TEXT )
964974
ba = convertFeatureInfoToText( result );
965975
else if ( infoFormat == QgsWmsParameters::Format::HTML )
966976
ba = convertFeatureInfoToHtml( result );

tests/src/python/test_qgsserver_wms_getfeatureinfo.py

+51-39
Original file line numberDiff line numberDiff line change
@@ -115,45 +115,6 @@ def testGetFeatureInfo(self):
115115
'info_format=InvalidFormat',
116116
'wms_getfeatureinfo-invalid-format')
117117

118-
# Regression for #8656
119-
# Mind the gap! (the space in the FILTER expression)
120-
self.wms_request_compare('GetFeatureInfo',
121-
'&layers=testlayer%20%C3%A8%C3%A9&' +
122-
'INFO_FORMAT=text%2Fxml&' +
123-
'width=600&height=400&srs=EPSG%3A3857&' +
124-
'query_layers=testlayer%20%C3%A8%C3%A9&' +
125-
'FEATURE_COUNT=10&FILTER=testlayer%20%C3%A8%C3%A9' + urllib.parse.quote(':"NAME" = \'two\''),
126-
'wms_getfeatureinfo_filter')
127-
128-
# Test a filter with NO condition results
129-
self.wms_request_compare('GetFeatureInfo',
130-
'&layers=testlayer%20%C3%A8%C3%A9&' +
131-
'INFO_FORMAT=text%2Fxml&' +
132-
'width=600&height=400&srs=EPSG%3A3857&' +
133-
'query_layers=testlayer%20%C3%A8%C3%A9&' +
134-
'FEATURE_COUNT=10&FILTER=testlayer%20%C3%A8%C3%A9' + urllib.parse.quote(':"NAME" = \'two\' AND "utf8nameè" = \'no-results\''),
135-
'wms_getfeatureinfo_filter_no_results')
136-
137-
# Test a filter with OR condition results
138-
self.wms_request_compare('GetFeatureInfo',
139-
'&layers=testlayer%20%C3%A8%C3%A9&' +
140-
'INFO_FORMAT=text%2Fxml&' +
141-
'width=600&height=400&srs=EPSG%3A3857&' +
142-
'query_layers=testlayer%20%C3%A8%C3%A9&' +
143-
'FEATURE_COUNT=10&FILTER=testlayer%20%C3%A8%C3%A9' + urllib.parse.quote(':"NAME" = \'two\' OR "NAME" = \'three\''),
144-
'wms_getfeatureinfo_filter_or')
145-
146-
# Test a filter with OR condition and UTF results
147-
# Note that the layer name that contains utf-8 chars cannot be
148-
# to upper case.
149-
self.wms_request_compare('GetFeatureInfo',
150-
'&layers=testlayer%20%C3%A8%C3%A9&' +
151-
'INFO_FORMAT=text%2Fxml&' +
152-
'width=600&height=400&srs=EPSG%3A3857&' +
153-
'query_layers=testlayer%20%C3%A8%C3%A9&' +
154-
'FEATURE_COUNT=10&FILTER=testlayer%20%C3%A8%C3%A9' + urllib.parse.quote(':"NAME" = \'two\' OR "utf8nameè" = \'three èé↓\''),
155-
'wms_getfeatureinfo_filter_or_utf8')
156-
157118
# Test feature info request with filter geometry
158119
self.wms_request_compare('GetFeatureInfo',
159120
'&layers=testlayer%20%C3%A8%C3%A9&' +
@@ -206,6 +167,57 @@ def testGetFeatureInfo(self):
206167
'wms_getfeatureinfo_notvisible',
207168
'test_project_scalevisibility.qgs')
208169

170+
def testGetFeatureInfoFilter(self):
171+
# Test getfeatureinfo response xml
172+
173+
# Regression for #8656
174+
# Mind the gap! (the space in the FILTER expression)
175+
self.wms_request_compare('GetFeatureInfo',
176+
'&layers=testlayer%20%C3%A8%C3%A9&' +
177+
'INFO_FORMAT=text%2Fxml&' +
178+
'width=600&height=400&srs=EPSG%3A3857&' +
179+
'query_layers=testlayer%20%C3%A8%C3%A9&' +
180+
'FEATURE_COUNT=10&FILTER=testlayer%20%C3%A8%C3%A9' + urllib.parse.quote(':"NAME" = \'two\''),
181+
'wms_getfeatureinfo_filter')
182+
183+
# Test a filter with NO condition results
184+
self.wms_request_compare('GetFeatureInfo',
185+
'&layers=testlayer%20%C3%A8%C3%A9&' +
186+
'INFO_FORMAT=text%2Fxml&' +
187+
'width=600&height=400&srs=EPSG%3A3857&' +
188+
'query_layers=testlayer%20%C3%A8%C3%A9&' +
189+
'FEATURE_COUNT=10&FILTER=testlayer%20%C3%A8%C3%A9' + urllib.parse.quote(':"NAME" = \'two\' AND "utf8nameè" = \'no-results\''),
190+
'wms_getfeatureinfo_filter_no_results')
191+
192+
# Test a filter with OR condition results
193+
self.wms_request_compare('GetFeatureInfo',
194+
'&layers=testlayer%20%C3%A8%C3%A9&' +
195+
'INFO_FORMAT=text%2Fxml&' +
196+
'width=600&height=400&srs=EPSG%3A3857&' +
197+
'query_layers=testlayer%20%C3%A8%C3%A9&' +
198+
'FEATURE_COUNT=10&FILTER=testlayer%20%C3%A8%C3%A9' + urllib.parse.quote(':"NAME" = \'two\' OR "NAME" = \'three\''),
199+
'wms_getfeatureinfo_filter_or')
200+
201+
# Test a filter with OR condition and UTF results
202+
# Note that the layer name that contains utf-8 chars cannot be
203+
# to upper case.
204+
self.wms_request_compare('GetFeatureInfo',
205+
'&layers=testlayer%20%C3%A8%C3%A9&' +
206+
'INFO_FORMAT=text%2Fxml&' +
207+
'width=600&height=400&srs=EPSG%3A3857&' +
208+
'query_layers=testlayer%20%C3%A8%C3%A9&' +
209+
'FEATURE_COUNT=10&FILTER=testlayer%20%C3%A8%C3%A9' + urllib.parse.quote(':"NAME" = \'two\' OR "utf8nameè" = \'three èé↓\''),
210+
'wms_getfeatureinfo_filter_or_utf8')
211+
212+
# Regression #18292 Server GetFeatureInfo FILTER search fails when WIDTH, HEIGHT are not specified
213+
self.wms_request_compare('GetFeatureInfo',
214+
'&layers=testlayer%20%C3%A8%C3%A9&' +
215+
'INFO_FORMAT=text%2Fxml&' +
216+
'srs=EPSG%3A3857&' +
217+
'query_layers=testlayer%20%C3%A8%C3%A9&' +
218+
'FEATURE_COUNT=10&FILTER=testlayer%20%C3%A8%C3%A9' + urllib.parse.quote(':"NAME" = \'two\''),
219+
'wms_getfeatureinfo_filter_no_width')
220+
209221

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

0 commit comments

Comments
 (0)