QGIS API Documentation  3.12.1-BucureČ™ti (121cc00ff0)
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 
QDomDocument getStyle(QgsServerInterface *serverIface, const QgsProject *project, const QString &version, const QgsServerRequest &request)
Returns an SLD file with the style of the requested layer.
bool labelsEnabled() const
Returns whether the layer contains labels which are enabled and should be drawn.
void writeGetStyles(QgsServerInterface *serverIface, const QgsProject *project, const QString &version, const QgsServerRequest &request, QgsServerResponse &response)
Output GetStyles response.
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...
Base class for all map layer types.
Definition: qgsmaplayer.h:79
QStringList styles() const
Returns list of all defined style names.
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
Exception thrown in case of malformed request.
virtual void write(const QString &data)
Write string This is a convenient method that will write directly to the underlying I/O device...
QMap< QString, QString > QgsStringMap
Definition: qgis.h:694
bool isSpatial() const FINAL
Returns true if this is a geometry layer and false in case of NoGeometry (table only) or UnknownGeome...
QgsMapLayerStyleManager * styleManager() const
Gets access to the layer&#39;s style manager.
QgsServerRequest::Parameters parameters() const
Returns a map of query parameters with keys converted to uppercase.
Encapsulates a QGIS project, including sets of map layers and their styles, layouts, annotations, canvases, etc.
Definition: qgsproject.h:91
QgsFeatureRenderer * renderer()
Returns renderer.
const QgsAbstractVectorLayerLabeling * labeling() const
Access to const labeling configuration.
double minimumScale() const
Returns the minimum map scale (i.e.
double maximumScale() const
Returns the maximum map scale (i.e.
QMap< QString, QgsMapLayer * > mapLayers(const bool validOnly=false) const
Returns a map of all registered layers by layer ID.
void writeGetStyle(QgsServerInterface *serverIface, const QgsProject *project, const QString &version, const QgsServerRequest &request, QgsServerResponse &response)
Output GetStyle response.
Median cut implementation.
QgsServerRequest Class defining request interface passed to services QgsService::executeRequest() met...
QString currentStyle() const
Returns name of the current style.
bool layerReadPermission(const QgsMapLayer *layer) const
Returns the layer read right.
QgsServerInterface Class defining interfaces exposed by QGIS Server and made available to plugins...
bool hasScaleBasedVisibility() const
Returns whether scale based visibility is enabled for the layer.
virtual void toSld(QDomNode &parent, const QgsStringMap &props) const
Writes the SE 1.1 TextSymbolizer element based on the current layer labeling settings.
Exception thrown when data access violates access controls.
QDomDocument getStyles(QgsServerInterface *serverIface, const QgsProject *project, const QString &version, const QgsServerRequest &request)
Returns an SLD file with the styles of the requested layers.
A helper class that centralizes restrictions given by all the access control filter plugins...
QgsServerResponse Class defining response interface passed to services QgsService::executeRequest() m...
virtual QgsAccessControl * accessControls() const =0
Gets the registered access control filters.
SERVER_EXPORT QStringList wmsRestrictedLayers(const QgsProject &project)
Returns the restricted layer name list.
Represents a vector layer which manages a vector based data sets.
bool setCurrentStyle(const QString &name)
Set a different style as the current style - will apply it to the layer.
QMap< QString, QString > Parameters
SERVER_EXPORT bool wmsUseLayerIds(const QgsProject &project)
Returns if layer ids are used as name in WMS.