QGIS API Documentation  3.23.0-Master (eb871beae0)
qgswmsgetstyles.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgswmsgetstyles.h
3  -------------------------
4  begin : December 20 , 2016
5  copyright : (C) 2007 by Marco Hugentobler (original code)
6  (C) 2014 by Alessandro Pasotti (original code)
7  (C) 2016 by David Marteau
8  email : marco dot hugentobler at karto dot baug dot ethz dot ch
9  a dot pasotti at itopen dot it
10  david dot marteau at 3liz dot com
11  ***************************************************************************/
12 
13 /***************************************************************************
14  * *
15  * This program is free software; you can redistribute it and/or modify *
16  * it under the terms of the GNU General Public License as published by *
17  * the Free Software Foundation; either version 2 of the License, or *
18  * (at your option) any later version. *
19  * *
20  ***************************************************************************/
21 
22 
23 #include "qgswmsutils.h"
24 #include "qgswmsrequest.h"
25 #include "qgswmsserviceexception.h"
26 #include "qgswmsgetstyles.h"
27 #include "qgswmsrendercontext.h"
28 #include "qgsserverprojectutils.h"
29 
30 #include "qgsproject.h"
31 #include "qgsrenderer.h"
32 #include "qgsvectorlayer.h"
34 #include "qgsvectorlayerlabeling.h"
35 
36 
37 namespace QgsWms
38 {
39 
40  namespace
41  {
42  QDomDocument getStyledLayerDescriptorDocument( QgsServerInterface *serverIface, const QgsProject *project, const QgsWmsRequest &request );
43  }
44 
45  void writeGetStyles( QgsServerInterface *serverIface, const QgsProject *project,
46  const QgsWmsRequest &request, QgsServerResponse &response )
47  {
48  const QDomDocument doc = getStyles( serverIface, project, request );
49  response.setHeader( QStringLiteral( "Content-Type" ), QStringLiteral( "text/xml; charset=utf-8" ) );
50  response.write( doc.toByteArray() );
51  }
52 
53  QDomDocument getStyles( QgsServerInterface *serverIface, const QgsProject *project,
54  const QgsWmsRequest &request )
55  {
56  return getStyledLayerDescriptorDocument( serverIface, project, request );
57  }
58 
59  namespace
60  {
61  QDomDocument getStyledLayerDescriptorDocument( QgsServerInterface *serverIface, const QgsProject *project, const QgsWmsRequest &request )
62  {
63  // init WMS parameters and context
64  const QgsWmsParameters parameters = request.wmsParameters();
65 
66  QgsWmsRenderContext context( project, serverIface );
67  context.setFlag( QgsWmsRenderContext::SetAccessControl );
68  context.setParameters( parameters );
69 
70  // init document
71  QDomDocument myDocument = QDomDocument();
72 
73  const QDomNode header = myDocument.createProcessingInstruction( QStringLiteral( "xml" ), QStringLiteral( "version=\"1.0\" encoding=\"UTF-8\"" ) );
74  myDocument.appendChild( header );
75 
76  // Create the root element
77  QDomElement root = myDocument.createElementNS( QStringLiteral( "http://www.opengis.net/sld" ), QStringLiteral( "StyledLayerDescriptor" ) );
78  root.setAttribute( QStringLiteral( "version" ), QStringLiteral( "1.1.0" ) );
79  root.setAttribute( QStringLiteral( "xsi:schemaLocation" ), QStringLiteral( "http://www.opengis.net/sld http://schemas.opengis.net/sld/1.1.0/StyledLayerDescriptor.xsd" ) );
80  root.setAttribute( QStringLiteral( "xmlns:ogc" ), QStringLiteral( "http://www.opengis.net/ogc" ) );
81  root.setAttribute( QStringLiteral( "xmlns:se" ), QStringLiteral( "http://www.opengis.net/se" ) );
82  root.setAttribute( QStringLiteral( "xmlns:xlink" ), QStringLiteral( "http://www.w3.org/1999/xlink" ) );
83  root.setAttribute( QStringLiteral( "xmlns:xsi" ), QStringLiteral( "http://www.w3.org/2001/XMLSchema-instance" ) );
84  myDocument.appendChild( root );
85 
86  for ( auto layer : context.layersToRender() )
87  {
88  // Create the NamedLayer element
89  QDomElement namedLayerNode = myDocument.createElement( QStringLiteral( "NamedLayer" ) );
90  root.appendChild( namedLayerNode );
91 
92  // store the Name element
93  QDomElement nameNode = myDocument.createElement( QStringLiteral( "se:Name" ) );
94  nameNode.appendChild( myDocument.createTextNode( context.layerNickname( *layer ) ) );
95  namedLayerNode.appendChild( nameNode );
96 
97  if ( layer->type() != QgsMapLayerType::VectorLayer )
98  continue;
99 
100  QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( layer );
101  if ( ! vlayer->isSpatial() )
102  continue;
103 
104  const QString currentStyle = vlayer->styleManager()->currentStyle();
105 
106  QVariantMap props;
107  if ( vlayer->hasScaleBasedVisibility() )
108  {
109  props[ QStringLiteral( "scaleMinDenom" ) ] = QString::number( vlayer->maximumScale() );
110  props[ QStringLiteral( "scaleMaxDenom" ) ] = QString::number( vlayer->minimumScale() );
111  }
112 
113  for ( const QString &styleName : vlayer->styleManager()->styles() )
114  {
115  vlayer->styleManager()->setCurrentStyle( styleName );
116 
117  QDomElement userStyleElem = myDocument.createElement( QStringLiteral( "UserStyle" ) );
118 
119  QDomElement styleNameElem = myDocument.createElement( QStringLiteral( "se:Name" ) );
120  styleNameElem.appendChild( myDocument.createTextNode( styleName ) );
121 
122  userStyleElem.appendChild( styleNameElem );
123 
124  QDomElement featureTypeStyleElem = myDocument.createElement( QStringLiteral( "se:FeatureTypeStyle" ) );
125  userStyleElem.appendChild( featureTypeStyleElem );
126 
127  vlayer->renderer()->toSld( myDocument, featureTypeStyleElem, props );
128  if ( vlayer->labelsEnabled() )
129  {
130  vlayer->labeling()->toSld( featureTypeStyleElem, props );
131  }
132 
133  namedLayerNode.appendChild( userStyleElem );
134  }
135  vlayer->styleManager()->setCurrentStyle( currentStyle );
136  }
137 
138  return myDocument;
139  }
140  }
141 } // namespace QgsWms
virtual void toSld(QDomNode &parent, const QVariantMap &props) const
Writes the SE 1.1 TextSymbolizer element based on the current layer labeling settings.
virtual void toSld(QDomDocument &doc, QDomElement &element, const QVariantMap &props=QVariantMap()) const
used from subclasses to create SLD Rule elements following SLD v1.1 specs
Definition: qgsrenderer.h:326
QString currentStyle() const
Returns name of the current style.
QStringList styles() const
Returns list of all defined style names.
bool setCurrentStyle(const QString &name)
Set a different style as the current style - will apply it to the layer.
bool hasScaleBasedVisibility() const
Returns whether scale based visibility is enabled for the layer.
double minimumScale() const
Returns the minimum map scale (i.e.
QgsMapLayerStyleManager * styleManager() const
Gets access to the layer's style manager.
double maximumScale() const
Returns the maximum map scale (i.e.
Encapsulates a QGIS project, including sets of map layers and their styles, layouts,...
Definition: qgsproject.h:101
QgsServerInterface Class defining interfaces exposed by QGIS Server and made available to plugins.
QgsServerResponse Class defining response interface passed to services QgsService::executeRequest() m...
virtual void write(const QString &data)
Write string This is a convenient method that will write directly to the underlying I/O device.
virtual void setHeader(const QString &key, const QString &value)=0
Set Header entry Add Header entry to the response Note that it is usually an error to set Header afte...
Represents a vector layer which manages a vector based data sets.
bool labelsEnabled() const
Returns whether the layer contains labels which are enabled and should be drawn.
bool isSpatial() const FINAL
Returns true if this is a geometry layer and false in case of NoGeometry (table only) or UnknownGeome...
const QgsAbstractVectorLayerLabeling * labeling() const
Access to const labeling configuration.
QgsFeatureRenderer * renderer()
Returns the feature renderer used for rendering the features in the layer in 2D map views.
Class defining request interface passed to WMS service.
Definition: qgswmsrequest.h:35
@ VectorLayer
Vector layer.
Median cut implementation.
QDomDocument getStyles(QgsServerInterface *serverIface, const QgsProject *project, const QgsWmsRequest &request)
Returns an SLD file with the styles of the requested layers.
void writeGetStyles(QgsServerInterface *serverIface, const QgsProject *project, const QgsWmsRequest &request, QgsServerResponse &response)
Output GetStyles response.