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