Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
WMS GetCapabilities: override parent's style if they have the same name
When there is a layer group with several sub-layers, the group has a
"default" style and the sub-layers each have a "default" layer. QGIS
was showing two "default" styles for the sub-layers, which would be
confusing to the user and could pick the wrong legend for the
sub-layer if the user picked the wrong entry (the first one).

Had to create a static lib for wmsprovider in order to unittest it.
  • Loading branch information
Patrick Valsecchi committed May 29, 2016
1 parent c7a4e5a commit e79a327
Show file tree
Hide file tree
Showing 5 changed files with 280 additions and 0 deletions.
6 changes: 6 additions & 0 deletions src/providers/wms/CMakeLists.txt
Expand Up @@ -41,6 +41,7 @@ INCLUDE_DIRECTORIES(SYSTEM
${QCA_INCLUDE_DIR}
)

ADD_LIBRARY(wmsprovider_a STATIC ${WMS_SRCS} ${WMS_MOC_SRCS})
ADD_LIBRARY(wmsprovider MODULE ${WMS_SRCS} ${WMS_MOC_SRCS})

TARGET_LINK_LIBRARIES(wmsprovider
Expand All @@ -50,6 +51,11 @@ TARGET_LINK_LIBRARIES(wmsprovider
${GDAL_LIBRARY} # for OGR_G_CreateGeometryFromJson()
)

TARGET_LINK_LIBRARIES(wmsprovider_a
qgis_core
${QT_QTSCRIPT_LIBRARY}
)

INSTALL (TARGETS wmsprovider
RUNTIME DESTINATION ${QGIS_PLUGIN_DIR}
LIBRARY DESTINATION ${QGIS_PLUGIN_DIR})
11 changes: 11 additions & 0 deletions src/providers/wms/qgswmscapabilities.cpp
Expand Up @@ -905,6 +905,17 @@ void QgsWmsCapabilities::parseLayer( QDomElement const & e, QgsWmsLayerProperty&

parseStyle( e1, styleProperty );

for ( int i = 0; i < layerProperty.style.size(); ++i )
{
if ( layerProperty.style[i].name == styleProperty.name )
{
// override inherited parent's style if it has the same name
// according to the WMS spec, it should not happen, but Mapserver
// does it all the time.
layerProperty.style.remove( i );
break;
}
}
layerProperty.style.push_back( styleProperty );
}
else if ( tagName == "MinScaleDenominator" )
Expand Down
5 changes: 5 additions & 0 deletions tests/src/providers/CMakeLists.txt
Expand Up @@ -9,6 +9,7 @@ INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_SOURCE_DIR}/src/core/auth
${CMAKE_SOURCE_DIR}/src/core/geometry
${CMAKE_SOURCE_DIR}/src/core/raster
${CMAKE_SOURCE_DIR}/src/providers/wms
)
INCLUDE_DIRECTORIES(SYSTEM
${QT_INCLUDE_DIR}
Expand Down Expand Up @@ -84,6 +85,10 @@ SET_TARGET_PROPERTIES(qgis_wcsprovidertest PROPERTIES

ADD_QGIS_TEST(gdalprovidertest testqgsgdalprovider.cpp)

ADD_QGIS_TEST(wmscapabilititestest
testqgswmscapabilities.cpp)
TARGET_LINK_LIBRARIES(qgis_wmscapabilititestest wmsprovider_a)

#############################################################
# WCS public servers test:
# No need to test on all platforms
Expand Down
70 changes: 70 additions & 0 deletions tests/src/providers/testqgswmscapabilities.cpp
@@ -0,0 +1,70 @@
#include <QFile>
#include <QObject>
#include <QtTest/QtTest>
#include <qgswmscapabilities.h>
#include <qgsapplication.h>

/** \ingroup UnitTests
* This is a unit test for the WMS capabilities parser.
*/
class TestQgsWmsCapabilities: public QObject
{
Q_OBJECT
private slots:

void initTestCase()
{
// init QGIS's paths - true means that all path will be inited from prefix
QgsApplication::init();
QgsApplication::initQgis();
}

//runs after all tests
void cleanupTestCase()
{
QgsApplication::exitQgis();
}


void read()
{
QgsWmsCapabilities capabilities;

QFile file( QString( TEST_DATA_DIR ) + "/provider/GetCapabilities.xml" );
QVERIFY( file.open( QIODevice::ReadOnly | QIODevice::Text ) );
const QByteArray content = file.readAll();
QVERIFY( content.size() > 0 );
const QgsWmsParserSettings config;

QVERIFY( capabilities.parseResponse( content, config ) );
QCOMPARE( capabilities.supportedLayers().size(), 5 );
QCOMPARE( capabilities.supportedLayers()[0].name, QString( "agri_zones" ) );
QCOMPARE( capabilities.supportedLayers()[1].name, QString( "buildings" ) );
QCOMPARE( capabilities.supportedLayers()[2].name, QString( "land_surveing_parcels" ) );
QCOMPARE( capabilities.supportedLayers()[3].name, QString( "cadastre" ) );
QCOMPARE( capabilities.supportedLayers()[4].name, QString( "test" ) );

// make sure the default style is not seen twice in the child layers
QCOMPARE( capabilities.supportedLayers()[3].style.size(), 1 );
QCOMPARE( capabilities.supportedLayers()[3].style[0].name, QString( "default" ) );
QCOMPARE( capabilities.supportedLayers()[1].style.size(), 1 );
QCOMPARE( capabilities.supportedLayers()[1].style[0].name, QString( "default" ) );
QCOMPARE( capabilities.supportedLayers()[2].style.size(), 1 );
QCOMPARE( capabilities.supportedLayers()[2].style[0].name, QString( "default" ) );

// check it can read 2 styles for a layer and that the legend URL is OK
QCOMPARE( capabilities.supportedLayers()[0].style.size(), 2 );
QCOMPARE( capabilities.supportedLayers()[0].style[0].name, QString( "yt_style" ) );
QCOMPARE( capabilities.supportedLayers()[0].style[0].legendUrl.size(), 1 );
QCOMPARE( capabilities.supportedLayers()[0].style[0].legendUrl[0].onlineResource.xlinkHref,
QString( "http://www.example.com/yt.png" ) );
QCOMPARE( capabilities.supportedLayers()[0].style[1].name, QString( "fb_style" ) );
QCOMPARE( capabilities.supportedLayers()[0].style[1].legendUrl.size(), 1 );
QCOMPARE( capabilities.supportedLayers()[0].style[1].legendUrl[0].onlineResource.xlinkHref,
QString( "http://www.example.com/fb.png" ) );
}

};

QTEST_MAIN( TestQgsWmsCapabilities )
#include "testqgswmscapabilities.moc"
188 changes: 188 additions & 0 deletions tests/testdata/provider/GetCapabilities.xml
@@ -0,0 +1,188 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<WMS_Capabilities version="1.3.0" xmlns="http://www.opengis.net/wms" xmlns:sld="http://www.opengis.net/sld" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ms="http://mapserver.gis.umn.edu/mapserver" xsi:schemaLocation="http://www.opengis.net/wms http://schemas.opengis.net/wms/1.3.0/capabilities_1_3_0.xsd http://www.opengis.net/sld http://schemas.opengis.net/sld/1.1.0/sld_capabilities.xsd http://mapserver.gis.umn.edu/mapserver http://localhost:8380/mapserv?service=WMS&amp;version=1.3.0&amp;request=GetSchemaExtension">
<!-- MapServer version 7.0.1 OUTPUT=PNG OUTPUT=JPEG OUTPUT=KML SUPPORTS=PROJ SUPPORTS=AGG SUPPORTS=FREETYPE SUPPORTS=CAIRO SUPPORTS=SVG_SYMBOLS SUPPORTS=RSVG SUPPORTS=ICONV SUPPORTS=FRIBIDI SUPPORTS=WMS_SERVER SUPPORTS=WMS_CLIENT SUPPORTS=WFS_SERVER SUPPORTS=WFS_CLIENT SUPPORTS=WCS_SERVER SUPPORTS=SOS_SERVER SUPPORTS=FASTCGI SUPPORTS=THREADS SUPPORTS=GEOS INPUT=JPEG INPUT=POSTGIS INPUT=OGR INPUT=GDAL INPUT=SHAPEFILE -->
<Service>
<Name>WMS</Name>
<Title>Test</Title>
<Abstract>Test</Abstract>
<OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://localhost:8380/mapserv?"/>
<ContactInformation>
</ContactInformation>
<MaxWidth>5000</MaxWidth>
<MaxHeight>5000</MaxHeight>
</Service>

<Capability>
<Request>
<GetCapabilities>
<Format>text/xml</Format>
<DCPType>
<HTTP>
<Get><OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://localhost:8380/mapserv?"/></Get>
<Post><OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://localhost:8380/mapserv?"/></Post>
</HTTP>
</DCPType>
</GetCapabilities>
<GetMap>
<Format>image/jpeg</Format>
<Format>image/png</Format>
<DCPType>
<HTTP>
<Get><OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://localhost:8380/mapserv?"/></Get>
<Post><OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://localhost:8380/mapserv?"/></Post>
</HTTP>
</DCPType>
</GetMap>
<GetFeatureInfo>
<Format>text/plain</Format>
<Format>application/vnd.ogc.gml</Format>
<DCPType>
<HTTP>
<Get><OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://localhost:8380/mapserv?"/></Get>
<Post><OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://localhost:8380/mapserv?"/></Post>
</HTTP>
</DCPType>
</GetFeatureInfo>
<sld:DescribeLayer>
<Format>text/xml</Format>
<DCPType>
<HTTP>
<Get><OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://localhost:8380/mapserv?"/></Get>
<Post><OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://localhost:8380/mapserv?"/></Post>
</HTTP>
</DCPType>
</sld:DescribeLayer>
<sld:GetLegendGraphic>
<Format>image/jpeg</Format>
<Format>image/png</Format>
<Format>image/png; mode=8bit</Format>
<DCPType>
<HTTP>
<Get><OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://localhost:8380/mapserv?"/></Get>
<Post><OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://localhost:8380/mapserv?"/></Post>
</HTTP>
</DCPType>
</sld:GetLegendGraphic>
<ms:GetStyles>
<Format>text/xml</Format>
<DCPType>
<HTTP>
<Get><OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://localhost:8380/mapserv?"/></Get>
<Post><OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://localhost:8380/mapserv?"/></Post>
</HTTP>
</DCPType>
</ms:GetStyles>
</Request>
<Exception>
<Format>XML</Format>
<Format>BLANK</Format>
</Exception>
<sld:UserDefinedSymbolization SupportSLD="1" UserLayer="0" UserStyle="1" RemoteWFS="0" InlineFeature="0" RemoteWCS="0"/>
<Layer>
<Name>test</Name>
<Title>Test</Title>
<Abstract>Test</Abstract>
<CRS>EPSG:2056</CRS>
<EX_GeographicBoundingBox>
<westBoundLongitude>5.01393</westBoundLongitude>
<eastBoundLongitude>11.4774</eastBoundLongitude>
<southBoundLatitude>45.356</southBoundLatitude>
<northBoundLatitude>48.3001</northBoundLatitude>
</EX_GeographicBoundingBox>
<BoundingBox CRS="EPSG:2056" minx="2.42e+06" miny="1.03e+06" maxx="2.9e+06" maxy="1.35e+06"/>
<Layer queryable="1" opaque="0" cascaded="0">
<Name>agri_zones</Name>
<Title>agri_zones</Title>
<CRS>EPSG:2056</CRS>
<EX_GeographicBoundingBox>
<westBoundLongitude>5.01393</westBoundLongitude>
<eastBoundLongitude>11.4774</eastBoundLongitude>
<southBoundLatitude>45.356</southBoundLatitude>
<northBoundLatitude>48.3001</northBoundLatitude>
</EX_GeographicBoundingBox>
<BoundingBox CRS="EPSG:2056" minx="2.42e+06" miny="1.03e+06" maxx="2.9e+06" maxy="1.35e+06"/>
<MetadataURL type="TC211">
<Format>text/html</Format>
<OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple" xlink:href="http://www.example.com/bar"/>
</MetadataURL>
<Style>
<Name>yt_style</Name>
<Title>yt_style</Title>
<LegendURL width="23" height="19">
<Format>image/png</Format>
<OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple" xlink:href="http://www.example.com/yt.png"/>
</LegendURL>
</Style>
<Style>
<Name>fb_style</Name>
<Title>fb_style</Title>
<LegendURL width="23" height="19">
<Format>image/png</Format>
<OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple" xlink:href="http://www.example.com/fb.png"/>
</LegendURL>
</Style>
</Layer>
<Layer>
<Name>cadastre</Name>
<Title>cadastre</Title>
<Abstract>cadastre</Abstract>
<Style>
<Name>default</Name>
<Title>default</Title>
<LegendURL width="88" height="50">
<Format>image/png</Format>
<OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple" xlink:href="http://localhost:8380/mapserv?version=1.3.0&amp;service=WMS&amp;request=GetLegendGraphic&amp;sld_version=1.1.0&amp;layer=cadastre&amp;format=image/png&amp;STYLE=default"/>
</LegendURL>
</Style>
<Layer queryable="1" opaque="0" cascaded="0">
<Name>buildings</Name>
<Title>buildings</Title>
<CRS>EPSG:2056</CRS>
<EX_GeographicBoundingBox>
<westBoundLongitude>5.01393</westBoundLongitude>
<eastBoundLongitude>11.4774</eastBoundLongitude>
<southBoundLatitude>45.356</southBoundLatitude>
<northBoundLatitude>48.3001</northBoundLatitude>
</EX_GeographicBoundingBox>
<BoundingBox CRS="EPSG:2056" minx="2.42e+06" miny="1.03e+06" maxx="2.9e+06" maxy="1.35e+06"/>
<MetadataURL type="TC211">
<Format>text/html</Format>
<OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple" xlink:href="http://www.example.com/bar"/>
</MetadataURL>
<Style>
<Name>default</Name>
<Title>default</Title>
<LegendURL width="88" height="20">
<Format>image/png</Format>
<OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple" xlink:href="http://www.example.com/buildings.png"/>
</LegendURL>
</Style>
</Layer>
<Layer queryable="1" opaque="0" cascaded="0">
<Name>land_surveing_parcels</Name>
<Title>land_surveing_parcels</Title>
<CRS>EPSG:2056</CRS>
<EX_GeographicBoundingBox>
<westBoundLongitude>5.01393</westBoundLongitude>
<eastBoundLongitude>11.4774</eastBoundLongitude>
<southBoundLatitude>45.356</southBoundLatitude>
<northBoundLatitude>48.3001</northBoundLatitude>
</EX_GeographicBoundingBox>
<BoundingBox CRS="EPSG:2056" minx="2.42e+06" miny="1.03e+06" maxx="2.9e+06" maxy="1.35e+06"/>
<MetadataURL type="TC211">
<Format>text/html</Format>
<OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple" xlink:href="http://www.example.com/bar"/>
</MetadataURL>
<Style>
<Name>default</Name>
<Title>default</Title>
<LegendURL width="84" height="20">
<Format>image/png</Format>
<OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple" xlink:href="http://localhost:8380/mapserv?version=1.3.0&amp;service=WMS&amp;request=GetLegendGraphic&amp;sld_version=1.1.0&amp;layer=land_surveing_parcels&amp;format=image/png&amp;STYLE=default"/>
</LegendURL>
</Style>
</Layer>
</Layer>
</Layer>
</Capability>
</WMS_Capabilities>

0 comments on commit e79a327

Please sign in to comment.