QGIS API Documentation 3.28.0-Firenze (ed3ad0430f)
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" ) ) )
58 {
59 throw QgsServiceException( QStringLiteral( "MissingParameterValue" ),
60 QStringLiteral( "LAYERS is mandatory for DescribeLayer operation" ), 400 );
61 }
62
63#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
64 QStringList layersList = parameters[ QStringLiteral( "LAYERS" )].split( ',', QString::SkipEmptyParts );
65#else
66 const QStringList layersList = parameters[ QStringLiteral( "LAYERS" )].split( ',', Qt::SkipEmptyParts );
67#endif
68 if ( layersList.isEmpty() )
69 {
70 throw QgsServiceException( QStringLiteral( "InvalidParameterValue" ), QStringLiteral( "Layers is empty" ), 400 );
71 }
72 QDomDocument myDocument = QDomDocument();
73
74 const QDomNode header = myDocument.createProcessingInstruction( QStringLiteral( "xml" ), QStringLiteral( "version=\"1.0\" encoding=\"UTF-8\"" ) );
75 myDocument.appendChild( header );
76
77 // Create the root element
78 QDomElement root = myDocument.createElementNS( QStringLiteral( "http://www.opengis.net/sld" ), QStringLiteral( "DescribeLayerResponse" ) );
79 root.setAttribute( QStringLiteral( "xsi:schemaLocation" ), QStringLiteral( "http://www.opengis.net/sld http://schemas.opengis.net/sld/1.1.0/DescribeLayer.xsd" ) );
80 root.setAttribute( QStringLiteral( "xmlns:ows" ), QStringLiteral( "http://www.opengis.net/ows" ) );
81 root.setAttribute( QStringLiteral( "xmlns:se" ), QStringLiteral( "http://www.opengis.net/se" ) );
82 root.setAttribute( QStringLiteral( "xmlns:xlink" ), QStringLiteral( "http://www.w3.org/1999/xlink" ) );
83 root.setAttribute( QStringLiteral( "xmlns:xsi" ), QStringLiteral( "http://www.w3.org/2001/XMLSchema-instance" ) );
84 myDocument.appendChild( root );
85
86 // store the Version element
87 QDomElement versionNode = myDocument.createElement( QStringLiteral( "Version" ) );
88 versionNode.appendChild( myDocument.createTextNode( QStringLiteral( "1.1.0" ) ) );
89 root.appendChild( versionNode );
90
91 // get the wms service url defined in project or keep the one from the
92 // request url
93 const QString wmsHrefString = serviceUrl( request, project, *serverIface->serverSettings() ).toString();
94
95 // get the wfs service url defined in project or take the same as the
96 // wms service url
97 QString wfsHrefString = QgsServerProjectUtils::wfsServiceUrl( *project, request, *serverIface->serverSettings() );
98 if ( wfsHrefString.isEmpty() )
99 {
100 wfsHrefString = wmsHrefString;
101 }
102
103 // get the wcs service url defined in project or take the same as the
104 // wms service url
105 QString wcsHrefString = QgsServerProjectUtils::wcsServiceUrl( *project, request, *serverIface->serverSettings() );
106 if ( wcsHrefString.isEmpty() )
107 {
108 wcsHrefString = wmsHrefString;
109 }
110
111 // access control
112#ifdef HAVE_SERVER_PYTHON_PLUGINS
113 QgsAccessControl *accessControl = serverIface->accessControls();
114#else
115 ( void )serverIface;
116#endif
117 // Use layer ids
118 const bool useLayerIds = QgsServerProjectUtils::wmsUseLayerIds( *project );
119 // WMS restricted layers
120 const QStringList restrictedLayers = QgsServerProjectUtils::wmsRestrictedLayers( *project );
121 // WFS layers
122 const QStringList wfsLayerIds = QgsServerProjectUtils::wfsLayerIds( *project );
123 // WCS layers
124 const QStringList wcsLayerIds = QgsServerProjectUtils::wcsLayerIds( *project );
125
126 for ( QgsMapLayer *layer : project->mapLayers() )
127 {
128 QString name = layer->name();
129 if ( useLayerIds )
130 name = layer->id();
131 else if ( !layer->shortName().isEmpty() )
132 name = layer->shortName();
133
134 if ( !layersList.contains( name ) )
135 {
136 continue;
137 }
138
139 //unpublished layer
140 if ( restrictedLayers.contains( layer->name() ) )
141 {
142 throw QgsSecurityException( QStringLiteral( "You are not allowed to access to this layer" ) );
143 }
144
145#ifdef HAVE_SERVER_PYTHON_PLUGINS
146 if ( accessControl && !accessControl->layerReadPermission( layer ) )
147 {
148 throw QgsSecurityException( QStringLiteral( "You are not allowed to access to this layer" ) );
149 }
150#endif
151
152 // Create the NamedLayer element
153 QDomElement layerNode = myDocument.createElement( QStringLiteral( "LayerDescription" ) );
154 root.appendChild( layerNode );
155
156 // store the owsType element
157 QDomElement typeNode = myDocument.createElement( QStringLiteral( "owsType" ) );
158 // store the se:OnlineResource element
159 QDomElement oResNode = myDocument.createElement( QStringLiteral( "se:OnlineResource" ) );
160 oResNode.setAttribute( QStringLiteral( "xlink:type" ), QStringLiteral( "simple" ) );
161 // store the TypeName element
162 QDomElement nameNode = myDocument.createElement( QStringLiteral( "TypeName" ) );
163 switch ( layer->type() )
164 {
166 {
167 typeNode.appendChild( myDocument.createTextNode( QStringLiteral( "wfs" ) ) );
168
169 if ( wfsLayerIds.indexOf( layer->id() ) != -1 )
170 {
171 oResNode.setAttribute( QStringLiteral( "xlink:href" ), wfsHrefString );
172 }
173
174 // store the se:FeatureTypeName element
175 QDomElement typeNameNode = myDocument.createElement( QStringLiteral( "se:FeatureTypeName" ) );
176 typeNameNode.appendChild( myDocument.createTextNode( name ) );
177 nameNode.appendChild( typeNameNode );
178 break;
179 }
181 {
182 typeNode.appendChild( myDocument.createTextNode( QStringLiteral( "wcs" ) ) );
183
184 if ( wcsLayerIds.indexOf( layer->id() ) != -1 )
185 {
186 oResNode.setAttribute( QStringLiteral( "xlink:href" ), wcsHrefString );
187 }
188
189 // store the se:CoverageTypeName element
190 QDomElement typeNameNode = myDocument.createElement( QStringLiteral( "se:CoverageTypeName" ) );
191 typeNameNode.appendChild( myDocument.createTextNode( name ) );
192 nameNode.appendChild( typeNameNode );
193 break;
194 }
195
202 break;
203 }
204 layerNode.appendChild( typeNode );
205 layerNode.appendChild( oResNode );
206 layerNode.appendChild( nameNode );
207 }
208
209 return myDocument;
210 }
211
212} // 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:73
Encapsulates a QGIS project, including sets of map layers and their styles, layouts,...
Definition: qgsproject.h:104
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
@ PointCloudLayer
Point cloud layer. Added in QGIS 3.18.
@ MeshLayer
Mesh layer. Added in QGIS 3.2.
@ VectorLayer
Vector layer.
@ RasterLayer
Raster layer.
@ GroupLayer
Composite group layer. Added in QGIS 3.24.
@ VectorTileLayer
Vector tile layer. Added in QGIS 3.14.
@ AnnotationLayer
Contains freeform, georeferenced annotations. Added in QGIS 3.16.
@ PluginLayer
Plugin based layer.
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