QGIS API Documentation  3.14.0-Pi (9f7028fd23)
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 "qgswmsserviceexception.h"
25 #include "qgswmsgetstyles.h"
26 #include "qgsserverprojectutils.h"
27 
28 #include "qgsproject.h"
29 #include "qgsrenderer.h"
30 #include "qgsvectorlayer.h"
32 #include "qgsvectorlayerlabeling.h"
33 
34 
35 namespace QgsWms
36 {
37 
38  namespace
39  {
40  QDomDocument getStyledLayerDescriptorDocument( QgsServerInterface *serverIface, const QgsProject *project,
41  QStringList &layerList );
42  }
43 
44  void writeGetStyles( QgsServerInterface *serverIface, const QgsProject *project, const QString &version,
45  const QgsServerRequest &request, QgsServerResponse &response )
46  {
47  QDomDocument doc = getStyles( serverIface, project, version, request );
48  response.setHeader( QStringLiteral( "Content-Type" ), QStringLiteral( "text/xml; charset=utf-8" ) );
49  response.write( doc.toByteArray() );
50  }
51 
52  QDomDocument getStyles( QgsServerInterface *serverIface, const QgsProject *project, const QString &version,
53  const QgsServerRequest &request )
54  {
55  Q_UNUSED( version )
56 
57  QgsServerRequest::Parameters parameters = request.parameters();
58 
59  QString layersName = parameters.value( "LAYERS" );
60 
61  if ( layersName.isEmpty() )
62  {
65  }
66 
67  QStringList layerList = layersName.split( ',', QString::SkipEmptyParts );
68  if ( layerList.isEmpty() )
69  {
72  }
73 
74  return getStyledLayerDescriptorDocument( serverIface, project, layerList );
75  }
76 
77  //GetStyle for compatibility with earlier QGIS versions
78  void writeGetStyle( QgsServerInterface *serverIface, const QgsProject *project, const QString &version,
79  const QgsServerRequest &request, QgsServerResponse &response )
80  {
81  QDomDocument doc = getStyle( serverIface, project, version, request );
82  response.setHeader( QStringLiteral( "Content-Type" ), QStringLiteral( "text/xml; charset=utf-8" ) );
83  response.write( doc.toByteArray() );
84  }
85 
86  QDomDocument getStyle( QgsServerInterface *serverIface, const QgsProject *project, const QString &version,
87  const QgsServerRequest &request )
88  {
89  Q_UNUSED( version )
90 
91  QgsServerRequest::Parameters parameters = request.parameters();
92 
93  QDomDocument doc;
94 
95  QString styleName = parameters.value( QStringLiteral( "STYLE" ) );
96  QString layerName = parameters.value( QStringLiteral( "LAYER" ) );
97 
98  if ( styleName.isEmpty() )
99  {
102  }
103 
104  if ( layerName.isEmpty() )
105  {
108  }
109 
110  QStringList layerList;
111  layerList.append( layerName );
112  return getStyledLayerDescriptorDocument( serverIface, project, layerList );
113  }
114 
115  namespace
116  {
117  QDomDocument getStyledLayerDescriptorDocument( QgsServerInterface *serverIface, const QgsProject *project,
118  QStringList &layerList )
119  {
120  QDomDocument myDocument = QDomDocument();
121 
122  QDomNode header = myDocument.createProcessingInstruction( QStringLiteral( "xml" ), QStringLiteral( "version=\"1.0\" encoding=\"UTF-8\"" ) );
123  myDocument.appendChild( header );
124 
125  // Create the root element
126  QDomElement root = myDocument.createElementNS( QStringLiteral( "http://www.opengis.net/sld" ), QStringLiteral( "StyledLayerDescriptor" ) );
127  root.setAttribute( QStringLiteral( "version" ), QStringLiteral( "1.1.0" ) );
128  root.setAttribute( QStringLiteral( "xsi:schemaLocation" ), QStringLiteral( "http://www.opengis.net/sld http://schemas.opengis.net/sld/1.1.0/StyledLayerDescriptor.xsd" ) );
129  root.setAttribute( QStringLiteral( "xmlns:ogc" ), QStringLiteral( "http://www.opengis.net/ogc" ) );
130  root.setAttribute( QStringLiteral( "xmlns:se" ), QStringLiteral( "http://www.opengis.net/se" ) );
131  root.setAttribute( QStringLiteral( "xmlns:xlink" ), QStringLiteral( "http://www.w3.org/1999/xlink" ) );
132  root.setAttribute( QStringLiteral( "xmlns:xsi" ), QStringLiteral( "http://www.w3.org/2001/XMLSchema-instance" ) );
133  myDocument.appendChild( root );
134 
135  // access control
136 #ifdef HAVE_SERVER_PYTHON_PLUGINS
137  QgsAccessControl *accessControl = serverIface->accessControls();
138 #else
139  ( void )serverIface;
140 #endif
141  // Use layer ids
142  bool useLayerIds = QgsServerProjectUtils::wmsUseLayerIds( *project );
143  // WMS restricted layers
144  QStringList restrictedLayers = QgsServerProjectUtils::wmsRestrictedLayers( *project );
145 
146  for ( QgsMapLayer *layer : project->mapLayers() )
147  {
148  QString name = layer->name();
149  if ( useLayerIds )
150  name = layer->id();
151  else if ( !layer->shortName().isEmpty() )
152  name = layer->shortName();
153 
154  if ( !layerList.contains( name ) )
155  {
156  continue;
157  }
158 
159  //unpublished layer
160  if ( restrictedLayers.contains( layer->name() ) )
161  {
162  throw QgsSecurityException( QStringLiteral( "You are not allowed to access to this layer" ) );
163  }
164 #ifdef HAVE_SERVER_PYTHON_PLUGINS
165  if ( accessControl && !accessControl->layerReadPermission( layer ) )
166  {
167  throw QgsSecurityException( QStringLiteral( "You are not allowed to access to this layer" ) );
168  }
169 #endif
170  // Create the NamedLayer element
171  QDomElement namedLayerNode = myDocument.createElement( QStringLiteral( "NamedLayer" ) );
172  root.appendChild( namedLayerNode );
173 
174  // store the Name element
175  QDomElement nameNode = myDocument.createElement( QStringLiteral( "se:Name" ) );
176  nameNode.appendChild( myDocument.createTextNode( name ) );
177  namedLayerNode.appendChild( nameNode );
178 
179  if ( layer->type() == QgsMapLayerType::VectorLayer )
180  {
181  QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( layer );
182  if ( vlayer->isSpatial() )
183  {
184  QString currentStyle = vlayer->styleManager()->currentStyle();
185 
186  QgsStringMap props;
187  if ( vlayer->hasScaleBasedVisibility() )
188  {
189  props[ QStringLiteral( "scaleMinDenom" ) ] = QString::number( vlayer->maximumScale() );
190  props[ QStringLiteral( "scaleMaxDenom" ) ] = QString::number( vlayer->minimumScale() );
191  }
192 
193  for ( const QString &styleName : vlayer->styleManager()->styles() )
194  {
195  vlayer->styleManager()->setCurrentStyle( styleName );
196 
197  QDomElement userStyleElem = myDocument.createElement( QStringLiteral( "UserStyle" ) );
198 
199  QDomElement styleNameElem = myDocument.createElement( QStringLiteral( "se:Name" ) );
200  styleNameElem.appendChild( myDocument.createTextNode( styleName ) );
201 
202  userStyleElem.appendChild( styleNameElem );
203 
204  QDomElement featureTypeStyleElem = myDocument.createElement( QStringLiteral( "se:FeatureTypeStyle" ) );
205  userStyleElem.appendChild( featureTypeStyleElem );
206 
207  vlayer->renderer()->toSld( myDocument, featureTypeStyleElem, props );
208  if ( vlayer->labelsEnabled() )
209  {
210  vlayer->labeling()->toSld( featureTypeStyleElem, props );
211  }
212 
213  namedLayerNode.appendChild( userStyleElem );
214  }
215  vlayer->styleManager()->setCurrentStyle( currentStyle );
216  }
217  }
218  }
219 
220  return myDocument;
221  }
222  }
223 
224 
225 } // namespace QgsWms
226 
227 
228 
229 
QgsMapLayerStyleManager::styles
QStringList styles() const
Returns list of all defined style names.
Definition: qgsmaplayerstylemanager.cpp:86
QgsServerRequest::parameters
QgsServerRequest::Parameters parameters() const
Returns a map of query parameters with keys converted to uppercase.
Definition: qgsserverrequest.cpp:85
qgsmaplayerstylemanager.h
QgsMapLayerType::VectorLayer
@ VectorLayer
qgswmsutils.h
QgsProject::mapLayers
QMap< QString, QgsMapLayer * > mapLayers(const bool validOnly=false) const
Returns a map of all registered layers by layer ID.
Definition: qgsproject.cpp:3347
QgsWms::getStyle
QDomDocument getStyle(QgsServerInterface *serverIface, const QgsProject *project, const QString &version, const QgsServerRequest &request)
Returns an SLD file with the style of the requested layer.
Definition: qgswmsgetstyles.cpp:103
QgsWms::QgsWmsParameter::STYLE
@ STYLE
Definition: qgswmsparameters.h:146
qgsserverprojectutils.h
QgsMapLayer::styleManager
QgsMapLayerStyleManager * styleManager() const
Gets access to the layer's style manager.
Definition: qgsmaplayer.cpp:1797
QgsAccessControl::layerReadPermission
bool layerReadPermission(const QgsMapLayer *layer) const
Returns the layer read right.
Definition: qgsaccesscontrol.cpp:105
QgsVectorLayer::isSpatial
bool isSpatial() const FINAL
Returns true if this is a geometry layer and false in case of NoGeometry (table only) or UnknownGeome...
Definition: qgsvectorlayer.cpp:3591
QgsServerRequest
Definition: qgsserverrequest.h:38
QgsAbstractVectorLayerLabeling::toSld
virtual void toSld(QDomNode &parent, const QgsStringMap &props) const
Writes the SE 1.1 TextSymbolizer element based on the current layer labeling settings.
Definition: qgsvectorlayerlabeling.h:110
QgsFeatureRenderer::toSld
virtual void toSld(QDomDocument &doc, QDomElement &element, const QgsStringMap &props=QgsStringMap()) const
used from subclasses to create SLD Rule elements following SLD v1.1 specs
Definition: qgsrenderer.h:312
QgsServerInterface::accessControls
virtual QgsAccessControl * accessControls() const =0
Gets the registered access control filters.
QgsProject
Definition: qgsproject.h:92
QgsServerRequest::Parameters
QMap< QString, QString > Parameters
Definition: qgsserverrequest.h:59
QgsServerResponse::write
virtual void write(const QString &data)
Write string This is a convenient method that will write directly to the underlying I/O device.
Definition: qgsserverresponse.cpp:25
QgsServerProjectUtils::wmsUseLayerIds
SERVER_EXPORT bool wmsUseLayerIds(const QgsProject &project)
Returns if layer ids are used as name in WMS.
Definition: qgsserverprojectutils.cpp:125
QgsVectorLayer::labeling
const QgsAbstractVectorLayerLabeling * labeling() const
Access to const labeling configuration.
Definition: qgsvectorlayer.h:1598
QgsServerProjectUtils::wmsRestrictedLayers
SERVER_EXPORT QStringList wmsRestrictedLayers(const QgsProject &project)
Returns the restricted layer name list.
Definition: qgsserverprojectutils.cpp:311
QgsWms::writeGetStyle
void writeGetStyle(QgsServerInterface *serverIface, const QgsProject *project, const QString &version, const QgsServerRequest &request, QgsServerResponse &response)
Output GetStyle response.
Definition: qgswmsgetstyles.cpp:95
QgsWms::QgsServiceException::QGIS_MissingParameterValue
@ QGIS_MissingParameterValue
Definition: qgswmsserviceexception.h:74
QgsMapLayer::hasScaleBasedVisibility
bool hasScaleBasedVisibility() const
Returns whether scale based visibility is enabled for the layer.
Definition: qgsmaplayer.cpp:676
qgsrenderer.h
QgsMapLayer::minimumScale
double minimumScale() const
Returns the minimum map scale (i.e.
Definition: qgsmaplayer.cpp:741
QgsMapLayerStyleManager::currentStyle
QString currentStyle() const
Returns name of the current style.
Definition: qgsmaplayerstylemanager.cpp:164
QgsMapLayer::maximumScale
double maximumScale() const
Returns the maximum map scale (i.e.
Definition: qgsmaplayer.cpp:725
QgsWms::getStyles
QDomDocument getStyles(QgsServerInterface *serverIface, const QgsProject *project, const QString &version, const QgsServerRequest &request)
Returns an SLD file with the styles of the requested layers.
Definition: qgswmsgetstyles.cpp:69
qgsvectorlayer.h
QgsAccessControl
A helper class that centralizes restrictions given by all the access control filter plugins.
Definition: qgsaccesscontrol.h:36
QgsWms
WMS implementation.
Definition: qgsdxfwriter.cpp:22
QgsStringMap
QMap< QString, QString > QgsStringMap
Definition: qgis.h:714
QgsWms::QgsWmsParameter::LAYERS
@ LAYERS
Definition: qgswmsparameters.h:140
QgsWms::QgsBadRequestException
Exception thrown in case of malformed request.
Definition: qgswmsserviceexception.h:226
QgsVectorLayer
Definition: qgsvectorlayer.h:385
QgsMapLayer
Definition: qgsmaplayer.h:81
qgswmsgetstyles.h
QgsMapLayerStyleManager::setCurrentStyle
bool setCurrentStyle(const QString &name)
Set a different style as the current style - will apply it to the layer.
Definition: qgsmaplayerstylemanager.cpp:169
qgsvectorlayerlabeling.h
QgsWms::writeGetStyles
void writeGetStyles(QgsServerInterface *serverIface, const QgsProject *project, const QString &version, const QgsServerRequest &request, QgsServerResponse &response)
Output GetStyles response.
Definition: qgswmsgetstyles.cpp:61
qgswmsserviceexception.h
QgsServerInterface
Definition: qgsserverinterface.h:60
qgsproject.h
QgsServerResponse
Definition: qgsserverresponse.h:43
QgsVectorLayer::labelsEnabled
bool labelsEnabled() const
Returns whether the layer contains labels which are enabled and should be drawn.
Definition: qgsvectorlayer.cpp:728
QgsServerResponse::setHeader
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...
QgsVectorLayer::renderer
QgsFeatureRenderer * renderer()
Returns renderer.
Definition: qgsvectorlayer.h:881