Skip to content

Commit b035704

Browse files
authored
Merge pull request #5168 from rldhont/release-2_18-server-getprint-group-order
[BUGFIX][Server] GetPrint request renders layers from group in wrong order
2 parents 70cd0e4 + 9d12581 commit b035704

File tree

5 files changed

+91
-81
lines changed

5 files changed

+91
-81
lines changed

python/server/qgswmsconfigparser.sip

+4
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ class QgsWMSConfigParser
3535
/** Fills a layer and a style list. The two list have the same number of entries and the style and the layer at a position belong together (similar to the HTTP parameters 'Layers' and 'Styles'. Returns 0 in case of success*/
3636
virtual int layersAndStyles( QStringList& layers, QStringList& styles ) const = 0;
3737

38+
/** Creates a layer set and returns a stringlist with layer ids that can be passed to a QgsMapRenderer. Usually used in conjunction with readLayersAndStyles
39+
@param scaleDenominator Filter out layer if scale based visibility does not match (or use -1 if no scale restriction)*/
40+
QStringList layerSet( const QStringList& layersList, const QStringList& stylesList, const QgsCoordinateReferenceSystem& destCRS, double scaleDenominator = -1 ) const;
41+
3842
/** Returns the xml fragment of a style*/
3943
virtual QDomDocument getStyle( const QString& styleName, const QString& layerName ) const = 0;
4044

src/server/qgswmsconfigparser.cpp

+80-7
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
#include "qgsmaplayer.h"
2020
#include "qgsmaplayerregistry.h"
2121
#include "qgsmapserviceexception.h"
22+
#include "qgslogger.h"
23+
#include "qgsmessagelog.h"
2224

2325
#include "qgscomposerlabel.h"
2426
#include "qgscomposerlegend.h"
@@ -45,6 +47,73 @@ QgsWMSConfigParser::~QgsWMSConfigParser()
4547

4648
}
4749

50+
QStringList QgsWMSConfigParser::layerSet( const QStringList &layersList,
51+
const QStringList &stylesList,
52+
const QgsCoordinateReferenceSystem &destCRS, double scaleDenominator ) const
53+
{
54+
Q_UNUSED( destCRS );
55+
QStringList layerKeys;
56+
QStringList::const_iterator llstIt;
57+
QStringList::const_iterator slstIt;
58+
QgsMapLayer* theMapLayer = nullptr;
59+
QgsMessageLog::logMessage( QString( "Calculating layerset using %1 layers, %2 styles and CRS %3" ).arg( layersList.count() ).arg( stylesList.count() ).arg( destCRS.description() ) );
60+
for ( llstIt = layersList.begin(), slstIt = stylesList.begin(); llstIt != layersList.end(); ++llstIt )
61+
{
62+
QString styleName;
63+
if ( slstIt != stylesList.end() )
64+
{
65+
styleName = *slstIt;
66+
}
67+
QgsMessageLog::logMessage( "Trying to get layer " + *llstIt + "//" + styleName );
68+
69+
//does the layer name appear several times in the layer list?
70+
//if yes, layer caching must be disabled because several named layers could have
71+
//several user styles
72+
bool allowCaching = true;
73+
if ( layersList.count( *llstIt ) > 1 )
74+
{
75+
allowCaching = false;
76+
}
77+
78+
QList<QgsMapLayer*> layerList = mapLayerFromStyle( *llstIt, styleName, allowCaching );
79+
int listIndex;
80+
81+
for ( listIndex = layerList.size() - 1; listIndex >= 0; listIndex-- )
82+
{
83+
theMapLayer = layerList.at( listIndex );
84+
if ( theMapLayer )
85+
{
86+
QString lName = theMapLayer->name();
87+
if ( useLayerIDs() )
88+
lName = theMapLayer->id();
89+
else if ( !theMapLayer->shortName().isEmpty() )
90+
lName = theMapLayer->shortName();
91+
QgsMessageLog::logMessage( QString( "Checking layer: %1" ).arg( lName ) );
92+
//test if layer is visible in requested scale
93+
bool useScaleConstraint = ( scaleDenominator > 0 && theMapLayer->hasScaleBasedVisibility() );
94+
if ( !useScaleConstraint ||
95+
( theMapLayer->minimumScale() <= scaleDenominator && theMapLayer->maximumScale() >= scaleDenominator ) )
96+
{
97+
layerKeys.push_front( theMapLayer->id() );
98+
QgsMapLayerRegistry::instance()->addMapLayers(
99+
QList<QgsMapLayer *>() << theMapLayer, false, false );
100+
}
101+
}
102+
else
103+
{
104+
QgsMessageLog::logMessage( "Layer or style not defined, aborting" );
105+
throw QgsMapServiceException( "LayerNotDefined", "Layer '" + *llstIt + "' and/or style '" + styleName + "' not defined" );
106+
}
107+
}
108+
109+
if ( slstIt != stylesList.end() )
110+
{
111+
++slstIt;
112+
}
113+
}
114+
return layerKeys;
115+
}
116+
48117
QgsComposition* QgsWMSConfigParser::createPrintComposition( const QString& composerTemplate, QgsMapRenderer* mapRenderer, const QMap< QString, QString >& parameterMap ) const
49118
{
50119
QStringList highlightLayers;
@@ -144,10 +213,11 @@ QgsComposition* QgsWMSConfigParser::createPrintComposition( const QString& compo
144213
}
145214

146215
//layers / styles
147-
QStringList layerSet;
216+
QgsCoordinateReferenceSystem dummyCRS;
217+
QStringList mapLayerSet;
148218
if ( currentMap->keepLayerSet() )
149219
{
150-
layerSet = currentMap->layerSet();
220+
mapLayerSet = currentMap->layerSet();
151221
}
152222
else
153223
{
@@ -169,6 +239,8 @@ QgsComposition* QgsWMSConfigParser::createPrintComposition( const QString& compo
169239
wmsStyleList = styles.split( "," );
170240
}
171241

242+
mapLayerSet = layerSet( wmsLayerList, wmsStyleList, dummyCRS );
243+
/*
172244
for ( int i = 0; i < wmsLayerList.size(); ++i )
173245
{
174246
QString styleName;
@@ -185,15 +257,16 @@ QgsComposition* QgsWMSConfigParser::createPrintComposition( const QString& compo
185257
}
186258
}
187259
}
260+
* */
188261
}
189262

190263
//save layer list prior to adding highlight layers
191-
QStringList bkLayerSet = layerSet;
264+
QStringList bkLayerSet = mapLayerSet;
192265

193266
//add highlight layers
194-
highlightLayers.append( addHighlightLayers( parameterMap, layerSet, mapId + ":" ) );
267+
highlightLayers.append( addHighlightLayers( parameterMap, mapLayerSet, mapId + ":" ) );
195268

196-
currentMap->setLayerSet( layerSet );
269+
currentMap->setLayerSet( mapLayerSet );
197270
currentMap->setKeepLayerSet( true );
198271

199272
//remove highlight layers from the composer legends
@@ -233,8 +306,8 @@ QgsComposition* QgsWMSConfigParser::createPrintComposition( const QString& compo
233306

234307
// get model and layer tree root of the legend
235308
QgsLegendModelV2* model = currentLegend->modelV2();
236-
QStringList layerSet = map->layerSet();
237-
setLayerIdsToLegendModel( model, layerSet, map->scale() );
309+
QStringList mapLayerSet = map->layerSet();
310+
setLayerIdsToLegendModel( model, mapLayerSet, map->scale() );
238311
}
239312
}
240313

