QGIS API Documentation  3.8.0-Zanzibar (11aff65)
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 
195  break;
196  }
197  layerNode.appendChild( typeNode );
198  layerNode.appendChild( oResNode );
199  layerNode.appendChild( nameNode );
200  }
201 
202  return myDocument;
203  }
204 
205 } // namespace QgsWms
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:78
virtual void write(const QString &data)
Write string This is a convenient method that will write directly to the underlying I/O device...
Exception class for WMS service exceptions.
QgsServerRequest::Parameters parameters() const
Returns a map of query parameters with keys converted to uppercase.
SERVER_EXPORT QStringList wcsLayerIds(const QgsProject &project)
Returns the Layer ids list defined in a QGIS project as published in WCS.
Reads and writes project states.
Definition: qgsproject.h:89
QMap< QString, QgsMapLayer * > mapLayers(const bool validOnly=false) const
Returns a map of all registered layers by layer ID.
Median cut implementation.
QgsServerRequest Class defining request interface passed to services QgsService::executeRequest() met...
bool layerReadPermission(const QgsMapLayer *layer) const
Returns the layer read right.
QgsServerInterface Class defining interfaces exposed by QGIS Server and made available to plugins...
SERVER_EXPORT QString wcsServiceUrl(const QgsProject &project)
Returns the WCS service url defined in a QGIS project.
Exception thrown when data access violates access controls.
SERVER_EXPORT QStringList wfsLayerIds(const QgsProject &project)
Returns the Layer ids list defined in a QGIS project as published in WFS.
QUrl serviceUrl(const QgsServerRequest &request, const QgsProject *project)
Returns WMS service URL.
Definition: qgswmsutils.cpp:32
A helper class that centralizes restrictions given by all the access control filter plugins...
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.
QgsServerResponse Class defining response interface passed to services QgsService::executeRequest() m...
virtual QgsAccessControl * accessControls() const =0
Gets the registered access control filters.
void writeDescribeLayer(QgsServerInterface *serverIface, const QgsProject *project, const QString &version, const QgsServerRequest &request, QgsServerResponse &response)
Output GetMap response in DXF format.
SERVER_EXPORT QStringList wmsRestrictedLayers(const QgsProject &project)
Returns the restricted layer name list.
SERVER_EXPORT QString wfsServiceUrl(const QgsProject &project)
Returns the WFS service url defined in a QGIS project.
QMap< QString, QString > Parameters
SERVER_EXPORT bool wmsUseLayerIds(const QgsProject &project)
Returns if layer ids are used as name in WMS.