QGIS API Documentation  3.18.1-Zürich (202f1bf7e5)
qgswmsdescribelayer.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgswmsdescribelayer.cpp
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 #include "qgswmsutils.h"
23 #include "qgswmsserviceexception.h"
24 #include "qgswmsdescribelayer.h"
25 #include "qgsserverprojectutils.h"
26 #include "qgsproject.h"
27 
28 namespace QgsWms
29 {
30 
31  void writeDescribeLayer( QgsServerInterface *serverIface, const QgsProject *project, const QString &version,
32  const QgsServerRequest &request, QgsServerResponse &response )
33  {
34  QDomDocument doc = describeLayer( serverIface, project, version, request );
35  response.setHeader( QStringLiteral( "Content-Type" ), QStringLiteral( "text/xml; charset=utf-8" ) );
36  response.write( doc.toByteArray() );
37  }
38 
39  // DescribeLayer is defined for WMS1.1.1/SLD1.0 and in WMS 1.3.0 SLD Extension
40  QDomDocument describeLayer( QgsServerInterface *serverIface, const QgsProject *project, const QString &version,
41  const QgsServerRequest &request )
42  {
43  Q_UNUSED( version )
44 
45  QgsServerRequest::Parameters parameters = request.parameters();
46 
47  if ( !parameters.contains( QStringLiteral( "SLD_VERSION" ) ) )
48  {
49  throw QgsServiceException( QStringLiteral( "MissingParameterValue" ),
50  QStringLiteral( "SLD_VERSION is mandatory for DescribeLayer operation" ), 400 );
51  }
52  if ( parameters[ QStringLiteral( "SLD_VERSION" )] != QLatin1String( "1.1.0" ) )
53  {
54  throw QgsServiceException( QStringLiteral( "InvalidParameterValue" ),
55  QStringLiteral( "SLD_VERSION = %1 is not supported" ).arg( parameters[ QStringLiteral( "SLD_VERSION" )] ), 400 );
56  }
57 
58  if ( !parameters.contains( QStringLiteral( "LAYERS" ) ) )
59  {
60  throw QgsServiceException( QStringLiteral( "MissingParameterValue" ),
61  QStringLiteral( "LAYERS is mandatory for DescribeLayer operation" ), 400 );
62  }
63 
64  QStringList layersList = parameters[ QStringLiteral( "LAYERS" )].split( ',', QString::SkipEmptyParts );
65  if ( layersList.isEmpty() )
66  {
67  throw QgsServiceException( QStringLiteral( "InvalidParameterValue" ), QStringLiteral( "Layers is empty" ), 400 );
68  }
69  QDomDocument myDocument = QDomDocument();
70 
71  QDomNode header = myDocument.createProcessingInstruction( QStringLiteral( "xml" ), QStringLiteral( "version=\"1.0\" encoding=\"UTF-8\"" ) );
72  myDocument.appendChild( header );
73 
74  // Create the root element
75  QDomElement root = myDocument.createElementNS( QStringLiteral( "http://www.opengis.net/sld" ), QStringLiteral( "DescribeLayerResponse" ) );
76  root.setAttribute( QStringLiteral( "xsi:schemaLocation" ), QStringLiteral( "http://www.opengis.net/sld http://schemas.opengis.net/sld/1.1.0/DescribeLayer.xsd" ) );
77  root.setAttribute( QStringLiteral( "xmlns:ows" ), QStringLiteral( "http://www.opengis.net/ows" ) );
78  root.setAttribute( QStringLiteral( "xmlns:se" ), QStringLiteral( "http://www.opengis.net/se" ) );
79  root.setAttribute( QStringLiteral( "xmlns:xlink" ), QStringLiteral( "http://www.w3.org/1999/xlink" ) );
80  root.setAttribute( QStringLiteral( "xmlns:xsi" ), QStringLiteral( "http://www.w3.org/2001/XMLSchema-instance" ) );
81  myDocument.appendChild( root );
82 
83  // store the Version element
84  QDomElement versionNode = myDocument.createElement( QStringLiteral( "Version" ) );
85  versionNode.appendChild( myDocument.createTextNode( QStringLiteral( "1.1.0" ) ) );
86  root.appendChild( versionNode );
87 
88  // get the wms service url defined in project or keep the one from the
89  // request url
90  QString wmsHrefString = serviceUrl( request, project ).toString();
91 
92  // get the wfs service url defined in project or take the same as the
93  // wms service url
94  QString wfsHrefString = QgsServerProjectUtils::wfsServiceUrl( *project );
95  if ( wfsHrefString.isEmpty() )
96  {
97  wfsHrefString = wmsHrefString;
98  }
99 
100  // get the wcs service url defined in project or take the same as the
101  // wms service url
102  QString wcsHrefString = QgsServerProjectUtils::wcsServiceUrl( *project );
103  if ( wcsHrefString.isEmpty() )
104  {
105  wcsHrefString = wmsHrefString;
106  }
107 
108  // access control
109 #ifdef HAVE_SERVER_PYTHON_PLUGINS
110  QgsAccessControl *accessControl = serverIface->accessControls();
111 #else
112  ( void )serverIface;
113 #endif
114  // Use layer ids
115  bool useLayerIds = QgsServerProjectUtils::wmsUseLayerIds( *project );
116  // WMS restricted layers
117  QStringList restrictedLayers = QgsServerProjectUtils::wmsRestrictedLayers( *project );
118  // WFS layers
119  QStringList wfsLayerIds = QgsServerProjectUtils::wfsLayerIds( *project );
120  // WCS layers
121  QStringList wcsLayerIds = QgsServerProjectUtils::wcsLayerIds( *project );
122 
123  for ( QgsMapLayer *layer : project->mapLayers() )
124  {
125  QString name = layer->name();
126  if ( useLayerIds )
127  name = layer->id();
128  else if ( !layer->shortName().isEmpty() )
129  name = layer->shortName();
130 
131  if ( !layersList.contains( name ) )
132  {
133  continue;
134  }
135 
136  //unpublished layer
137  if ( restrictedLayers.contains( layer->name() ) )
138  {
139  throw QgsSecurityException( QStringLiteral( "You are not allowed to access to this layer" ) );
140  }
141 
142 #ifdef HAVE_SERVER_PYTHON_PLUGINS
143  if ( accessControl && !accessControl->layerReadPermission( layer ) )
144  {
145  throw QgsSecurityException( QStringLiteral( "You are not allowed to access to this layer" ) );
146  }
147 #endif
148 
149  // Create the NamedLayer element
150  QDomElement layerNode = myDocument.createElement( QStringLiteral( "LayerDescription" ) );
151  root.appendChild( layerNode );
152 
153  // store the owsType element
154  QDomElement typeNode = myDocument.createElement( QStringLiteral( "owsType" ) );
155  // store the se:OnlineResource element
156  QDomElement oResNode = myDocument.createElement( QStringLiteral( "se:OnlineResource" ) );
157  oResNode.setAttribute( QStringLiteral( "xlink:type" ), QStringLiteral( "simple" ) );
158  // store the TypeName element
159  QDomElement nameNode = myDocument.createElement( QStringLiteral( "TypeName" ) );
160  switch ( layer->type() )
161  {
163  {
164  typeNode.appendChild( myDocument.createTextNode( QStringLiteral( "wfs" ) ) );
165 
166  if ( wfsLayerIds.indexOf( layer->id() ) != -1 )
167  {
168  oResNode.setAttribute( QStringLiteral( "xlink:href" ), wfsHrefString );
169  }
170 
171  // store the se:FeatureTypeName element
172  QDomElement typeNameNode = myDocument.createElement( QStringLiteral( "se:FeatureTypeName" ) );
173  typeNameNode.appendChild( myDocument.createTextNode( name ) );
174  nameNode.appendChild( typeNameNode );
175  break;
176  }
178  {
179  typeNode.appendChild( myDocument.createTextNode( QStringLiteral( "wcs" ) ) );
180 
181  if ( wcsLayerIds.indexOf( layer->id() ) != -1 )
182  {
183  oResNode.setAttribute( QStringLiteral( "xlink:href" ), wcsHrefString );
184  }
185 
186  // store the se:CoverageTypeName element
187  QDomElement typeNameNode = myDocument.createElement( QStringLiteral( "se:CoverageTypeName" ) );
188  typeNameNode.appendChild( myDocument.createTextNode( name ) );
189  nameNode.appendChild( typeNameNode );
190  break;
191  }
192 
198  break;
199  }
200  layerNode.appendChild( typeNode );
201  layerNode.appendChild( oResNode );
202  layerNode.appendChild( nameNode );
203  }
204 
205  return myDocument;
206  }
207 
208 } // namespace QgsWms
A helper class that centralizes restrictions given by all the access control filter plugins.
bool layerReadPermission(const QgsMapLayer *layer) const
Returns the layer read right.
Base class for all map layer types.
Definition: qgsmaplayer.h:85
Encapsulates a QGIS project, including sets of map layers and their styles, layouts,...
Definition: qgsproject.h:99
QMap< QString, QgsMapLayer * > mapLayers(const bool validOnly=false) const
Returns a map of all registered layers by layer ID.
QgsServerInterface Class defining interfaces exposed by QGIS Server and made available to plugins.
virtual QgsAccessControl * accessControls() const =0
Gets the registered access control filters.
QgsServerRequest Class defining request interface passed to services QgsService::executeRequest() met...
QgsServerRequest::Parameters parameters() const
Returns a map of query parameters with keys converted to uppercase.
QMap< QString, QString > Parameters
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...
Exception thrown when data access violates access controls.
Exception class for WMS service exceptions.
@ PointCloudLayer
Added in 3.18.
@ MeshLayer
Added in 3.2.
@ VectorTileLayer
Added in 3.14.
@ AnnotationLayer
Contains freeform, georeferenced annotations. Added in QGIS 3.16.
SERVER_EXPORT QString wcsServiceUrl(const QgsProject &project)
Returns the WCS service url defined in a QGIS project.
SERVER_EXPORT QString wfsServiceUrl(const QgsProject &project)
Returns the WFS service url defined in a QGIS project.
SERVER_EXPORT bool wmsUseLayerIds(const QgsProject &project)
Returns if layer ids are used as name in WMS.
SERVER_EXPORT QStringList wfsLayerIds(const QgsProject &project)
Returns the Layer ids list defined in a QGIS project as published in WFS.
SERVER_EXPORT QStringList wmsRestrictedLayers(const QgsProject &project)
Returns the restricted layer name list.
SERVER_EXPORT QStringList wcsLayerIds(const QgsProject &project)
Returns the Layer ids list defined in a QGIS project as published in WCS.
Median cut implementation.
QDomDocument describeLayer(QgsServerInterface *serverIface, const QgsProject *project, const QString &version, const QgsServerRequest &request)
DescribeLayer is defined for WMS1.1.1/SLD1.0 and in WMS 1.3.0 SLD Extension.
void writeDescribeLayer(QgsServerInterface *serverIface, const QgsProject *project, const QString &version, const QgsServerRequest &request, QgsServerResponse &response)
Output GetMap response in DXF format.
QUrl serviceUrl(const QgsServerRequest &request, const QgsProject *project)
Returns WMS service URL.
Definition: qgswmsutils.cpp:32