QGIS API Documentation 3.28.0-Firenze (ed3ad0430f)
qgswcsgetcapabilities.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgswcsgecapabilities.cpp
3 -------------------------
4 begin : January 16 , 2017
5 copyright : (C) 2013 by René-Luc D'Hont ( parts from qgswcsserver )
6 (C) 2017 by David Marteau
7 email : rldhont at 3liz dot com
8 david dot marteau at 3liz dot com
9 ***************************************************************************/
10
11/***************************************************************************
12 * *
13 * This program is free software; you can redistribute it and/or modify *
14 * it under the terms of the GNU General Public License as published by *
15 * the Free Software Foundation; either version 2 of the License, or *
16 * (at your option) any later version. *
17 * *
18 ***************************************************************************/
19#include "qgswcsutils.h"
22
23#include "qgsproject.h"
24#include "qgsrasterlayer.h"
25
26namespace QgsWcs
27{
28
32 void writeGetCapabilities( QgsServerInterface *serverIface, const QgsProject *project, const QString &version,
33 const QgsServerRequest &request, QgsServerResponse &response )
34 {
35#ifdef HAVE_SERVER_PYTHON_PLUGINS
36 QgsAccessControl *accessControl = serverIface->accessControls();
37#endif
38 QDomDocument doc;
39 const QDomDocument *capabilitiesDocument = nullptr;
40
41#ifdef HAVE_SERVER_PYTHON_PLUGINS
42 QgsServerCacheManager *cacheManager = serverIface->cacheManager();
43 if ( cacheManager && cacheManager->getCachedDocument( &doc, project, request, accessControl ) )
44 {
45 capabilitiesDocument = &doc;
46 }
47 else //capabilities xml not in cache. Create a new one
48 {
49 doc = createGetCapabilitiesDocument( serverIface, project, version, request );
50
51 if ( cacheManager )
52 {
53 cacheManager->setCachedDocument( &doc, project, request, accessControl );
54 }
55 capabilitiesDocument = &doc;
56 }
57#else
58 doc = createGetCapabilitiesDocument( serverIface, project, version, request );
59 capabilitiesDocument = &doc;
60#endif
61 response.setHeader( QStringLiteral( "Content-Type" ), QStringLiteral( "text/xml; charset=utf-8" ) );
62 response.write( capabilitiesDocument->toByteArray() );
63 }
64
65
66 QDomDocument createGetCapabilitiesDocument( QgsServerInterface *serverIface, const QgsProject *project, const QString &version,
67 const QgsServerRequest &request )
68 {
69 Q_UNUSED( version )
70
71 QDomDocument doc;
72
73 //wcs:WCS_Capabilities element
74 QDomElement wcsCapabilitiesElement = doc.createElement( QStringLiteral( "WCS_Capabilities" )/*wcs:WCS_Capabilities*/ );
75 wcsCapabilitiesElement.setAttribute( QStringLiteral( "xmlns" ), WCS_NAMESPACE );
76 wcsCapabilitiesElement.setAttribute( QStringLiteral( "xmlns:xsi" ), QStringLiteral( "http://www.w3.org/2001/XMLSchema-instance" ) );
77 wcsCapabilitiesElement.setAttribute( QStringLiteral( "xsi:schemaLocation" ), WCS_NAMESPACE + " http://schemas.opengis.net/wcs/1.0.0/wcsCapabilities.xsd" );
78 wcsCapabilitiesElement.setAttribute( QStringLiteral( "xmlns:gml" ), GML_NAMESPACE );
79 wcsCapabilitiesElement.setAttribute( QStringLiteral( "xmlns:xlink" ), QStringLiteral( "http://www.w3.org/1999/xlink" ) );
80 wcsCapabilitiesElement.setAttribute( QStringLiteral( "version" ), implementationVersion() );
81 wcsCapabilitiesElement.setAttribute( QStringLiteral( "updateSequence" ), QStringLiteral( "0" ) );
82 doc.appendChild( wcsCapabilitiesElement );
83
84 //INSERT Service
85 wcsCapabilitiesElement.appendChild( getServiceElement( doc, project ) );
86
87 //wcs:Capability element
88 QDomElement capabilityElement = doc.createElement( QStringLiteral( "Capability" )/*wcs:Capability*/ );
89 wcsCapabilitiesElement.appendChild( capabilityElement );
90
91 //wcs:Request element
92 QDomElement requestElement = doc.createElement( QStringLiteral( "Request" )/*wcs:Request*/ );
93 capabilityElement.appendChild( requestElement );
94
95 //wcs:GetCapabilities
96 QDomElement getCapabilitiesElement = doc.createElement( QStringLiteral( "GetCapabilities" )/*wcs:GetCapabilities*/ );
97 requestElement.appendChild( getCapabilitiesElement );
98
99 QDomElement dcpTypeElement = doc.createElement( QStringLiteral( "DCPType" )/*wcs:DCPType*/ );
100 getCapabilitiesElement.appendChild( dcpTypeElement );
101 QDomElement httpElement = doc.createElement( QStringLiteral( "HTTP" )/*wcs:HTTP*/ );
102 dcpTypeElement.appendChild( httpElement );
103
104 //Prepare url
105 const QString hrefString = serviceUrl( request, project, *serverIface->serverSettings() );
106
107 QDomElement getElement = doc.createElement( QStringLiteral( "Get" )/*wcs:Get*/ );
108 httpElement.appendChild( getElement );
109 QDomElement onlineResourceElement = doc.createElement( QStringLiteral( "OnlineResource" )/*wcs:OnlineResource*/ );
110 onlineResourceElement.setAttribute( QStringLiteral( "xlink:type" ), QStringLiteral( "simple" ) );
111 onlineResourceElement.setAttribute( QStringLiteral( "xlink:href" ), hrefString );
112 getElement.appendChild( onlineResourceElement );
113
114 const QDomElement getCapabilitiesDhcTypePostElement = dcpTypeElement.cloneNode().toElement();//this is the same as for 'GetCapabilities'
115 getCapabilitiesDhcTypePostElement.firstChild().firstChild().toElement().setTagName( QStringLiteral( "Post" ) );
116 getCapabilitiesElement.appendChild( getCapabilitiesDhcTypePostElement );
117
118 QDomElement describeCoverageElement = getCapabilitiesElement.cloneNode().toElement();//this is the same as 'GetCapabilities'
119 describeCoverageElement.setTagName( QStringLiteral( "DescribeCoverage" ) );
120 requestElement.appendChild( describeCoverageElement );
121
122 QDomElement getCoverageElement = getCapabilitiesElement.cloneNode().toElement();//this is the same as 'GetCapabilities'
123 getCoverageElement.setTagName( QStringLiteral( "GetCoverage" ) );
124 requestElement.appendChild( getCoverageElement );
125
126 //INSERT ContentMetadata
127 wcsCapabilitiesElement.appendChild( getContentMetadataElement( doc, serverIface, project ) );
128
129 return doc;
130
131 }
132
133 QDomElement getServiceElement( QDomDocument &doc, const QgsProject *project )
134 {
135 //Service element
136 QDomElement serviceElem = doc.createElement( QStringLiteral( "Service" ) );
137
138 //Service name
139 QDomElement nameElem = doc.createElement( QStringLiteral( "name" ) );
140 const QDomText nameText = doc.createTextNode( "WCS" );
141 nameElem.appendChild( nameText );
142 serviceElem.appendChild( nameElem );
143
144 const QString title = QgsServerProjectUtils::owsServiceTitle( *project );
145 QDomElement titleElem = doc.createElement( QStringLiteral( "label" ) );
146 const QDomText titleText = doc.createTextNode( title );
147 titleElem.appendChild( titleText );
148 serviceElem.appendChild( titleElem );
149
150 const QString abstract = QgsServerProjectUtils::owsServiceAbstract( *project );
151 if ( !abstract.isEmpty() )
152 {
153 QDomElement abstractElem = doc.createElement( QStringLiteral( "description" ) );
154 const QDomText abstractText = doc.createCDATASection( abstract );
155 abstractElem.appendChild( abstractText );
156 serviceElem.appendChild( abstractElem );
157 }
158
159 const QStringList keywords = QgsServerProjectUtils::owsServiceKeywords( *project );
160 if ( !keywords.isEmpty() )
161 {
162 QDomElement keywordsElem = doc.createElement( QStringLiteral( "keywords" ) );
163 for ( int i = 0; i < keywords.size(); ++i )
164 {
165 QDomElement keywordElem = doc.createElement( QStringLiteral( "keyword" ) );
166 const QDomText keywordText = doc.createTextNode( keywords.at( i ) );
167 keywordElem.appendChild( keywordText );
168 keywordsElem.appendChild( keywordElem );
169 }
170 serviceElem.appendChild( keywordsElem );
171 }
172
173
174 const QString contactPerson = QgsServerProjectUtils::owsServiceContactPerson( *project );
175 const QString contactOrganization = QgsServerProjectUtils::owsServiceContactOrganization( *project );
176 const QString contactPosition = QgsServerProjectUtils::owsServiceContactPosition( *project );
177 const QString contactMail = QgsServerProjectUtils::owsServiceContactMail( *project );
178 const QString contactPhone = QgsServerProjectUtils::owsServiceContactPhone( *project );
179 const QString onlineResource = QgsServerProjectUtils::owsServiceOnlineResource( *project );
180 if ( !contactPerson.isEmpty() ||
181 !contactOrganization.isEmpty() ||
182 !contactPosition.isEmpty() ||
183 !contactMail.isEmpty() ||
184 !contactPhone.isEmpty() ||
185 !onlineResource.isEmpty() )
186 {
187 QDomElement responsiblePartyElem = doc.createElement( QStringLiteral( "responsibleParty" ) );
188 if ( !contactPerson.isEmpty() )
189 {
190 QDomElement contactPersonElem = doc.createElement( QStringLiteral( "individualName" ) );
191 const QDomText contactPersonText = doc.createTextNode( contactPerson );
192 contactPersonElem.appendChild( contactPersonText );
193 responsiblePartyElem.appendChild( contactPersonElem );
194 }
195 if ( !contactOrganization.isEmpty() )
196 {
197 QDomElement contactOrganizationElem = doc.createElement( QStringLiteral( "organisationName" ) );
198 const QDomText contactOrganizationText = doc.createTextNode( contactOrganization );
199 contactOrganizationElem.appendChild( contactOrganizationText );
200 responsiblePartyElem.appendChild( contactOrganizationElem );
201 }
202 if ( !contactPosition.isEmpty() )
203 {
204 QDomElement contactPositionElem = doc.createElement( QStringLiteral( "positionName" ) );
205 const QDomText contactPositionText = doc.createTextNode( contactPosition );
206 contactPositionElem.appendChild( contactPositionText );
207 responsiblePartyElem.appendChild( contactPositionElem );
208 }
209 if ( !contactMail.isEmpty() ||
210 !contactPhone.isEmpty() ||
211 !onlineResource.isEmpty() )
212 {
213 QDomElement contactInfoElem = doc.createElement( QStringLiteral( "contactInfo" ) );
214 if ( !contactMail.isEmpty() )
215 {
216 QDomElement contactAddressElem = doc.createElement( QStringLiteral( "address" ) );
217 QDomElement contactAddressMailElem = doc.createElement( QStringLiteral( "electronicMailAddress" ) );
218 const QDomText contactAddressMailText = doc.createTextNode( contactMail );
219 contactAddressMailElem.appendChild( contactAddressMailText );
220 contactAddressElem.appendChild( contactAddressMailElem );
221 contactInfoElem.appendChild( contactAddressElem );
222 }
223 if ( !contactPhone.isEmpty() )
224 {
225 QDomElement contactPhoneElem = doc.createElement( QStringLiteral( "phone" ) );
226 QDomElement contactVoiceElem = doc.createElement( QStringLiteral( "voice" ) );
227 const QDomText contactVoiceText = doc.createTextNode( contactPhone );
228 contactVoiceElem.appendChild( contactVoiceText );
229 contactPhoneElem.appendChild( contactVoiceElem );
230 contactInfoElem.appendChild( contactPhoneElem );
231 }
232 if ( !onlineResource.isEmpty() )
233 {
234 QDomElement onlineResourceElem = doc.createElement( QStringLiteral( "onlineResource" ) );
235 onlineResourceElem.setAttribute( QStringLiteral( "xmlns:xlink" ), QStringLiteral( "http://www.w3.org/1999/xlink" ) );
236 onlineResourceElem.setAttribute( QStringLiteral( "xlink:type" ), QStringLiteral( "simple" ) );
237 onlineResourceElem.setAttribute( QStringLiteral( "xlink:href" ), onlineResource );
238 contactInfoElem.appendChild( onlineResourceElem );
239 }
240 responsiblePartyElem.appendChild( contactInfoElem );
241 }
242 serviceElem.appendChild( responsiblePartyElem );
243 }
244
245 QDomElement feesElem = doc.createElement( QStringLiteral( "fees" ) );
246 QDomText feesText = doc.createTextNode( QStringLiteral( "None" ) ); // default value if fees are unknown
247 const QString fees = QgsServerProjectUtils::owsServiceFees( *project );
248 if ( !fees.isEmpty() )
249 {
250 feesText = doc.createTextNode( fees );
251 }
252 feesElem.appendChild( feesText );
253 serviceElem.appendChild( feesElem );
254
255 QDomElement accessConstraintsElem = doc.createElement( QStringLiteral( "accessConstraints" ) );
256 QDomText accessConstraintsText = doc.createTextNode( QStringLiteral( "None" ) ); // default value if access constraints are unknown
257 const QString accessConstraints = QgsServerProjectUtils::owsServiceAccessConstraints( *project );
258 if ( !accessConstraints.isEmpty() )
259 {
260 accessConstraintsText = doc.createTextNode( accessConstraints );
261 }
262 accessConstraintsElem.appendChild( accessConstraintsText );
263 serviceElem.appendChild( accessConstraintsElem );
264
265 //End
266 return serviceElem;
267 }
268
269 QDomElement getContentMetadataElement( QDomDocument &doc, QgsServerInterface *serverIface, const QgsProject *project )
270 {
271#ifdef HAVE_SERVER_PYTHON_PLUGINS
272 QgsAccessControl *accessControl = serverIface->accessControls();
273#else
274 ( void )serverIface;
275#endif
276 /*
277 * Adding layer list in ContentMetadata
278 */
279 QDomElement contentMetadataElement = doc.createElement( QStringLiteral( "ContentMetadata" )/*wcs:ContentMetadata*/ );
280
281 const QStringList wcsLayersId = QgsServerProjectUtils::wcsLayerIds( *project );
282 for ( int i = 0; i < wcsLayersId.size(); ++i )
283 {
284 QgsMapLayer *layer = project->mapLayer( wcsLayersId.at( i ) );
285 if ( !layer )
286 {
287 continue;
288 }
289 if ( layer->type() != QgsMapLayerType::RasterLayer )
290 {
291 continue;
292 }
293#ifdef HAVE_SERVER_PYTHON_PLUGINS
294 if ( !accessControl->layerReadPermission( layer ) )
295 {
296 continue;
297 }
298#endif
299
300 QgsRasterLayer *rLayer = qobject_cast<QgsRasterLayer *>( layer );
301 const QDomElement layerElem = getCoverageOffering( doc, const_cast<QgsRasterLayer *>( rLayer ), project, true );
302
303 contentMetadataElement.appendChild( layerElem );
304 }
305
306 //End
307 return contentMetadataElement;
308 }
309
310} // namespace QgsWcs
311
312
313
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
QgsMapLayerType type
Definition: qgsmaplayer.h:80
Encapsulates a QGIS project, including sets of map layers and their styles, layouts,...
Definition: qgsproject.h:104
Q_INVOKABLE QgsMapLayer * mapLayer(const QString &layerId) const
Retrieve a pointer to a registered layer by layer ID.
Represents a raster layer.
A helper class that centralizes caches accesses given by all the server cache filter plugins.
bool setCachedDocument(const QDomDocument *doc, const QgsProject *project, const QgsServerRequest &request, QgsAccessControl *accessControl) const
Updates or inserts the document in cache like capabilities.
bool getCachedDocument(QDomDocument *doc, const QgsProject *project, const QgsServerRequest &request, QgsAccessControl *accessControl) const
Returns cached document (or 0 if document not in cache) like capabilities.
QgsServerInterface Class defining interfaces exposed by QGIS Server and made available to plugins.
virtual QgsServerCacheManager * cacheManager() const =0
Gets the registered server cache filters.
virtual QgsAccessControl * accessControls() const =0
Gets the registered access control filters.
virtual QgsServerSettings * serverSettings()=0
Returns the server settings.
QgsServerRequest Class defining request interface passed to services QgsService::executeRequest() met...
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...
@ RasterLayer
Raster layer.
SERVER_EXPORT QString owsServiceAccessConstraints(const QgsProject &project)
Returns the owsService access constraints defined in project.
SERVER_EXPORT QString owsServiceOnlineResource(const QgsProject &project)
Returns the owsService online resource defined in project.
SERVER_EXPORT QString owsServiceFees(const QgsProject &project)
Returns the owsService fees defined in project.
SERVER_EXPORT QStringList owsServiceKeywords(const QgsProject &project)
Returns the owsService keywords defined in project.
SERVER_EXPORT QString owsServiceContactPosition(const QgsProject &project)
Returns the owsService contact position defined in project.
SERVER_EXPORT QString owsServiceContactOrganization(const QgsProject &project)
Returns the owsService contact organization defined in project.
SERVER_EXPORT QString owsServiceTitle(const QgsProject &project)
Returns the owsService title defined in project.
SERVER_EXPORT QString owsServiceContactMail(const QgsProject &project)
Returns the owsService contact mail defined in project.
SERVER_EXPORT QString owsServiceAbstract(const QgsProject &project)
Returns the owsService abstract defined in project.
SERVER_EXPORT QStringList wcsLayerIds(const QgsProject &project)
Returns the Layer ids list defined in a QGIS project as published in WCS.
SERVER_EXPORT QString owsServiceContactPhone(const QgsProject &project)
Returns the owsService contact phone defined in project.
SERVER_EXPORT QString owsServiceContactPerson(const QgsProject &project)
Returns the owsService contact person defined in project.
WCS implementation.
Definition: qgswcs.cpp:30
QDomDocument createGetCapabilitiesDocument(QgsServerInterface *serverIface, const QgsProject *project, const QString &version, const QgsServerRequest &request)
Create get capabilities document.
QDomElement getCoverageOffering(QDomDocument &doc, const QgsRasterLayer *layer, const QgsProject *project, bool brief)
CoverageOffering or CoverageOfferingBrief element.
Definition: qgswcsutils.cpp:35
QString implementationVersion()
Returns the highest version supported by this implementation.
Definition: qgswcsutils.cpp:30
const QString WCS_NAMESPACE
Definition: qgswcsutils.h:63
const QString GML_NAMESPACE
Definition: qgswcsutils.h:64
QString serviceUrl(const QgsServerRequest &request, const QgsProject *project, const QgsServerSettings &settings)
Service URL string.
QDomElement getServiceElement(QDomDocument &doc, const QgsProject *project)
Create Service element for get capabilities document.
QDomElement getContentMetadataElement(QDomDocument &doc, QgsServerInterface *serverIface, const QgsProject *project)
Create ContentMetadata element for get capabilities document.
void writeGetCapabilities(QgsServerInterface *serverIface, const QgsProject *project, const QString &version, const QgsServerRequest &request, QgsServerResponse &response)
Output WCS GetCapabilities response.