Skip to content

Commit 172b217

Browse files
authored
Merge pull request #5899 from peppsac/fix_17668
[server] Fix layers group handling
2 parents dd03981 + ac27347 commit 172b217

File tree

5 files changed

+4507
-24
lines changed

5 files changed

+4507
-24
lines changed

src/server/services/wms/qgswmsrenderer.cpp

+55-24
Original file line numberDiff line numberDiff line change
@@ -504,30 +504,7 @@ namespace QgsWms
504504
}
505505
else
506506
{
507-
QList<QgsMapLayer *> layerSet;
508-
const QList<QgsWmsParametersLayer> layers = cMapParams.mLayers;
509-
for ( const auto &layer : layers )
510-
{
511-
QString nickname = layer.mNickname;
512-
QString style = layer.mStyle;
513-
if ( mNicknameLayers.contains( nickname ) && !mRestrictedLayers.contains( nickname ) )
514-
{
515-
if ( !style.isEmpty() )
516-
{
517-
bool rc = mNicknameLayers[nickname]->styleManager()->setCurrentStyle( style );
518-
if ( ! rc )
519-
{
520-
throw QgsMapServiceException( QStringLiteral( "StyleNotDefined" ), QStringLiteral( "Style \"%1\" does not exist for layer \"%2\"" ).arg( style, nickname ) );
521-
}
522-
}
523-
layerSet << mNicknameLayers[nickname];
524-
}
525-
else
526-
{
527-
throw QgsBadRequestException( QStringLiteral( "LayerNotDefined" ),
528-
QStringLiteral( "Layer \"%1\" does not exist" ).arg( nickname ) );
529-
}
530-
}
507+
QList<QgsMapLayer *> layerSet = stylizedLayers( cMapParams.mLayers );
531508
layerSet << highlightLayers( cMapParams.mHighlightLayers );
532509
std::reverse( layerSet.begin(), layerSet.end() );
533510
map->setLayers( layerSet );
@@ -2389,6 +2366,30 @@ namespace QgsWms
23892366
{
23902367
mNicknameLayers[ layerNickname( *ml ) ] = ml;
23912368
}
2369+
2370+
// init groups
2371+
const QgsLayerTreeGroup *root = mProject->layerTreeRoot();
2372+
initLayerGroupsRecursive( root, mProject->title() );
2373+
}
2374+
2375+
void QgsRenderer::initLayerGroupsRecursive( const QgsLayerTreeGroup *group, const QString &groupName )
2376+
{
2377+
if ( !groupName.isEmpty() )
2378+
{
2379+
mLayerGroups[groupName] = QList<QgsMapLayer *>();
2380+
for ( QgsLayerTreeLayer *layer : group->findLayers() )
2381+
{
2382+
mLayerGroups[groupName].append( layer->layer() );
2383+
}
2384+
}
2385+
2386+
for ( const QgsLayerTreeNode *child : group->children() )
2387+
{
2388+
if ( child->nodeType() == QgsLayerTreeNode::NodeGroup )
2389+
{
2390+
initLayerGroupsRecursive( static_cast<const QgsLayerTreeGroup *>( child ), child->name() );
2391+
}
2392+
}
23922393
}
23932394