src/server/qgswmsconfigparser.h

+4
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@ class SERVER_EXPORT QgsWMSConfigParser
4646
/** Fills a layer and a style list. The two list have the same number of entries and the style and the layer at a position belong together (similar to the HTTP parameters 'Layers' and 'Styles'. Returns 0 in case of success*/
4747
virtual int layersAndStyles( QStringList& layers, QStringList& styles ) const = 0;
4848

49+
/** Creates a layer set and returns a stringlist with layer ids that can be passed to a QgsMapRenderer. Usually used in conjunction with readLayersAndStyles
50+
@param scaleDenominator Filter out layer if scale based visibility does not match (or use -1 if no scale restriction)*/
51+
QStringList layerSet( const QStringList& layersList, const QStringList& stylesList, const QgsCoordinateReferenceSystem& destCRS, double scaleDenominator = -1 ) const;
52+
4953
/** Returns the xml fragment of a style*/
5054
virtual QDomDocument getStyle( const QString& styleName, const QString& layerName ) const = 0;
5155

src/server/qgswmsserver.cpp

+3-70
Original file line numberDiff line numberDiff line change
@@ -779,7 +779,7 @@ QImage* QgsWMSServer::getLegendGraphics()
779779
}
780780

781781
QgsCoordinateReferenceSystem dummyCRS;
782-
QStringList layerIds = layerSet( layersList, stylesList, dummyCRS, scaleDenominator );
782+
QStringList layerIds = mConfigParser->layerSet( layersList, stylesList, dummyCRS, scaleDenominator );
783783
if ( layerIds.size() < 1 )
784784
{
785785
return nullptr;
@@ -1690,7 +1690,7 @@ int QgsWMSServer::getFeatureInfo( QDomDocument& result, const QString& version )
16901690
}
16911691

16921692
//get the layer registered in QgsMapLayerRegistry and apply possible filters
1693-
( void )layerSet( layersList, stylesList, mMapRenderer->destinationCrs() );
1693+
( void )mConfigParser->layerSet( layersList, stylesList, mMapRenderer->destinationCrs() );
16941694

