Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[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.
  • Loading branch information
elpaso committed Mar 11, 2018
1 parent 5281c84 commit 59e68d9
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 48 deletions.
5 changes: 5 additions & 0 deletions src/server/services/wms/qgswmsparameters.cpp
Expand Up @@ -1209,6 +1209,11 @@ namespace QgsWms
return value( ParameterName::INFO_FORMAT ).toString();
}

bool QgsWmsParameters::infoFormatIsImage() const
{
return infoFormat() == Format::PNG || infoFormat() == Format::JPG;
}

QgsWmsParameters::Format QgsWmsParameters::infoFormat() const
{
QString fStr = infoFormatAsString();
Expand Down
6 changes: 6 additions & 0 deletions src/server/services/wms/qgswmsparameters.h
Expand Up @@ -333,6 +333,12 @@ namespace QgsWms
*/
QString infoFormatAsString() const;

/**
* Check if INFO_FORMAT parameter is one of the image formats (PNG, JPG).
* \returns true if the INFO_FORMAT is an image format
*/
bool infoFormatIsImage() const;

/**
* Returns infoFormat. If the INFO_FORMAT parameter is not used, then the
* default value is text/plain.
Expand Down
28 changes: 19 additions & 9 deletions src/server/services/wms/qgswmsrenderer.cpp
Expand Up @@ -882,6 +882,13 @@ namespace QgsWms
QStringLiteral( "I/J parameters are required for GetFeatureInfo" ) );
}

QgsWmsParameters::Format infoFormat = mWmsParameters.infoFormat();
if ( infoFormat == QgsWmsParameters::Format::NONE )
{
throw QgsBadRequestException( QStringLiteral( "InvalidFormat" ),
QStringLiteral( "Invalid INFO_FORMAT parameter" ) );
}

// get layers parameters
QList<QgsMapLayer *> layers;
QList<QgsWmsParametersLayer> params = mWmsParameters.layersParameters();
Expand All @@ -908,8 +915,18 @@ namespace QgsWms
}

// create the mapSettings and the output image
int imageWidth = mWmsParameters.widthAsInt();
int imageHeight = mWmsParameters.heightAsInt();

// Provide default image width/height values if format is not image
if ( !( imageWidth && imageHeight ) && ! mWmsParameters.infoFormatIsImage() )
{
imageWidth = 10;
imageHeight = 10;
}

QgsMapSettings mapSettings;
std::unique_ptr<QImage> outputImage( createImage() );
std::unique_ptr<QImage> outputImage( createImage( imageWidth, imageHeight ) );

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

QByteArray ba;

QgsWmsParameters::Format infoFormat = mWmsParameters.infoFormat();

if ( infoFormat == QgsWmsParameters::Format::NONE )
{
throw QgsBadRequestException( QStringLiteral( "InvalidFormat" ),
QStringLiteral( "Invalid INFO_FORMAT parameter" ) );
}
else if ( infoFormat == QgsWmsParameters::Format::TEXT )
if ( infoFormat == QgsWmsParameters::Format::TEXT )
ba = convertFeatureInfoToText( result );
else if ( infoFormat == QgsWmsParameters::Format::HTML )
ba = convertFeatureInfoToHtml( result );
Expand Down
90 changes: 51 additions & 39 deletions tests/src/python/test_qgsserver_wms_getfeatureinfo.py
Expand Up @@ -115,45 +115,6 @@ def testGetFeatureInfo(self):
'info_format=InvalidFormat',
'wms_getfeatureinfo-invalid-format')

# Regression for #8656
# Mind the gap! (the space in the FILTER expression)
self.wms_request_compare('GetFeatureInfo',
'&layers=testlayer%20%C3%A8%C3%A9&' +
'INFO_FORMAT=text%2Fxml&' +
'width=600&height=400&srs=EPSG%3A3857&' +
'query_layers=testlayer%20%C3%A8%C3%A9&' +
'FEATURE_COUNT=10&FILTER=testlayer%20%C3%A8%C3%A9' + urllib.parse.quote(':"NAME" = \'two\''),
'wms_getfeatureinfo_filter')

# Test a filter with NO condition results
self.wms_request_compare('GetFeatureInfo',
'&layers=testlayer%20%C3%A8%C3%A9&' +
'INFO_FORMAT=text%2Fxml&' +
'width=600&height=400&srs=EPSG%3A3857&' +
'query_layers=testlayer%20%C3%A8%C3%A9&' +
'FEATURE_COUNT=10&FILTER=testlayer%20%C3%A8%C3%A9' + urllib.parse.quote(':"NAME" = \'two\' AND "utf8nameè" = \'no-results\''),
'wms_getfeatureinfo_filter_no_results')

# Test a filter with OR condition results
self.wms_request_compare('GetFeatureInfo',
'&layers=testlayer%20%C3%A8%C3%A9&' +
'INFO_FORMAT=text%2Fxml&' +
'width=600&height=400&srs=EPSG%3A3857&' +
'query_layers=testlayer%20%C3%A8%C3%A9&' +
'FEATURE_COUNT=10&FILTER=testlayer%20%C3%A8%C3%A9' + urllib.parse.quote(':"NAME" = \'two\' OR "NAME" = \'three\''),
'wms_getfeatureinfo_filter_or')

# Test a filter with OR condition and UTF results
# Note that the layer name that contains utf-8 chars cannot be
# to upper case.
self.wms_request_compare('GetFeatureInfo',
'&layers=testlayer%20%C3%A8%C3%A9&' +
'INFO_FORMAT=text%2Fxml&' +
'width=600&height=400&srs=EPSG%3A3857&' +
'query_layers=testlayer%20%C3%A8%C3%A9&' +
'FEATURE_COUNT=10&FILTER=testlayer%20%C3%A8%C3%A9' + urllib.parse.quote(':"NAME" = \'two\' OR "utf8nameè" = \'three èé↓\''),
'wms_getfeatureinfo_filter_or_utf8')

# Test feature info request with filter geometry
self.wms_request_compare('GetFeatureInfo',
'&layers=testlayer%20%C3%A8%C3%A9&' +
Expand Down Expand Up @@ -206,6 +167,57 @@ def testGetFeatureInfo(self):
'wms_getfeatureinfo_notvisible',
'test_project_scalevisibility.qgs')

def testGetFeatureInfoFilter(self):
# Test getfeatureinfo response xml

# Regression for #8656
# Mind the gap! (the space in the FILTER expression)
self.wms_request_compare('GetFeatureInfo',
'&layers=testlayer%20%C3%A8%C3%A9&' +
'INFO_FORMAT=text%2Fxml&' +
'width=600&height=400&srs=EPSG%3A3857&' +
'query_layers=testlayer%20%C3%A8%C3%A9&' +
'FEATURE_COUNT=10&FILTER=testlayer%20%C3%A8%C3%A9' + urllib.parse.quote(':"NAME" = \'two\''),
'wms_getfeatureinfo_filter')

# Test a filter with NO condition results
self.wms_request_compare('GetFeatureInfo',
'&layers=testlayer%20%C3%A8%C3%A9&' +
'INFO_FORMAT=text%2Fxml&' +
'width=600&height=400&srs=EPSG%3A3857&' +
'query_layers=testlayer%20%C3%A8%C3%A9&' +
'FEATURE_COUNT=10&FILTER=testlayer%20%C3%A8%C3%A9' + urllib.parse.quote(':"NAME" = \'two\' AND "utf8nameè" = \'no-results\''),
'wms_getfeatureinfo_filter_no_results')

# Test a filter with OR condition results
self.wms_request_compare('GetFeatureInfo',
'&layers=testlayer%20%C3%A8%C3%A9&' +
'INFO_FORMAT=text%2Fxml&' +
'width=600&height=400&srs=EPSG%3A3857&' +
'query_layers=testlayer%20%C3%A8%C3%A9&' +
'FEATURE_COUNT=10&FILTER=testlayer%20%C3%A8%C3%A9' + urllib.parse.quote(':"NAME" = \'two\' OR "NAME" = \'three\''),
'wms_getfeatureinfo_filter_or')

# Test a filter with OR condition and UTF results
# Note that the layer name that contains utf-8 chars cannot be
# to upper case.
self.wms_request_compare('GetFeatureInfo',
'&layers=testlayer%20%C3%A8%C3%A9&' +
'INFO_FORMAT=text%2Fxml&' +
'width=600&height=400&srs=EPSG%3A3857&' +
'query_layers=testlayer%20%C3%A8%C3%A9&' +
'FEATURE_COUNT=10&FILTER=testlayer%20%C3%A8%C3%A9' + urllib.parse.quote(':"NAME" = \'two\' OR "utf8nameè" = \'three èé↓\''),
'wms_getfeatureinfo_filter_or_utf8')

# Regression #18292 Server GetFeatureInfo FILTER search fails when WIDTH, HEIGHT are not specified
self.wms_request_compare('GetFeatureInfo',
'&layers=testlayer%20%C3%A8%C3%A9&' +
'INFO_FORMAT=text%2Fxml&' +
'srs=EPSG%3A3857&' +
'query_layers=testlayer%20%C3%A8%C3%A9&' +
'FEATURE_COUNT=10&FILTER=testlayer%20%C3%A8%C3%A9' + urllib.parse.quote(':"NAME" = \'two\''),
'wms_getfeatureinfo_filter_no_width')


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

0 comments on commit 59e68d9

Please sign in to comment.