23942395
QString QgsRenderer::layerNickname( const QgsMapLayer &layer ) const
@@ -2602,6 +2603,18 @@ namespace QgsWms
26022603
mNicknameLayers[lname]->setCustomProperty( "readSLD", true );
26032604
layers.append( mNicknameLayers[lname] );
26042605
}
2606+
else if ( mLayerGroups.contains( lname ) )
2607+
{
2608+
for ( QgsMapLayer *layer : mLayerGroups[lname] )
2609+
{
2610+
if ( !mRestrictedLayers.contains( layerNickname( *layer ) ) )
2611+
{
2612+
layer->readSld( namedElem, err );
2613+
layer->setCustomProperty( "readSLD", true );
2614+
layers.append( layer );
2615+
}
2616+
}
2617+
}
26052618
else
26062619
{
26072620
throw QgsBadRequestException( QStringLiteral( "LayerNotDefined" ),
@@ -2648,6 +2661,24 @@ namespace QgsWms
26482661

26492662
layers.append( mNicknameLayers[nickname] );
26502663
}
2664+
else if ( mLayerGroups.contains( nickname ) )
2665+
{
2666+
for ( QgsMapLayer *layer : mLayerGroups[nickname] )
2667+
{
2668+
if ( !mRestrictedLayers.contains( layerNickname( *layer ) ) )
2669+
{
2670+
if ( !style.isEmpty() )
2671+
{
2672+
bool rc = layer->styleManager()->setCurrentStyle( style );
2673+
if ( ! rc )
2674+
{
2675+
throw QgsMapServiceException( QStringLiteral( "StyleNotDefined" ), QStringLiteral( "Style \"%1\" does not exist for layer \"%2\"" ).arg( style, layerNickname( *layer ) ) );
2676+
}
2677+
}
2678+
layers.append( layer );
2679+
}
2680+
}
2681+
}
26512682
else
26522683
{
26532684
throw QgsBadRequestException( QStringLiteral( "LayerNotDefined" ),

src/server/services/wms/qgswmsrenderer.h

+4
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ class QImage;
5757
class QPaintDevice;
5858
class QPainter;
5959
class QStandardItem;
60+
class QgsLayerTreeGroup;
6061

6162
/**
6263
* This class handles requestsi that share rendering:
@@ -136,6 +137,8 @@ namespace QgsWms
136137
// Init a map with nickname for layers' project
137138
void initNicknameLayers();
138139

140+
void initLayerGroupsRecursive( const QgsLayerTreeGroup *group, const QString &groupName );
141+
139142
// Return the nickname of the layer (short name, id or name according to
140143
// the project configuration)
141144
QString layerNickname( const QgsMapLayer &layer ) const;
@@ -297,6 +300,7 @@ namespace QgsWms
297300
QgsWmsParameters mWmsParameters;
298301
QStringList mRestrictedLayers;
299302
QMap<QString, QgsMapLayer *> mNicknameLayers;
303+
QMap<QString, QList<QgsMapLayer *> > mLayerGroups;
300304
QList<QgsMapLayer *> mTemporaryLayers;
301305

302306
public:

tests/src/python/test_qgsserver.py

+1
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ def setUp(self):
122122
self.projectAnnotationPath = os.path.join(d, "project_with_annotations.qgs")
123123
self.projectStatePath = os.path.join(d, "project_state.qgs")
124124
self.projectUseLayerIdsPath = os.path.join(d, "project_use_layerids.qgs")
125+
self.projectGroupsPath = os.path.join(d, "project_groups.qgs")
125126

126127
# Clean env just to be sure
127128
env_vars = ['QUERY_STRING', 'QGIS_PROJECT_FILE']

tests/src/python/test_qgsserver_wms_getmap.py

+51
Original file line numberDiff line numberDiff line change
@@ -889,6 +889,57 @@ def test_wms_getmap_sld(self):
889889
r, h = self._result(self._execute_request(qs))
890890
self._img_diff_error(r, h, "WMS_GetMap_SLDRestored")
891891

892+
def test_wms_getmap_group(self):
893+
qs = "?" + "&".join(["%s=%s" % i for i in list({
894+
"MAP": urllib.parse.quote(self.projectGroupsPath),
895+
"SERVICE": "WMS",
896+
"VERSION": "1.1.1",
897+
"REQUEST": "GetMap",
898+
"LAYERS": "Country,Country_Labels,Country_Diagrams",
899+
"STYLES": "",
900+
"FORMAT": "image/png",
901+
"BBOX": "-16817707,-4710778,5696513,14587125",
902+
"HEIGHT": "500",
903+
"WIDTH": "500",
904+
"CRS": "EPSG:3857"
905+
}.items())])
906+
907+
r_individual, _ = self._result(self._execute_request(qs))
908+
909+
qs = "?" + "&".join(["%s=%s" % i for i in list({
910+
"MAP": urllib.parse.quote(self.projectGroupsPath),
911+
"SERVICE": "WMS",
912+
"VERSION": "1.1.1",
913+
"REQUEST": "GetMap",
914+
"LAYERS": "CountryGroup",
915+
"STYLES": "",
916+
"FORMAT": "image/png",
917+
"BBOX": "-16817707,-4710778,5696513,14587125",
918+
"HEIGHT": "500",
919+
"WIDTH": "500",
920+
"CRS": "EPSG:3857"
921+
}.items())])
922+
923+
r_group, _ = self._result(self._execute_request(qs))
924+
self.assertEqual(r_individual, r_group, 'Individual layers query and group layers query results should be identical')
925+
926+
qs = "?" + "&".join(["%s=%s" % i for i in list({
927+
"MAP": urllib.parse.quote(self.projectGroupsPath),
928+
"SERVICE": "WMS",
929+
"VERSION": "1.1.1",
930+
"REQUEST": "GetMap",
931+
"SLD": "<?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>CountryGroup</se:Name></NamedLayer> </StyledLayerDescriptor>",
932+
"STYLES": "",
933+
"FORMAT": "image/png",
934+
"BBOX": "-16817707,-4710778,5696513,14587125",
935+
"HEIGHT": "500",
936+
"WIDTH": "500",
937+
"CRS": "EPSG:3857"
938+
}.items())])
939+
940+
r_group_sld, _ = self._result(self._execute_request(qs))
941+
self.assertEqual(r_individual, r_group_sld, 'Individual layers query and SLD group layers query results should be identical')
942+
892943

893944
if __name__ == '__main__':
894945
unittest.main()

0 commit comments

Comments
 (0)