Skip to content

Commit 69bed21

Browse files
author
Patrick Valsecchi
committed
WMS: Better logic to pick the legend URL
QGIS had two problems: 1) It was using the specified legend URL only if its mime type was matching the layer's mime type. There is no reason for that. 2) When QGIS was using the default layer (empty string), it was not even trying to find out in what style to pick the legend URL.
1 parent e79a327 commit 69bed21

File tree

4 files changed

+126
-17
lines changed

4 files changed

+126
-17
lines changed

src/providers/wms/qgswmscapabilities.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -907,7 +907,7 @@ void QgsWmsCapabilities::parseLayer( QDomElement const & e, QgsWmsLayerProperty&
907907

908908
for ( int i = 0; i < layerProperty.style.size(); ++i )
909909
{
910-
if ( layerProperty.style[i].name == styleProperty.name )
910+
if ( layerProperty.style.at( i ).name == styleProperty.name )
911911
{
912912
// override inherited parent's style if it has the same name
913913
// according to the WMS spec, it should not happen, but Mapserver

src/providers/wms/qgswmsprovider.cpp

+52-16
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,36 @@ QString QgsWmsProvider::getTileUrl() const
215215
}
216216
}
217217

218+
static bool isValidLegend( const QgsWmsLegendUrlProperty &l )
219+
{
220+
return l.format.startsWith( "image/" );
221+
}
222+
223+
/**
224+
* Picks a usable legend URL for a given style.
225+
*/
226+
static QString pickLegend( const QgsWmsStyleProperty &s )
227+
{
228+
QString url;
229+
for ( int k = 0; k < s.legendUrl.size() && url.isEmpty(); k++ )
230+
{
231+
const QgsWmsLegendUrlProperty &l = s.legendUrl[k];
232+
if ( isValidLegend( l ) )
233+
{
234+
url = l.onlineResource.xlinkHref;
235+
}
236+
}
237+
return url;
238+
}
239+
240+
static const QgsWmsStyleProperty *searchStyle( const QVector<QgsWmsStyleProperty>& styles, const QString& name )
241+
{
242+
Q_FOREACH ( const QgsWmsStyleProperty &s, styles )
243+
if ( s.name == name )
244+
return &s;
245+
return nullptr;
246+
}
247+
218248
QString QgsWmsProvider::getLegendGraphicUrl() const
219249
{
220250
QString url;
@@ -223,25 +253,31 @@ QString QgsWmsProvider::getLegendGraphicUrl() const
223253
{
224254
const QgsWmsLayerProperty &l = mCaps.mLayersSupported[i];
225255

226-
if ( l.name != mSettings.mActiveSubLayers[0] )
227-
continue;
228-
229-
for ( int j = 0; j < l.style.size() && url.isEmpty(); j++ )
256+
if ( l.name == mSettings.mActiveSubLayers[0] )
230257
{
231-
const QgsWmsStyleProperty &s = l.style[j];
232-
233-
if ( s.name != mSettings.mActiveSubStyles[0] )
234-
continue;
235-
236-
for ( int k = 0; k < s.legendUrl.size() && url.isEmpty(); k++ )
258+
if ( !mSettings.mActiveSubStyles[0].isEmpty() && mSettings.mActiveSubStyles[0] != "default" )
237259
{
238-
const QgsWmsLegendUrlProperty &l = s.legendUrl[k];
239-
240-
if ( l.format != mSettings.mImageMimeType )
241-
continue;
242-
243-
url = l.onlineResource.xlinkHref;
260+
const QgsWmsStyleProperty *s = searchStyle( l.style, mSettings.mActiveSubStyles[0] );
261+
if ( s )
262+
url = pickLegend( *s );
244263
}
264+
else
265+
{
266+
// QGIS wants the default style, but GetCapabilities doesn't give us a
267+
// way to know what is the default style. So we look for the onlineResource
268+
// only if there is a single style available or if there is a style called "default".
269+
if ( l.style.size() == 1 )
270+
{
271+
url = pickLegend( l.style[0] );
272+
}
273+
else
274+
{
275+
const QgsWmsStyleProperty *s = searchStyle( l.style, "default" );
276+
if ( s )
277+
url = pickLegend( *s );
278+
}
279+
}
280+
break;
245281
}
246282
}
247283

tests/src/providers/CMakeLists.txt

+4
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,10 @@ ADD_QGIS_TEST(wmscapabilititestest
8989
testqgswmscapabilities.cpp)
9090
TARGET_LINK_LIBRARIES(qgis_wmscapabilititestest wmsprovider_a)
9191
92+
ADD_QGIS_TEST(wmsprovidertest
93+
testqgswmsprovider.cpp)
94+
TARGET_LINK_LIBRARIES(qgis_wmsprovidertest wmsprovider_a)
95+
9296
#############################################################
9397
# WCS public servers test:
9498
# No need to test on all platforms
+69
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
#include <QFile>
2+
#include <QObject>
3+
#include <QtTest/QtTest>
4+
#include <qgswmsprovider.h>
5+
#include <qgsapplication.h>
6+
7+
/** \ingroup UnitTests
8+
* This is a unit test for the WMS provider.
9+
*/
10+
class TestQgsWmsProvider: public QObject
11+
{
12+
Q_OBJECT
13+
private slots:
14+
15+
void initTestCase()
16+
{
17+
// init QGIS's paths - true means that all path will be inited from prefix
18+
QgsApplication::init();
19+
QgsApplication::initQgis();
20+
21+
QFile file( QString( TEST_DATA_DIR ) + "/provider/GetCapabilities.xml" );
22+
QVERIFY( file.open( QIODevice::ReadOnly | QIODevice::Text ) );
23+
const QByteArray content = file.readAll();
24+
QVERIFY( content.size() > 0 );
25+
const QgsWmsParserSettings config;
26+
27+
mCapabilities = new QgsWmsCapabilities();
28+
QVERIFY( mCapabilities->parseResponse( content, config ) );
29+
}
30+
31+
//runs after all tests
32+
void cleanupTestCase()
33+
{
34+
delete mCapabilities;
35+
QgsApplication::exitQgis();
36+
}
37+
38+
void legendGraphicsWithStyle()
39+
{
40+
QgsWmsProvider provider( "http://localhost:8380/mapserv?xxx&layers=agri_zones&styles=fb_style&format=image/jpg", mCapabilities );
41+
QCOMPARE( provider.getLegendGraphicUrl(), QString( "http://www.example.com/fb.png?" ) );
42+
}
43+
44+
void legendGraphicsWithSecondStyle()
45+
{
46+
QgsWmsProvider provider( "http://localhost:8380/mapserv?xxx&layers=agri_zones&styles=yt_style&format=image/jpg", mCapabilities );
47+
QCOMPARE( provider.getLegendGraphicUrl(), QString( "http://www.example.com/yt.png?" ) );
48+
}
49+
50+
void legendGraphicsWithoutStyleWithDefault()
51+
{
52+
QgsWmsProvider provider( "http://localhost:8380/mapserv?xxx&layers=buildings&styles=&format=image/jpg", mCapabilities );
53+
//only one style, can guess default => use it
54+
QCOMPARE( provider.getLegendGraphicUrl(), QString( "http://www.example.com/buildings.png?" ) );
55+
}
56+
57+
void legendGraphicsWithoutStyleWithoutDefault()
58+
{
59+
QgsWmsProvider provider( "http://localhost:8380/mapserv?xxx&layers=agri_zones&styles=&format=image/jpg", mCapabilities );
60+
//two style, cannot guess default => use the WMS GetLegendGraphics
61+
QCOMPARE( provider.getLegendGraphicUrl(), QString( "http://localhost:8380/mapserv?" ) );
62+
}
63+
64+
private:
65+
QgsWmsCapabilities* mCapabilities;
66+
};
67+
68+
QTEST_MAIN( TestQgsWmsProvider )
69+
#include "testqgswmsprovider.moc"

0 commit comments

Comments
 (0)