Skip to content

Commit

Permalink
Merge pull request #32433 from qgis/backport-32342-to-release-3_10
Browse files Browse the repository at this point in the history
[Backport release-3_10] [Server] WMS: Use QGIS Style instead of SLD to restore layer style
  • Loading branch information
rldhont committed Oct 28, 2019
2 parents 2884851 + ba8eaba commit edff9ce
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 9 deletions.
26 changes: 18 additions & 8 deletions src/server/services/wms/qgslayerrestorer.cpp
Expand Up @@ -16,11 +16,13 @@
***************************************************************************/

#include "qgslayerrestorer.h"
#include "qgsmessagelog.h"
#include "qgsmaplayer.h"
#include "qgsvectorlayer.h"
#include "qgsrasterlayer.h"
#include "qgsrasterrenderer.h"
#include "qgsmaplayerstylemanager.h"
#include "qgsreadwritecontext.h"

QgsLayerRestorer::QgsLayerRestorer( const QList<QgsMapLayer *> &layers )
{
Expand All @@ -36,9 +38,14 @@ QgsLayerRestorer::QgsLayerRestorer( const QList<QgsMapLayer *> &layers )
layer->setCustomProperty( "readSLD", false );

QString errMsg;
QDomDocument sldDoc;
layer->exportSldStyle( sldDoc, errMsg );
( void )settings.mSldStyle.setContent( sldDoc.toString(), true ); // for namespace processing
QDomDocument styleDoc( QStringLiteral( "style" ) );
QDomElement styleXml = styleDoc.createElement( QStringLiteral( "style" ) );
styleDoc.appendChild( styleXml );
if ( !layer->writeStyle( styleXml, styleDoc, errMsg, QgsReadWriteContext() ) )
{
QgsMessageLog::logMessage( QStringLiteral( "QGIS Style has not been added to layer restorer for layer %1: %2" ).arg( layer->name(), errMsg ) );
}
( void )settings.mQgisStyle.setContent( styleDoc.toString() );

switch ( layer->type() )
{
Expand Down Expand Up @@ -82,13 +89,16 @@ QgsLayerRestorer::~QgsLayerRestorer()
layer->styleManager()->setCurrentStyle( settings.mNamedStyle );
layer->setName( mLayerSettings[layer].name );

// if a SLD file has been loaded for rendering, we restore the previous one
QString errMsg;
QDomElement root = settings.mSldStyle.firstChildElement( "StyledLayerDescriptor" );
QDomElement el = root.firstChildElement( "NamedLayer" );
// if a SLD file has been loaded for rendering, we restore the previous style
if ( layer->customProperty( "readSLD", false ).toBool() )
{
layer->readSld( el, errMsg );
QString errMsg;
QDomElement root = settings.mQgisStyle.documentElement();
QgsReadWriteContext context = QgsReadWriteContext();
if ( !layer->readStyle( root, errMsg, context ) )
{
QgsMessageLog::logMessage( QStringLiteral( "QGIS Style has not been read from layer restorer for layer %1: %2" ).arg( layer->name(), errMsg ) );
}
}
layer->removeCustomProperty( "readSLD" );

Expand Down
2 changes: 1 addition & 1 deletion src/server/services/wms/qgslayerrestorer.h
Expand Up @@ -56,7 +56,7 @@ class QgsLayerRestorer
QString name;
double mOpacity;
QString mNamedStyle;
QDomDocument mSldStyle;
QDomDocument mQgisStyle;
QString mFilter;
QgsFeatureIds mSelectedFeatureIds;
};
Expand Down
37 changes: 37 additions & 0 deletions tests/src/python/test_qgsserver_wms_getmap.py
Expand Up @@ -1397,6 +1397,43 @@ def test_wms_getmap_sld_body(self):
r, h = self._result(self._execute_request(qs))
self._img_diff_error(r, h, "WMS_GetMap_SLDRestored")

def test_wms_getmap_sld_restore_labeling(self):
"""QGIS Server has to restore all the style. This test is not done
to evaluate the SLD application but the style restoration and
specifically the labeling."""
qs = "?" + "&".join(["%s=%s" % i for i in list({
"MAP": urllib.parse.quote(self.projectPath),
"SERVICE": "WMS",
"VERSION": "1.1.1",
"REQUEST": "GetMap",
"LAYERS": "pointlabel",
"STYLES": "",
"SLD_BODY": "<?xml version=\"1.0\" encoding=\"UTF-8\"?><StyledLayerDescriptor xmlns=\"http://www.opengis.net/sld\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:ogc=\"http://www.opengis.net/ogc\" xsi:schemaLocation=\"http://www.opengis.net/sld http://schemas.opengis.net/sld/1.1.0/StyledLayerDescriptor.xsd\" version=\"1.1.0\" xmlns:se=\"http://www.opengis.net/se\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"> <NamedLayer> <se:Name>pointlabel</se:Name> <UserStyle> <se:Name>pointlabel_style</se:Name> <se:FeatureTypeStyle> <se:Rule> <se:Name>Single symbol</se:Name> <se:PointSymbolizer uom=\"http://www.opengeospatial.org/se/units/metre\"> <se:Graphic> <se:Mark> <se:WellKnownName>square</se:WellKnownName> <se:Fill> <se:SvgParameter name=\"fill\">5e86a1</se:SvgParameter> </se:Fill> <se:Stroke> <se:SvgParameter name=\"stroke\">000000</se:SvgParameter> </se:Stroke> </se:Mark> <se:Size>0.007</se:Size> </se:Graphic> </se:PointSymbolizer> </se:Rule> </se:FeatureTypeStyle> </UserStyle> </NamedLayer> </StyledLayerDescriptor>",
"FORMAT": "image/png",
"BBOX": "-16817707,-4710778,5696513,14587125",
"HEIGHT": "500",
"WIDTH": "500",
"CRS": "EPSG:3857"
}.items())])
r, h = self._result(self._execute_request(qs))

qs = "?" + "&".join(["%s=%s" % i for i in list({
"MAP": urllib.parse.quote(self.projectPath),
"SERVICE": "WMS",
"VERSION": "1.1.1",
"REQUEST": "GetMap",
"LAYERS": "pointlabel",
"STYLES": "",
"FORMAT": "image/png",
"BBOX": "-16817707,-4710778,5696513,14587125",
"HEIGHT": "500",
"WIDTH": "500",
"CRS": "EPSG:3857"
}.items())])

r, h = self._result(self._execute_request(qs))
self._img_diff_error(r, h, "WMS_GetMap_Labeling_Complex")

def test_wms_getmap_group(self):
"""A WMS shall render the requested layers by drawing the leftmost in the list
bottommost, the next one over that, and so on."""
Expand Down

0 comments on commit edff9ce

Please sign in to comment.