QGIS API Documentation  3.21.0-Master (5b68dc587e)
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"
20 #include "qgsserverprojectutils.h"
21 #include "qgswcsgetcapabilities.h"
22 
23 #include "qgsproject.h"
24 #include "qgsrasterlayer.h"
25 
26 namespace 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  if ( !title.isEmpty() )
146  {
147  QDomElement titleElem = doc.createElement( QStringLiteral( "label" ) );
148  const QDomText titleText = doc.createTextNode( title );
149  titleElem.appendChild( titleText );
150  serviceElem.appendChild( titleElem );
151  }
152 
153  const QString abstract = QgsServerProjectUtils::owsServiceAbstract( *project );
154  if ( !abstract.isEmpty() )
155  {
156  QDomElement abstractElem = doc.createElement( QStringLiteral( "description" ) );
157  const QDomText abstractText = doc.createCDATASection( abstract );
158  abstractElem.appendChild( abstractText );
159  serviceElem.appendChild( abstractElem );
160  }
161 
162  const QStringList keywords = QgsServerProjectUtils::owsServiceKeywords( *project );
163  if ( !keywords.isEmpty() )
164  {
165  QDomElement keywordsElem = doc.createElement( QStringLiteral( "keywords" ) );
166  for ( int i = 0; i < keywords.size(); ++i )
167  {
168  QDomElement keywordElem = doc.createElement( QStringLiteral( "keyword" ) );
169  const QDomText keywordText = doc.createTextNode( keywords.at( i ) );
170  keywordElem.appendChild( keywordText );
171  keywordsElem.appendChild( keywordElem );
172  }
173  serviceElem.appendChild( keywordsElem );
174  }
175 
176 
177  const QString contactPerson = QgsServerProjectUtils::owsServiceContactPerson( *project );
178  const QString contactOrganization = QgsServerProjectUtils::owsServiceContactOrganization( *project );
179  const QString contactPosition = QgsServerProjectUtils::owsServiceContactPosition( *project );
180  const QString contactMail = QgsServerProjectUtils::owsServiceContactMail( *project );
181  const QString contactPhone = QgsServerProjectUtils::owsServiceContactPhone( *project );
182  const QString onlineResource = QgsServerProjectUtils::owsServiceOnlineResource( *project );
183  if ( !contactPerson.isEmpty() ||
184  !contactOrganization.isEmpty() ||
185  !contactPosition.isEmpty() ||
186  !contactMail.isEmpty() ||
187  !contactPhone.isEmpty() ||
188  !onlineResource.isEmpty() )
189  {
190  QDomElement responsiblePartyElem = doc.createElement( QStringLiteral( "responsibleParty" ) );
191  if ( !contactPerson.isEmpty() )
192  {
193  QDomElement contactPersonElem = doc.createElement( QStringLiteral( "individualName" ) );
194  const QDomText contactPersonText = doc.createTextNode( contactPerson );
195  contactPersonElem.appendChild( contactPersonText );
196  responsiblePartyElem.appendChild( contactPersonElem );
197  }
198  if ( !contactOrganization.isEmpty() )
199  {
200  QDomElement contactOrganizationElem = doc.createElement( QStringLiteral( "organisationName" ) );
201  const QDomText contactOrganizationText = doc.createTextNode( contactOrganization );
202  contactOrganizationElem.appendChild( contactOrganizationText );
203  responsiblePartyElem.appendChild( contactOrganizationElem );
204  }
205  if ( !contactPosition.isEmpty() )
206  {
207  QDomElement contactPositionElem = doc.createElement( QStringLiteral( "positionName" ) );
208  const QDomText contactPositionText = doc.createTextNode( contactPosition );
209  contactPositionElem.appendChild( contactPositionText );
210  responsiblePartyElem.appendChild( contactPositionElem );
211  }
212  if ( !contactMail.isEmpty() ||
213  !contactPhone.isEmpty() ||
214  !onlineResource.isEmpty() )
215  {
216  QDomElement contactInfoElem = doc.createElement( QStringLiteral( "contactInfo" ) );
217  if ( !contactMail.isEmpty() )
218  {
219  QDomElement contactAddressElem = doc.createElement( QStringLiteral( "address" ) );
220  QDomElement contactAddressMailElem = doc.createElement( QStringLiteral( "electronicMailAddress" ) );
221  const QDomText contactAddressMailText = doc.createTextNode( contactMail );
222  contactAddressMailElem.appendChild( contactAddressMailText );
223  contactAddressElem.appendChild( contactAddressMailElem );
224  contactInfoElem.appendChild( contactAddressElem );
225  }
226  if ( !contactPhone.isEmpty() )
227  {
228  QDomElement contactPhoneElem = doc.createElement( QStringLiteral( "phone" ) );
229  QDomElement contactVoiceElem = doc.createElement( QStringLiteral( "voice" ) );
230  const QDomText contactVoiceText = doc.createTextNode( contactPhone );
231  contactVoiceElem.appendChild( contactVoiceText );
232  contactPhoneElem.appendChild( contactVoiceElem );
233  contactInfoElem.appendChild( contactPhoneElem );
234  }
235  if ( !onlineResource.isEmpty() )
236  {
237  QDomElement onlineResourceElem = doc.createElement( QStringLiteral( "onlineResource" ) );
238  onlineResourceElem.setAttribute( QStringLiteral( "xmlns:xlink" ), QStringLiteral( "http://www.w3.org/1999/xlink" ) );
239  onlineResourceElem.setAttribute( QStringLiteral( "xlink:type" ), QStringLiteral( "simple" ) );
240  onlineResourceElem.setAttribute( QStringLiteral( "xlink:href" ), onlineResource );
241  contactInfoElem.appendChild( onlineResourceElem );
242  }
243  responsiblePartyElem.appendChild( contactInfoElem );
244  }
245  serviceElem.appendChild( responsiblePartyElem );
246  }
247 
248  QDomElement feesElem = doc.createElement( QStringLiteral( "fees" ) );
249  QDomText feesText = doc.createTextNode( QStringLiteral( "None" ) ); // default value if fees are unknown
250  const QString fees = QgsServerProjectUtils::owsServiceFees( *project );
251  if ( !fees.isEmpty() )
252  {
253  feesText = doc.createTextNode( fees );
254  }
255  feesElem.appendChild( feesText );
256  serviceElem.appendChild( feesElem );
257 
258  QDomElement accessConstraintsElem = doc.createElement( QStringLiteral( "accessConstraints" ) );
259  QDomText accessConstraintsText = doc.createTextNode( QStringLiteral( "None" ) ); // default value if access constraints are unknown
260  const QString accessConstraints = QgsServerProjectUtils::owsServiceAccessConstraints( *project );
261  if ( !accessConstraints.isEmpty() )
262  {
263  accessConstraintsText = doc.createTextNode( accessConstraints );
264  }
265  accessConstraintsElem.appendChild( accessConstraintsText );
266  serviceElem.appendChild( accessConstraintsElem );
267 
268  //End
269  return serviceElem;
270  }
271 
272  QDomElement getContentMetadataElement( QDomDocument &doc, QgsServerInterface *serverIface, const QgsProject *project )
273  {
274 #ifdef HAVE_SERVER_PYTHON_PLUGINS
275  QgsAccessControl *accessControl = serverIface->accessControls();
276 #else
277  ( void )serverIface;
278 #endif
279  /*
280  * Adding layer list in ContentMetadata
281  */
282  QDomElement contentMetadataElement = doc.createElement( QStringLiteral( "ContentMetadata" )/*wcs:ContentMetadata*/ );
283 
284  const QStringList wcsLayersId = QgsServerProjectUtils::wcsLayerIds( *project );
285  for ( int i = 0; i < wcsLayersId.size(); ++i )
286  {
287  QgsMapLayer *layer = project->mapLayer( wcsLayersId.at( i ) );
288  if ( !layer )
289  {
290  continue;
291  }
292  if ( layer->type() != QgsMapLayerType::RasterLayer )
293  {
294  continue;
295  }
296 #ifdef HAVE_SERVER_PYTHON_PLUGINS
297  if ( !accessControl->layerReadPermission( layer ) )
298  {
299  continue;
300  }
301 #endif
302 
303  QgsRasterLayer *rLayer = qobject_cast<QgsRasterLayer *>( layer );
304  const QDomElement layerElem = getCoverageOffering( doc, const_cast<QgsRasterLayer *>( rLayer ), project, true );
305 
306  contentMetadataElement.appendChild( layerElem );
307  }
308 
309  //End
310  return contentMetadataElement;
311  }
312 
313 } // namespace QgsWcs
314 
315 
316 
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:101
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 QgsAccessControl * accessControls() const =0
Gets the registered access control filters.
virtual QgsServerCacheManager * cacheManager() const =0
Gets the registered server cache 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...
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.