QGIS API Documentation  3.6.0-Noosa (5873452)
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 #endif
112  // Use layer ids
113  bool useLayerIds = QgsServerProjectUtils::wmsUseLayerIds( *project );
114  // WMS restricted layers
115  QStringList restrictedLayers = QgsServerProjectUtils::wmsRestrictedLayers( *project );
116  // WFS layers
117  QStringList wfsLayerIds = QgsServerProjectUtils::wfsLayerIds( *project );
118  // WCS layers
119  QStringList wcsLayerIds = QgsServerProjectUtils::wcsLayerIds( *project );
120 
121  for ( QgsMapLayer *layer : project->mapLayers() )
122  {
123  QString name = layer->name();
124  if ( useLayerIds )
125  name = layer->id();
126  else if ( !layer->shortName().isEmpty() )
127  name = layer->shortName();
128 
129  if ( !layersList.contains( name ) )
130  {
131  continue;
132  }
133 
134  //unpublished layer
135  if ( restrictedLayers.contains( layer->name() ) )
136  {
137  throw QgsSecurityException( QStringLiteral( "You are not allowed to access to this layer" ) );
138  }
139 
140 #ifdef HAVE_SERVER_PYTHON_PLUGINS
141  if ( accessControl && !accessControl->layerReadPermission( layer ) )
142  {
143  throw QgsSecurityException( QStringLiteral( "You are not allowed to access to this layer" ) );
144  }
145 #endif
146 
147  // Create the NamedLayer element
148  QDomElement layerNode = myDocument.createElement( QStringLiteral( "LayerDescription" ) );
149  root.appendChild( layerNode );
150 
151  // store the owsType element
152  QDomElement typeNode = myDocument.createElement( QStringLiteral( "owsType" ) );
153  // store the se:OnlineResource element
154  QDomElement oResNode = myDocument.createElement( QStringLiteral( "se:OnlineResource" ) );
155  oResNode.setAttribute( QStringLiteral( "xlink:type" ), QStringLiteral( "simple" ) );
156  // store the TypeName element
157  QDomElement nameNode = myDocument.createElement( QStringLiteral( "TypeName" ) );
158  switch ( layer->type() )
159  {
161  {
162  typeNode.appendChild( myDocument.createTextNode( QStringLiteral( "wfs" ) ) );
163 
164  if ( wfsLayerIds.indexOf( layer->id() ) != -1 )
165  {
166  oResNode.setAttribute( QStringLiteral( "xlink:href" ), wfsHrefString );
167  }
168 
169  // store the se:FeatureTypeName element
170  QDomElement typeNameNode = myDocument.createElement( QStringLiteral( "se:FeatureTypeName" ) );
171  typeNameNode.appendChild( myDocument.createTextNode( name ) );
172  nameNode.appendChild( typeNameNode );
173  break;
174  }
176  {
177  typeNode.appendChild( myDocument.createTextNode( QStringLiteral( "wcs" ) ) );
178 
179  if ( wcsLayerIds.indexOf( layer->id() ) != -1 )
180  {
181  oResNode.setAttribute( QStringLiteral( "xlink:href" ), wcsHrefString );
182  }
183 
184  // store the se:CoverageTypeName element
185  QDomElement typeNameNode = myDocument.createElement( QStringLiteral( "se:CoverageTypeName" ) );
186  typeNameNode.appendChild( myDocument.createTextNode( name ) );
187  nameNode.appendChild( typeNameNode );
188  break;
189  }
190 
193  break;
194  }
195  layerNode.appendChild( typeNode );
196  layerNode.appendChild( oResNode );
197  layerNode.appendChild( nameNode );
198  }
199 
200  return myDocument;
201  }
202 
203 } // 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:64
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.
Added in 3.2.
Definition: qgsmaplayer.h:111
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:37
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.