QGIS API Documentation 3.37.0-Master (fdefdf9c27f)
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 "qgswmsrequest.h"
25#include "qgswmsdescribelayer.h"
27#include "qgsproject.h"
28
29namespace QgsWms
30{
31
32 void writeDescribeLayer( QgsServerInterface *serverIface, const QgsProject *project,
33 const QgsWmsRequest &request, QgsServerResponse &response )
34 {
35 const QDomDocument doc = describeLayer( serverIface, project, request );
36 response.setHeader( QStringLiteral( "Content-Type" ), QStringLiteral( "text/xml; charset=utf-8" ) );
37 response.write( doc.toByteArray() );
38 }
39
40 // DescribeLayer is defined for WMS1.1.1/SLD1.0 and in WMS 1.3.0 SLD Extension
41 QDomDocument describeLayer( QgsServerInterface *serverIface, const QgsProject *project,
42 const QgsWmsRequest &request )
43 {
44 const 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" ) ) && !parameters.contains( QStringLiteral( "LAYER" ) ) )
58 {
59 throw QgsServiceException( QStringLiteral( "MissingParameterValue" ),
60 QStringLiteral( "LAYERS or LAYER is mandatory for DescribeLayer operation" ), 400 );
61 }
62
63 QStringList layersList;
64
65 if ( parameters.contains( QStringLiteral( "LAYERS" ) ) )
66 {
67 layersList = parameters[ QStringLiteral( "LAYERS" )].split( ',', Qt::SkipEmptyParts );
68 }
69 else
70 {
71 layersList = parameters[ QStringLiteral( "LAYER" )].split( ',', Qt::SkipEmptyParts );
72 }
73 if ( layersList.isEmpty() )
74 {
75 throw QgsServiceException( QStringLiteral( "InvalidParameterValue" ), QStringLiteral( "Layers is empty" ), 400 );
76 }
77 QDomDocument myDocument = QDomDocument();
78
79 const QDomNode header = myDocument.createProcessingInstruction( QStringLiteral( "xml" ), QStringLiteral( "version=\"1.0\" encoding=\"UTF-8\"" ) );
80 myDocument.appendChild( header );
81
82 // Create the root element
83 QDomElement root = myDocument.createElementNS( QStringLiteral( "http://www.opengis.net/sld" ), QStringLiteral( "DescribeLayerResponse" ) );
84 root.setAttribute( QStringLiteral( "xsi:schemaLocation" ), QStringLiteral( "http://www.opengis.net/sld http://schemas.opengis.net/sld/1.1.0/DescribeLayer.xsd" ) );
85 root.setAttribute( QStringLiteral( "xmlns:ows" ), QStringLiteral( "http://www.opengis.net/ows" ) );
86 root.setAttribute( QStringLiteral( "xmlns:se" ), QStringLiteral( "http://www.opengis.net/se" ) );
87 root.setAttribute( QStringLiteral( "xmlns:xlink" ), QStringLiteral( "http://www.w3.org/1999/xlink" ) );
88 root.setAttribute( QStringLiteral( "xmlns:xsi" ), QStringLiteral( "http://www.w3.org/2001/XMLSchema-instance" ) );
89 myDocument.appendChild( root );
90
91 // store the Version element
92 QDomElement versionNode = myDocument.createElement( QStringLiteral( "Version" ) );
93 versionNode.appendChild( myDocument.createTextNode( QStringLiteral( "1.1.0" ) ) );
94 root.appendChild( versionNode );
95
96 // get the wms service url defined in project or keep the one from the
97 // request url
98 const QString wmsHrefString = serviceUrl( request, project, *serverIface->serverSettings() ).toString();
99
100 // get the wfs service url defined in project or take the same as the
101 // wms service url
102 QString wfsHrefString = QgsServerProjectUtils::wfsServiceUrl( *project, request, *serverIface->serverSettings() );
103 if ( wfsHrefString.isEmpty() )
104 {
105 wfsHrefString = wmsHrefString;
106 }
107
108 // get the wcs service url defined in project or take the same as the
109 // wms service url
110 QString wcsHrefString = QgsServerProjectUtils::wcsServiceUrl( *project, request, *serverIface->serverSettings() );
111 if ( wcsHrefString.isEmpty() )
112 {
113 wcsHrefString = wmsHrefString;
114 }
115
116 // access control
117#ifdef HAVE_SERVER_PYTHON_PLUGINS
118 QgsAccessControl *accessControl = serverIface->accessControls();
119#else
120 ( void )serverIface;
121#endif
122 // Use layer ids
123 const bool useLayerIds = QgsServerProjectUtils::wmsUseLayerIds( *project );
124 // WMS restricted layers
125 const QStringList restrictedLayers = QgsServerProjectUtils::wmsRestrictedLayers( *project );
126 // WFS layers
127 const QStringList wfsLayerIds = QgsServerProjectUtils::wfsLayerIds( *project );
128 // WCS layers
129 const QStringList wcsLayerIds = QgsServerProjectUtils::wcsLayerIds( *project );
130
131 for ( QgsMapLayer *layer : project->mapLayers() )
132 {
133 QString name = layer->name();
134 if ( useLayerIds )
135 name = layer->id();
136 else if ( !layer->shortName().isEmpty() )
137 name = layer->shortName();
138
139 if ( !layersList.contains( name ) )
140 {
141 continue;
142 }
143
144 //unpublished layer
145 if ( restrictedLayers.contains( layer->name() ) )
146 {
147 throw QgsSecurityException( QStringLiteral( "You are not allowed to access to this layer" ) );
148 }
149
150#ifdef HAVE_SERVER_PYTHON_PLUGINS
151 if ( accessControl && !accessControl->layerReadPermission( layer ) )
152 {
153 throw QgsSecurityException( QStringLiteral( "You are not allowed to access to this layer" ) );
154 }
155#endif
156
157 // Create the NamedLayer element
158 QDomElement layerNode = myDocument.createElement( QStringLiteral( "LayerDescription" ) );
159 root.appendChild( layerNode );
160
161 // store the owsType element
162 QDomElement typeNode = myDocument.createElement( QStringLiteral( "owsType" ) );
163 // store the se:OnlineResource element
164 QDomElement oResNode = myDocument.createElement( QStringLiteral( "se:OnlineResource" ) );
165 oResNode.setAttribute( QStringLiteral( "xlink:type" ), QStringLiteral( "simple" ) );
166 // store the TypeName element
167 QDomElement nameNode = myDocument.createElement( QStringLiteral( "TypeName" ) );
168 switch ( layer->type() )
169 {
171 {
172 typeNode.appendChild( myDocument.createTextNode( QStringLiteral( "wfs" ) ) );
173
174 if ( wfsLayerIds.indexOf( layer->id() ) != -1 )
175 {
176 oResNode.setAttribute( QStringLiteral( "xlink:href" ), wfsHrefString );
177 }
178
179 // store the se:FeatureTypeName element
180 QDomElement typeNameNode = myDocument.createElement( QStringLiteral( "se:FeatureTypeName" ) );
181 typeNameNode.appendChild( myDocument.createTextNode( name ) );
182 nameNode.appendChild( typeNameNode );
183 break;
184 }
186 {
187 typeNode.appendChild( myDocument.createTextNode( QStringLiteral( "wcs" ) ) );
188
189 if ( wcsLayerIds.indexOf( layer->id() ) != -1 )
190 {
191 oResNode.setAttribute( QStringLiteral( "xlink:href" ), wcsHrefString );
192 }
193
194 // store the se:CoverageTypeName element
195 QDomElement typeNameNode = myDocument.createElement( QStringLiteral( "se:CoverageTypeName" ) );
196 typeNameNode.appendChild( myDocument.createTextNode( name ) );
197 nameNode.appendChild( typeNameNode );
198 break;
199 }
200
208 break;
209 }
210 layerNode.appendChild( typeNode );
211 layerNode.appendChild( oResNode );
212 layerNode.appendChild( nameNode );
213 }
214
215 return myDocument;
216 }
217
218} // namespace QgsWms
@ Group
Composite group layer. Added in QGIS 3.24.
@ Plugin
Plugin based layer.
@ TiledScene
Tiled scene layer. Added in QGIS 3.34.
@ Annotation
Contains freeform, georeferenced annotations. Added in QGIS 3.16.
@ Vector
Vector layer.
@ VectorTile
Vector tile layer. Added in QGIS 3.14.
@ Mesh
Mesh layer. Added in QGIS 3.2.
@ Raster
Raster layer.
@ PointCloud
Point cloud layer. Added in QGIS 3.18.
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:75
Encapsulates a QGIS project, including sets of map layers and their styles, layouts,...
Definition: qgsproject.h:107
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.
virtual QgsServerSettings * serverSettings()=0
Returns the server settings.
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.
Class defining request interface passed to WMS service.
Definition: qgswmsrequest.h:35
SERVER_EXPORT QString wcsServiceUrl(const QgsProject &project, const QgsServerRequest &request=QgsServerRequest(), const QgsServerSettings &settings=QgsServerSettings())
Returns the WCS service url.
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 QString wfsServiceUrl(const QgsProject &project, const QgsServerRequest &request=QgsServerRequest(), const QgsServerSettings &settings=QgsServerSettings())
Returns the WFS service url.
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 QgsWmsRequest &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 QgsWmsRequest &request, QgsServerResponse &response)
Output GetMap response in DXF format.
QUrl serviceUrl(const QgsServerRequest &request, const QgsProject *project, const QgsServerSettings &settings)
Returns WMS service URL.
Definition: qgswmsutils.cpp:38