Skip to content

Commit

Permalink
Merge pull request #38807 from pblottiere/gfi_null
Browse files Browse the repository at this point in the history
GetFeatureInfo and no data values
  • Loading branch information
pblottiere committed Sep 30, 2020
2 parents 09fc4ed + 5c74aee commit 8351e06
Show file tree
Hide file tree
Showing 14 changed files with 234 additions and 8 deletions.
31 changes: 27 additions & 4 deletions src/server/services/wms/qgswmsrenderer.cpp
Expand Up @@ -1774,7 +1774,14 @@ namespace QgsWms
{
QDomElement attributeElement = infoDocument.createElement( QStringLiteral( "Attribute" ) );
attributeElement.setAttribute( QStringLiteral( "name" ), layer->bandName( it.key() ) );
attributeElement.setAttribute( QStringLiteral( "value" ), QString::number( it.value().toDouble() ) );

QString value;
if ( ! it.value().isNull() )
{
value = QString::number( it.value().toDouble() );
}

attributeElement.setAttribute( QStringLiteral( "value" ), value );
layerElement.appendChild( attributeElement );
}
}
Expand Down Expand Up @@ -2119,8 +2126,13 @@ namespace QgsWms
for ( int j = 0; j < attributeNodeList.size(); ++j )
{
QDomElement attributeElement = attributeNodeList.at( j ).toElement();
QString value = attributeElement.attribute( QStringLiteral( "value" ) );
if ( value.isEmpty() )
{
value = QStringLiteral( "no data" );
}
featureInfoString.append( "<TR><TH>" + attributeElement.attribute( QStringLiteral( "name" ) ) +
"</TH><TD>" + attributeElement.attribute( QStringLiteral( "value" ) ) + "</TD></TR>\n" );
"</TH><TD>" + value + "</TD></TR>\n" );
}
}

Expand Down Expand Up @@ -2177,8 +2189,13 @@ namespace QgsWms
for ( int j = 0; j < attributeNodeList.size(); ++j )
{
QDomElement attributeElement = attributeNodeList.at( j ).toElement();
QString value = attributeElement.attribute( QStringLiteral( "value" ) );
if ( value.isEmpty() )
{
value = QStringLiteral( "no data" );
}
featureInfoString.append( attributeElement.attribute( QStringLiteral( "name" ) ) + " = '" +
attributeElement.attribute( QStringLiteral( "value" ) ) + "'\n" );
value + "'\n" );
}
}

Expand Down Expand Up @@ -2289,7 +2306,13 @@ namespace QgsWms
{
const QDomElement attrElmt = attributesNode.at( j ).toElement();
const QString name = attrElmt.attribute( QStringLiteral( "name" ) );
const QString value = attrElmt.attribute( QStringLiteral( "value" ) );

QString value = attrElmt.attribute( QStringLiteral( "value" ) );
if ( value.isEmpty() )
{
value = QStringLiteral( "null" );
}

properties[name.toStdString()] = value.toStdString();
}

Expand Down
4 changes: 2 additions & 2 deletions tests/src/python/test_qgsserver.py
Expand Up @@ -64,7 +64,7 @@ class QgsServerTestBase(unittest.TestCase):
# Set to True in child classes to re-generate reference files for this class
regenerate_reference = False