16951695
//scoped pointer to restore all original layer filters (subsetStrings) when pointer goes out of scope
16961696
//there's LOTS of potential exit paths here, so we avoid having to restore the filters manually
@@ -1967,7 +1967,7 @@ QImage* QgsWMSServer::initializeRendering( QStringList& layersList, QStringList&
19671967
QgsRectangle mapExtent = mMapRenderer->extent();
19681968
mConfigParser->setScaleDenominator( scaleCalc.calculate( mapExtent, theImage->width() ) );
19691969

1970-
layerIdList = layerSet( layersList, stylesList, mMapRenderer->destinationCrs() );
1970+
layerIdList = mConfigParser->layerSet( layersList, stylesList, mMapRenderer->destinationCrs() );
19711971
#ifdef QGISDEBUG
19721972
QgsMessageLog::logMessage( QString( "Number of layers to be rendered. %1" ).arg( layerIdList.count() ) );
19731973
#endif
@@ -2597,73 +2597,6 @@ int QgsWMSServer::featureInfoFromRasterLayer( QgsRasterLayer* layer,
25972597
return 0;
25982598
}
25992599

2600-
QStringList QgsWMSServer::layerSet( const QStringList &layersList,
2601-
const QStringList &stylesList,
2602-
const QgsCoordinateReferenceSystem &destCRS, double scaleDenominator ) const
2603-
{
2604-
Q_UNUSED( destCRS );
2605-
QStringList layerKeys;
2606-
QStringList::const_iterator llstIt;
2607-
QStringList::const_iterator slstIt;
2608-
QgsMapLayer* theMapLayer = nullptr;
2609-
QgsMessageLog::logMessage( QString( "Calculating layerset using %1 layers, %2 styles and CRS %3" ).arg( layersList.count() ).arg( stylesList.count() ).arg( destCRS.description() ) );
2610-
for ( llstIt = layersList.begin(), slstIt = stylesList.begin(); llstIt != layersList.end(); ++llstIt )
2611-
{
2612-
QString styleName;
2613-
if ( slstIt != stylesList.end() )
2614-
{
2615-
styleName = *slstIt;
2616-
}
2617-
QgsMessageLog::logMessage( "Trying to get layer " + *llstIt + "//" + styleName );
2618-
2619-
//does the layer name appear several times in the layer list?
2620-
//if yes, layer caching must be disabled because several named layers could have
2621-
//several user styles
2622-
bool allowCaching = true;
2623-
if ( layersList.count( *llstIt ) > 1 )
2624-
{
2625-
allowCaching = false;
2626-
}
2627-
2628-
QList<QgsMapLayer*> layerList = mConfigParser->mapLayerFromStyle( *llstIt, styleName, allowCaching );
2629-
int listIndex;
2630-
2631-
for ( listIndex = layerList.size() - 1; listIndex >= 0; listIndex-- )
2632-
{
2633-
theMapLayer = layerList.at( listIndex );
2634-
if ( theMapLayer )
2635-
{
2636-
QString lName = theMapLayer->name();
2637-
if ( mConfigParser && mConfigParser->useLayerIDs() )
2638-
lName = theMapLayer->id();
2639-
else if ( !theMapLayer->shortName().isEmpty() )
2640-
lName = theMapLayer->shortName();
2641-
QgsMessageLog::logMessage( QString( "Checking layer: %1" ).arg( lName ) );
2642-
//test if layer is visible in requested scale
2643-
bool useScaleConstraint = ( scaleDenominator > 0 && theMapLayer->hasScaleBasedVisibility() );
2644-
if ( !useScaleConstraint ||
2645-
( theMapLayer->minimumScale() <= scaleDenominator && theMapLayer->maximumScale() >= scaleDenominator ) )
2646-
{
2647-
layerKeys.push_front( theMapLayer->id() );
2648-
QgsMapLayerRegistry::instance()->addMapLayers(
2649-
QList<QgsMapLayer *>() << theMapLayer, false, false );
2650-
}
2651-
}
2652-
else
2653-
{
2654-
QgsMessageLog::logMessage( "Layer or style not defined, aborting" );
2655-
throw QgsMapServiceException( "LayerNotDefined", "Layer '" + *llstIt + "' and/or style '" + styleName + "' not defined" );
2656-
}
2657-
}
2658-
2659-
if ( slstIt != stylesList.end() )
2660-
{
2661-
++slstIt;
2662-
}
2663-
}
2664-
return layerKeys;
2665-
}
2666-
26672600

26682601
void QgsWMSServer::applyRequestedLayerFilters( const QStringList& layerList , QHash<QgsMapLayer*, QString>& originalFilters ) const
26692602
{

src/server/qgswmsserver.h

-4
Original file line numberDiff line numberDiff line change
@@ -171,10 +171,6 @@ class QgsWMSServer: public QgsOWSServer
171171
const QString& version,
172172
const QString& infoFormat ) const;
173173

174-
/** Creates a layer set and returns a stringlist with layer ids that can be passed to a QgsMapRenderer. Usually used in conjunction with readLayersAndStyles
175-
@param scaleDenominator Filter out layer if scale based visibility does not match (or use -1 if no scale restriction)*/
176-
QStringList layerSet( const QStringList& layersList, const QStringList& stylesList, const QgsCoordinateReferenceSystem& destCRS, double scaleDenominator = -1 ) const;
177-
178174
/** Record which symbols would be used if the map was in the current configuration of mMapRenderer. This is useful for content-based legend*/
179175
void runHitTest( QPainter* painter, HitTest& hitTest );
180176
/** Record which symbols within one layer would be rendered with the given renderer context*/

0 commit comments

Comments
 (0)