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