QGIS API Documentation 3.99.0-Master (d270888f95f)
Loading...
Searching...
No Matches
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 ***************************************************************************/
20
21#include "qgsproject.h"
22#include "qgsrasterlayer.h"
24#include "qgswcsutils.h"
25
26#include <QString>
27
28using namespace Qt::StringLiterals;
29
30namespace QgsWcs
31{
32
36 void writeGetCapabilities( QgsServerInterface *serverIface, const QgsProject *project, const QString &version, const QgsServerRequest &request, QgsServerResponse &response )
37 {
38#ifdef HAVE_SERVER_PYTHON_PLUGINS
39 QgsAccessControl *accessControl = serverIface->accessControls();
40#endif
41 QDomDocument doc;
42 const QDomDocument *capabilitiesDocument = nullptr;
43
44#ifdef HAVE_SERVER_PYTHON_PLUGINS
45 QgsServerCacheManager *cacheManager = serverIface->cacheManager();
46 if ( cacheManager && cacheManager->getCachedDocument( &doc, project, request, accessControl ) )
47 {
48 capabilitiesDocument = &doc;
49 }
50 else //capabilities xml not in cache. Create a new one
51 {
52 doc = createGetCapabilitiesDocument( serverIface, project, version, request );
53
54 if ( cacheManager )
55 {
56 cacheManager->setCachedDocument( &doc, project, request, accessControl );
57 }
58 capabilitiesDocument = &doc;
59 }
60#else
61 doc = createGetCapabilitiesDocument( serverIface, project, version, request );
62 capabilitiesDocument = &doc;
63#endif
64 response.setHeader( u"Content-Type"_s, u"text/xml; charset=utf-8"_s );
65 response.write( capabilitiesDocument->toByteArray() );
66 }
67
68
69 QDomDocument createGetCapabilitiesDocument( QgsServerInterface *serverIface, const QgsProject *project, const QString &version, const QgsServerRequest &request )
70 {
71 Q_UNUSED( version )
72
73 QDomDocument doc;
74
75 //wcs:WCS_Capabilities element
76 QDomElement wcsCapabilitiesElement = doc.createElement( u"WCS_Capabilities"_s /*wcs:WCS_Capabilities*/ );
77 wcsCapabilitiesElement.setAttribute( u"xmlns"_s, WCS_NAMESPACE );
78 wcsCapabilitiesElement.setAttribute( u"xmlns:xsi"_s, u"http://www.w3.org/2001/XMLSchema-instance"_s );
79 wcsCapabilitiesElement.setAttribute( u"xsi:schemaLocation"_s, WCS_NAMESPACE + " http://schemas.opengis.net/wcs/1.0.0/wcsCapabilities.xsd" );
80 wcsCapabilitiesElement.setAttribute( u"xmlns:gml"_s, GML_NAMESPACE );
81 wcsCapabilitiesElement.setAttribute( u"xmlns:xlink"_s, u"http://www.w3.org/1999/xlink"_s );
82 wcsCapabilitiesElement.setAttribute( u"version"_s, implementationVersion() );
83 wcsCapabilitiesElement.setAttribute( u"updateSequence"_s, u"0"_s );
84 doc.appendChild( wcsCapabilitiesElement );
85
86 //INSERT Service
87 wcsCapabilitiesElement.appendChild( getServiceElement( doc, project ) );
88
89 //wcs:Capability element
90 QDomElement capabilityElement = doc.createElement( u"Capability"_s /*wcs:Capability*/ );
91 wcsCapabilitiesElement.appendChild( capabilityElement );
92
93 //wcs:Request element
94 QDomElement requestElement = doc.createElement( u"Request"_s /*wcs:Request*/ );
95 capabilityElement.appendChild( requestElement );
96
97 //wcs:GetCapabilities
98 QDomElement getCapabilitiesElement = doc.createElement( u"GetCapabilities"_s /*wcs:GetCapabilities*/ );
99 requestElement.appendChild( getCapabilitiesElement );
100
101 QDomElement dcpTypeElement = doc.createElement( u"DCPType"_s /*wcs:DCPType*/ );
102 getCapabilitiesElement.appendChild( dcpTypeElement );
103 QDomElement httpElement = doc.createElement( u"HTTP"_s /*wcs:HTTP*/ );
104 dcpTypeElement.appendChild( httpElement );
105
106 //Prepare url
107 const QString hrefString = serviceUrl( request, project, *serverIface->serverSettings() );
108
109 QDomElement getElement = doc.createElement( u"Get"_s /*wcs:Get*/ );
110 httpElement.appendChild( getElement );
111 QDomElement onlineResourceElement = doc.createElement( u"OnlineResource"_s /*wcs:OnlineResource*/ );
112 onlineResourceElement.setAttribute( u"xlink:type"_s, u"simple"_s );
113 onlineResourceElement.setAttribute( u"xlink:href"_s, hrefString );
114 getElement.appendChild( onlineResourceElement );
115
116 const QDomElement getCapabilitiesDhcTypePostElement = dcpTypeElement.cloneNode().toElement(); //this is the same as for 'GetCapabilities'
117 getCapabilitiesDhcTypePostElement.firstChild().firstChild().toElement().setTagName( u"Post"_s );
118 getCapabilitiesElement.appendChild( getCapabilitiesDhcTypePostElement );
119
120 QDomElement describeCoverageElement = getCapabilitiesElement.cloneNode().toElement(); //this is the same as 'GetCapabilities'
121 describeCoverageElement.setTagName( u"DescribeCoverage"_s );
122 requestElement.appendChild( describeCoverageElement );
123
124 QDomElement getCoverageElement = getCapabilitiesElement.cloneNode().toElement(); //this is the same as 'GetCapabilities'
125 getCoverageElement.setTagName( u"GetCoverage"_s );
126 requestElement.appendChild( getCoverageElement );
127
128 //INSERT ContentMetadata
129 wcsCapabilitiesElement.appendChild( getContentMetadataElement( doc, serverIface, project ) );
130
131 return doc;
132 }
133
134 QDomElement getServiceElement( QDomDocument &doc, const QgsProject *project )
135 {
136 //Service element
137 QDomElement serviceElem = doc.createElement( u"Service"_s );
138
139 //Service name
140 QDomElement nameElem = doc.createElement( u"name"_s );
141 const QDomText nameText = doc.createTextNode( "WCS" );
142 nameElem.appendChild( nameText );
143 serviceElem.appendChild( nameElem );
144
145 const QString title = QgsServerProjectUtils::owsServiceTitle( *project );
146 QDomElement titleElem = doc.createElement( u"label"_s );
147 const QDomText titleText = doc.createTextNode( title );
148 titleElem.appendChild( titleText );
149 serviceElem.appendChild( titleElem );
150
151 const QString abstract = QgsServerProjectUtils::owsServiceAbstract( *project );
152 if ( !abstract.isEmpty() )
153 {
154 QDomElement abstractElem = doc.createElement( u"description"_s );
155 const QDomText abstractText = doc.createCDATASection( abstract );
156 abstractElem.appendChild( abstractText );
157 serviceElem.appendChild( abstractElem );
158 }
159
160 const QStringList keywords = QgsServerProjectUtils::owsServiceKeywords( *project );
161 if ( !keywords.isEmpty() )
162 {
163 QDomElement keywordsElem = doc.createElement( u"keywords"_s );
164 for ( int i = 0; i < keywords.size(); ++i )
165 {
166 QDomElement keywordElem = doc.createElement( u"keyword"_s );
167 const QDomText keywordText = doc.createTextNode( keywords.at( i ) );
168 keywordElem.appendChild( keywordText );
169 keywordsElem.appendChild( keywordElem );
170 }
171 serviceElem.appendChild( keywordsElem );
172 }
173
174
175 const QString contactPerson = QgsServerProjectUtils::owsServiceContactPerson( *project );
176 const QString contactOrganization = QgsServerProjectUtils::owsServiceContactOrganization( *project );
177 const QString contactPosition = QgsServerProjectUtils::owsServiceContactPosition( *project );
178 const QString contactMail = QgsServerProjectUtils::owsServiceContactMail( *project );
179 const QString contactPhone = QgsServerProjectUtils::owsServiceContactPhone( *project );
180 const QString onlineResource = QgsServerProjectUtils::owsServiceOnlineResource( *project );
181 if ( !contactPerson.isEmpty() || !contactOrganization.isEmpty() || !contactPosition.isEmpty() || !contactMail.isEmpty() || !contactPhone.isEmpty() || !onlineResource.isEmpty() )
182 {
183 QDomElement responsiblePartyElem = doc.createElement( u"responsibleParty"_s );
184 if ( !contactPerson.isEmpty() )
185 {
186 QDomElement contactPersonElem = doc.createElement( u"individualName"_s );
187 const QDomText contactPersonText = doc.createTextNode( contactPerson );
188 contactPersonElem.appendChild( contactPersonText );
189 responsiblePartyElem.appendChild( contactPersonElem );
190 }
191 if ( !contactOrganization.isEmpty() )
192 {
193 QDomElement contactOrganizationElem = doc.createElement( u"organisationName"_s );
194 const QDomText contactOrganizationText = doc.createTextNode( contactOrganization );
195 contactOrganizationElem.appendChild( contactOrganizationText );
196 responsiblePartyElem.appendChild( contactOrganizationElem );
197 }
198 if ( !contactPosition.isEmpty() )
199 {
200 QDomElement contactPositionElem = doc.createElement( u"positionName"_s );
201 const QDomText contactPositionText = doc.createTextNode( contactPosition );
202 contactPositionElem.appendChild( contactPositionText );
203 responsiblePartyElem.appendChild( contactPositionElem );
204 }
205 if ( !contactMail.isEmpty() || !contactPhone.isEmpty() || !onlineResource.isEmpty() )
206 {
207 QDomElement contactInfoElem = doc.createElement( u"contactInfo"_s );
208 if ( !contactMail.isEmpty() )
209 {
210 QDomElement contactAddressElem = doc.createElement( u"address"_s );
211 QDomElement contactAddressMailElem = doc.createElement( u"electronicMailAddress"_s );
212 const QDomText contactAddressMailText = doc.createTextNode( contactMail );
213 contactAddressMailElem.appendChild( contactAddressMailText );
214 contactAddressElem.appendChild( contactAddressMailElem );
215 contactInfoElem.appendChild( contactAddressElem );
216 }
217 if ( !contactPhone.isEmpty() )
218 {
219 QDomElement contactPhoneElem = doc.createElement( u"phone"_s );
220 QDomElement contactVoiceElem = doc.createElement( u"voice"_s );
221 const QDomText contactVoiceText = doc.createTextNode( contactPhone );
222 contactVoiceElem.appendChild( contactVoiceText );
223 contactPhoneElem.appendChild( contactVoiceElem );
224 contactInfoElem.appendChild( contactPhoneElem );
225 }
226 if ( !onlineResource.isEmpty() )
227 {
228 QDomElement onlineResourceElem = doc.createElement( u"onlineResource"_s );
229 onlineResourceElem.setAttribute( u"xmlns:xlink"_s, u"http://www.w3.org/1999/xlink"_s );
230 onlineResourceElem.setAttribute( u"xlink:type"_s, u"simple"_s );
231 onlineResourceElem.setAttribute( u"xlink:href"_s, onlineResource );
232 contactInfoElem.appendChild( onlineResourceElem );
233 }
234 responsiblePartyElem.appendChild( contactInfoElem );
235 }
236 serviceElem.appendChild( responsiblePartyElem );
237 }
238
239 QDomElement feesElem = doc.createElement( u"fees"_s );
240 QDomText feesText = doc.createTextNode( u"None"_s ); // default value if fees are unknown
241 const QString fees = QgsServerProjectUtils::owsServiceFees( *project );
242 if ( !fees.isEmpty() )
243 {
244 feesText = doc.createTextNode( fees );
245 }
246 feesElem.appendChild( feesText );
247 serviceElem.appendChild( feesElem );
248
249 QDomElement accessConstraintsElem = doc.createElement( u"accessConstraints"_s );
250 QDomText accessConstraintsText = doc.createTextNode( u"None"_s ); // default value if access constraints are unknown
251 const QString accessConstraints = QgsServerProjectUtils::owsServiceAccessConstraints( *project );
252 if ( !accessConstraints.isEmpty() )
253 {
254 accessConstraintsText = doc.createTextNode( accessConstraints );
255 }
256 accessConstraintsElem.appendChild( accessConstraintsText );
257 serviceElem.appendChild( accessConstraintsElem );
258
259 //End
260 return serviceElem;
261 }
262
263 QDomElement getContentMetadataElement( QDomDocument &doc, QgsServerInterface *serverIface, const QgsProject *project )
264 {
265#ifdef HAVE_SERVER_PYTHON_PLUGINS
266 QgsAccessControl *accessControl = serverIface->accessControls();
267#else
268 ( void ) serverIface;
269#endif
270 /*
271 * Adding layer list in ContentMetadata
272 */
273 QDomElement contentMetadataElement = doc.createElement( u"ContentMetadata"_s /*wcs:ContentMetadata*/ );
274
275 const QStringList wcsLayersId = QgsServerProjectUtils::wcsLayerIds( *project );
276 for ( int i = 0; i < wcsLayersId.size(); ++i )
277 {
278 QgsMapLayer *layer = project->mapLayer( wcsLayersId.at( i ) );
279 if ( !layer )
280 {
281 continue;
282 }
283 if ( layer->type() != Qgis::LayerType::Raster )
284 {
285 continue;
286 }
287#ifdef HAVE_SERVER_PYTHON_PLUGINS
288 if ( !accessControl->layerReadPermission( layer ) )
289 {
290 continue;
291 }
292#endif
293
294 QgsRasterLayer *rLayer = qobject_cast<QgsRasterLayer *>( layer );
295 const QDomElement layerElem = getCoverageOffering( doc, const_cast<QgsRasterLayer *>( rLayer ), project, true );
296
297 contentMetadataElement.appendChild( layerElem );
298 }
299
300 //End
301 return contentMetadataElement;
302 }
303
304} // namespace QgsWcs
@ Raster
Raster layer.
Definition qgis.h:195
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:83
Qgis::LayerType type
Definition qgsmaplayer.h:93
Encapsulates a QGIS project, including sets of map layers and their styles, layouts,...
Definition qgsproject.h:112
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.
Defines 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.
static QString owsServiceAccessConstraints(const QgsProject &project)
Returns the owsService access constraints defined in project.
static QString owsServiceOnlineResource(const QgsProject &project)
Returns the owsService online resource defined in project.
static QString owsServiceFees(const QgsProject &project)
Returns the owsService fees defined in project.
static QStringList owsServiceKeywords(const QgsProject &project)
Returns the owsService keywords defined in project.
static QString owsServiceContactPosition(const QgsProject &project)
Returns the owsService contact position defined in project.
static QString owsServiceContactOrganization(const QgsProject &project)
Returns the owsService contact organization defined in project.
static QString owsServiceTitle(const QgsProject &project)
Returns the owsService title defined in project.
static QString owsServiceContactMail(const QgsProject &project)
Returns the owsService contact mail defined in project.
static QString owsServiceAbstract(const QgsProject &project)
Returns the owsService abstract defined in project.
static QStringList wcsLayerIds(const QgsProject &project)
Returns the Layer ids list defined in a QGIS project as published in WCS.
static QString owsServiceContactPhone(const QgsProject &project)
Returns the owsService contact phone defined in project.
static QString owsServiceContactPerson(const QgsProject &project)
Returns the owsService contact person defined in project.
Defines requests passed to QgsService classes.
Defines the response interface passed to QgsService.
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...
WCS implementation.
Definition qgswcs.cpp:34
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.
QString implementationVersion()
Returns the highest version supported by this implementation.
const QString WCS_NAMESPACE
Definition qgswcsutils.h:65
const QString GML_NAMESPACE
Definition qgswcsutils.h:66
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.