def assertXMLEqual(self, response, expected, msg=''):
def assertXMLEqual(self, response, expected, msg='', raw=False):
"""Compare XML line by line and sorted attributes"""
response_lines = response.splitlines()
expected_lines = expected.splitlines()
Expand All @@ -80,7 +80,7 @@ def assertXMLEqual(self, response, expected, msg=''):
response_line = response_lines[line_no - 1].strip()
response_line = response_line.replace(b'e+6', br'e+06')
# Compare tag
if re.match(RE_ELEMENT, expected_line):
if re.match(RE_ELEMENT, expected_line) and not raw:
expected_elements = re.findall(RE_ELEMENT, expected_line)
response_elements = re.findall(RE_ELEMENT, response_line)
self.assertEqual(expected_elements[0],
Expand Down
4 changes: 2 additions & 2 deletions tests/src/python/test_qgsserver_wms.py
Expand Up @@ -57,7 +57,7 @@ def wms_request(self, request, extra=None, project='test_project.qgs', version='
header, body = self._execute_request(query_string)
return (header, body, query_string)

def wms_request_compare(self, request, extra=None, reference_file=None, project='test_project.qgs', version='1.3.0', ignoreExtent=False, normalizeJson=False):
def wms_request_compare(self, request, extra=None, reference_file=None, project='test_project.qgs', version='1.3.0', ignoreExtent=False, normalizeJson=False, raw=False):
response_header, response_body, query_string = self.wms_request(request, extra, project, version)
response = response_header + response_body
reference_path = os.path.join(self.testdata_path, (request.lower() if not reference_file else reference_file) + '.txt')
Expand Down Expand Up @@ -85,7 +85,7 @@ def _n(r):
expected = re.sub(RE_STRIP_EXTENTS, b'*****', expected)

msg = "request %s failed.\nQuery: %s\nExpected file: %s\nResponse:\n%s" % (query_string, request, reference_path, response.decode('utf-8'))
self.assertXMLEqual(response, expected, msg=msg)
self.assertXMLEqual(response, expected, msg=msg, raw=raw)


class TestQgsServerWMS(TestQgsServerWMSTestBase):
Expand Down
133 changes: 133 additions & 0 deletions tests/src/python/test_qgsserver_wms_getfeatureinfo.py
Expand Up @@ -802,6 +802,139 @@ def testGetFeatureInfoCascadingLayers(self):
'wms_getfeatureinfo_cascading_issue31177',
project_name)

def testGetFeatureInfoRasterNoData(self):
# outside the image in text
self.wms_request_compare('GetFeatureInfo',
'&BBOX=-39.43236293126383885,135.95002698514588246,-30.54405018572365194,156.29582900705395332' +
'&CRS=EPSG:4326' +
'&VERSION=1.3.0' +
'&WIDTH=800&HEIGHT=400' +
'&LAYERS=requires_warped_vrt' +
'&QUERY_LAYERS=requires_warped_vrt' +
'&I=1&J=1' +
'&FEATURE_COUNT=10',
'wms_getfeatureinfo_raster_nodata_out_txt',
'test_raster_nodata.qgz',
raw=True)

# 0 text
self.wms_request_compare('GetFeatureInfo',
'&BBOX=-39.43236293126383885,135.95002698514588246,-30.54405018572365194,156.29582900705395332' +
'&CRS=EPSG:4326' +
'&VERSION=1.3.0' +
'&WIDTH=800&HEIGHT=400' +
'&LAYERS=requires_warped_vrt' +
'&QUERY_LAYERS=requires_warped_vrt' +
'&I=576&J=163' +
'&FEATURE_COUNT=10',
'wms_getfeatureinfo_raster_nodata_zero_txt',
'test_raster_nodata.qgz',
raw=True)

# nodata text
self.wms_request_compare('GetFeatureInfo',
'&BBOX=-39.43236293126383885,135.95002698514588246,-30.54405018572365194,156.29582900705395332' +
'&CRS=EPSG:4326' +
'&VERSION=1.3.0' +
'&WIDTH=800&HEIGHT=400' +
'&LAYERS=requires_warped_vrt' +
'&QUERY_LAYERS=requires_warped_vrt' +
'&I=560&J=78' +
'&FEATURE_COUNT=10',
'wms_getfeatureinfo_raster_nodata_txt',
'test_raster_nodata.qgz',
raw=True)

# outside the image in html
self.wms_request_compare('GetFeatureInfo',
'&BBOX=-39.43236293126383885,135.95002698514588246,-30.54405018572365194,156.29582900705395332' +
'&CRS=EPSG:4326' +
'&VERSION=1.3.0' +
'&INFO_FORMAT=text/html' +
'&WIDTH=800&HEIGHT=400' +
'&LAYERS=requires_warped_vrt' +
'&QUERY_LAYERS=requires_warped_vrt' +
'&I=1&J=1' +
'&FEATURE_COUNT=10',
'wms_getfeatureinfo_raster_nodata_out_html',
'test_raster_nodata.qgz',
raw=True)

# 0 html
self.wms_request_compare('GetFeatureInfo',
'&BBOX=-39.43236293126383885,135.95002698514588246,-30.54405018572365194,156.29582900705395332' +
'&CRS=EPSG:4326' +
'&VERSION=1.3.0' +
'&INFO_FORMAT=text/html' +
'&WIDTH=800&HEIGHT=400' +
'&LAYERS=requires_warped_vrt' +
'&QUERY_LAYERS=requires_warped_vrt' +
'&I=576&J=163' +
'&FEATURE_COUNT=10',
'wms_getfeatureinfo_raster_nodata_zero_html',
'test_raster_nodata.qgz',
raw=True)

# nodata html
self.wms_request_compare('GetFeatureInfo',
'&BBOX=-39.43236293126383885,135.95002698514588246,-30.54405018572365194,156.29582900705395332' +
'&CRS=EPSG:4326' +
'&VERSION=1.3.0' +
'&INFO_FORMAT=text/html' +
'&WIDTH=800&HEIGHT=400' +
'&LAYERS=requires_warped_vrt' +
'&QUERY_LAYERS=requires_warped_vrt' +
'&I=560&J=78' +
'&FEATURE_COUNT=10',
'wms_getfeatureinfo_raster_nodata_html',
'test_raster_nodata.qgz',
raw=True)

# outside the image in json
self.wms_request_compare('GetFeatureInfo',
'&BBOX=-39.43236293126383885,135.95002698514588246,-30.54405018572365194,156.29582900705395332' +
'&CRS=EPSG:4326' +
'&VERSION=1.3.0' +
'&INFO_FORMAT=application/json' +
'&WIDTH=800&HEIGHT=400' +
'&LAYERS=requires_warped_vrt' +
'&QUERY_LAYERS=requires_warped_vrt' +
'&I=1&J=1' +
'&FEATURE_COUNT=10',
'wms_getfeatureinfo_raster_nodata_out_json',
'test_raster_nodata.qgz',
raw=True)

# 0 json
self.wms_request_compare('GetFeatureInfo',
'&BBOX=-39.43236293126383885,135.95002698514588246,-30.54405018572365194,156.29582900705395332' +
'&CRS=EPSG:4326' +
'&VERSION=1.3.0' +
'&INFO_FORMAT=application/json' +
'&WIDTH=800&HEIGHT=400' +
'&LAYERS=requires_warped_vrt' +
'&QUERY_LAYERS=requires_warped_vrt' +
'&I=576&J=163' +
'&FEATURE_COUNT=10',
'wms_getfeatureinfo_raster_nodata_zero_json',
'test_raster_nodata.qgz',
raw=True)

# nodata json
self.wms_request_compare('GetFeatureInfo',
'&BBOX=-39.43236293126383885,135.95002698514588246,-30.54405018572365194,156.29582900705395332' +
'&CRS=EPSG:4326' +
'&VERSION=1.3.0' +
'&INFO_FORMAT=application/json' +
'&WIDTH=800&HEIGHT=400' +
'&LAYERS=requires_warped_vrt' +
'&QUERY_LAYERS=requires_warped_vrt' +
'&I=560&J=78' +
'&FEATURE_COUNT=10',
'wms_getfeatureinfo_raster_nodata_json',
'test_raster_nodata.qgz',
raw=True)


if __name__ == '__main__':
unittest.main()
Binary file added tests/testdata/qgis_server/test_raster_nodata.qgz
Binary file not shown.
@@ -0,0 +1,14 @@
*****
Content-Type: text/html; charset=utf-8

<HEAD>
<TITLE> GetFeatureInfo results </TITLE>
<META http-equiv="Content-Type" content="text/html;charset=utf-8"/>
</HEAD>
<BODY>
<TABLE border=1 width=100%>
<TR><TH width=25%>Layer</TH><TD>requires_warped_vrt</TD></TR>
</BR><TR><TH>Band 1</TH><TD>no data</TD></TR>
</TABLE>
<BR></BR>
</BODY>
@@ -0,0 +1,2 @@
*****
Content-Type: application/json; charset=utf-8{"features": [{"id": "requires_warped_vrt", "properties": {"Band 1": "null"}, "type": "Feature"}], "type": "FeatureCollection"}
@@ -0,0 +1,13 @@
*****
Content-Type: text/html; charset=utf-8

<HEAD>
<TITLE> GetFeatureInfo results </TITLE>
<META http-equiv="Content-Type" content="text/html;charset=utf-8"/>
</HEAD>
<BODY>
<TABLE border=1 width=100%>
<TR><TH width=25%>Layer</TH><TD>requires_warped_vrt</TD></TR>
</BR></TABLE>
<BR></BR>
</BODY>
@@ -0,0 +1,2 @@
*****
Content-Type: application/json; charset=utf-8{"features": [{"id": "requires_warped_vrt", "properties": {}, "type": "Feature"}], "type": "FeatureCollection"}
@@ -0,0 +1,7 @@
*****
Content-Type: text/plain; charset=utf-8

GetFeatureInfo results

Layer 'requires_warped_vrt'

@@ -0,0 +1,8 @@
*****
Content-Type: text/plain; charset=utf-8

GetFeatureInfo results

Layer 'requires_warped_vrt'
Band 1 = 'no data'

@@ -0,0 +1,14 @@
*****
Content-Type: text/html; charset=utf-8

<HEAD>
<TITLE> GetFeatureInfo results </TITLE>
<META http-equiv="Content-Type" content="text/html;charset=utf-8"/>
</HEAD>
<BODY>
<TABLE border=1 width=100%>
<TR><TH width=25%>Layer</TH><TD>requires_warped_vrt</TD></TR>
</BR><TR><TH>Band 1</TH><TD>0</TD></TR>
</TABLE>
<BR></BR>
</BODY>
@@ -0,0 +1,2 @@
*****
Content-Type: application/json; charset=utf-8{"features": [{"id": "requires_warped_vrt", "properties": {"Band 1": "0"}, "type": "Feature"}], "type": "FeatureCollection"}
@@ -0,0 +1,8 @@
*****
Content-Type: text/plain; charset=utf-8

GetFeatureInfo results

Layer 'requires_warped_vrt'
Band 1 = '0'

0 comments on commit 8351e06

Please sign in to comment.