QGIS API Documentation 3.99.0-Master (d270888f95f)
Loading...
Searching...
No Matches
qgswmsgetcontext.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgswmsgetcontext.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#include "qgswmsgetcontext.h"
22
24#include "qgsexception.h"
25#include "qgslayertree.h"
26#include "qgslayertreegroup.h"
27#include "qgslayertreelayer.h"
28#include "qgslayertreenode.h"
31#include "qgswmsrequest.h"
32#include "qgswmsutils.h"
33
34#include <QRegularExpression>
35#include <QString>
36
37using namespace Qt::StringLiterals;
38
39namespace QgsWms
40{
41 namespace
42 {
43 void appendOwsLayerStyles( QDomDocument &doc, QDomElement &layerElem, QgsMapLayer *currentLayer );
44
45 void appendOwsLayersFromTreeGroup( QDomDocument &doc, QDomElement &parentLayer, QgsServerInterface *serverIface, const QgsProject *project, const QgsWmsRequest &request, const QgsLayerTreeGroup *layerTreeGroup, QgsRectangle &combinedBBox, const QString &strGroup );
46
47 void appendOwsGeneralAndResourceList( QDomDocument &doc, QDomElement &parentElement, QgsServerInterface *serverIface, const QgsProject *project, const QgsWmsRequest &request );
48 } // namespace
49
50 void writeGetContext( QgsServerInterface *serverIface, const QgsProject *project, const QgsWmsRequest &request, QgsServerResponse &response )
51 {
52#ifdef HAVE_SERVER_PYTHON_PLUGINS
53 QgsAccessControl *accessControl = serverIface->accessControls();
54#endif
55
56 QDomDocument doc;
57 const QDomDocument *contextDocument = nullptr;
58
59#ifdef HAVE_SERVER_PYTHON_PLUGINS
60 QgsServerCacheManager *cacheManager = serverIface->cacheManager();
61 if ( cacheManager && cacheManager->getCachedDocument( &doc, project, request, accessControl ) )
62 {
63 contextDocument = &doc;
64 }
65 else //context xml not in cache. Create a new one
66 {
67 doc = getContext( serverIface, project, request );
68
69 if ( cacheManager )
70 {
71 cacheManager->setCachedDocument( &doc, project, request, accessControl );
72 }
73 contextDocument = &doc;
74 }
75#else
76 doc = getContext( serverIface, project, request );
77 contextDocument = &doc;
78#endif
79 response.setHeader( u"Content-Type"_s, u"text/xml; charset=utf-8"_s );
80 response.write( contextDocument->toByteArray() );
81 }
82
83
84 QDomDocument getContext( QgsServerInterface *serverIface, const QgsProject *project, const QgsWmsRequest &request )
85 {
86 QDomDocument doc;
87 const QDomProcessingInstruction xmlDeclaration = doc.createProcessingInstruction( u"xml"_s, u"version=\"1.0\" encoding=\"utf-8\""_s );
88
89 doc.appendChild( xmlDeclaration );
90
91 QDomElement owsContextElem = doc.createElement( u"OWSContext"_s );
92 owsContextElem.setAttribute( u"xmlns"_s, u"http://www.opengis.net/ows-context"_s );
93 owsContextElem.setAttribute( u"xmlns:ows-context"_s, u"http://www.opengis.net/ows-context"_s );
94 owsContextElem.setAttribute( u"xmlns:context"_s, u"http://www.opengis.net/context"_s );
95 owsContextElem.setAttribute( u"xmlns:ows"_s, u"http://www.opengis.net/ows"_s );
96 owsContextElem.setAttribute( u"xmlns:sld"_s, u"http://www.opengis.net/sld"_s );
97 owsContextElem.setAttribute( u"xmlns:ogc"_s, u"http://www.opengis.net/ogc"_s );
98 owsContextElem.setAttribute( u"xmlns:gml"_s, u"http://www.opengis.net/gml"_s );
99 owsContextElem.setAttribute( u"xmlns:kml"_s, u"http://www.opengis.net/kml/2.2"_s );
100 owsContextElem.setAttribute( u"xmlns:xlink"_s, u"http://www.w3.org/1999/xlink"_s );
101 owsContextElem.setAttribute( u"xmlns:ns9"_s, u"http://www.w3.org/2005/Atom"_s );
102 owsContextElem.setAttribute( u"xmlns:xal"_s, u"urn:oasis:names:tc:ciq:xsdschema:xAL:2.0"_s );
103 owsContextElem.setAttribute( u"xmlns:ins"_s, u"http://www.inspire.org"_s );
104 owsContextElem.setAttribute( u"version"_s, u"0.3.1"_s );
105 doc.appendChild( owsContextElem );
106
107 appendOwsGeneralAndResourceList( doc, owsContextElem, serverIface, project, request );
108
109 return doc;
110 }
111 namespace
112 {
113 void appendOwsGeneralAndResourceList( QDomDocument &doc, QDomElement &parentElement, QgsServerInterface *serverIface, const QgsProject *project, const QgsWmsRequest &request )
114 {
115 parentElement.setAttribute( u"id"_s, "ows-context-" + project->baseName() );
116
117 // OWSContext General element
118 QDomElement generalElem = doc.createElement( u"General"_s );
119
120 // OWSContext Window element
121 QDomElement windowElem = doc.createElement( u"Window"_s );
122 windowElem.setAttribute( u"height"_s, u"600"_s );
123 windowElem.setAttribute( u"width"_s, u"800"_s );
124 generalElem.appendChild( windowElem );
125
126 //OWS title
127 const QString title = QgsServerProjectUtils::owsServiceTitle( *project );
128 QDomElement titleElem = doc.createElement( u"ows:Title"_s );
129 const QDomText titleText = doc.createTextNode( title );
130 titleElem.appendChild( titleText );
131 generalElem.appendChild( titleElem );
132
133 //OWS abstract
134 const QString abstract = QgsServerProjectUtils::owsServiceAbstract( *project );
135 if ( !abstract.isEmpty() )
136 {
137 QDomElement abstractElem = doc.createElement( u"ows:Abstract"_s );
138 const QDomText abstractText = doc.createCDATASection( abstract );
139 abstractElem.appendChild( abstractText );
140 generalElem.appendChild( abstractElem );
141 }
142
143 //OWS Keywords
144 const QStringList keywords = QgsServerProjectUtils::owsServiceKeywords( *project );
145 if ( !keywords.isEmpty() )
146 {
147 const bool sia2045 = QgsServerProjectUtils::wmsInfoFormatSia2045( *project );
148
149 QDomElement keywordsElem = doc.createElement( u"ows:Keywords"_s );
150
151 for ( int i = 0; i < keywords.size(); ++i )
152 {
153 const QString keyword = keywords.at( i );
154 if ( !keyword.isEmpty() )
155 {
156 QDomElement keywordElem = doc.createElement( u"ows:Keyword"_s );
157 const QDomText keywordText = doc.createTextNode( keyword );
158 keywordElem.appendChild( keywordText );
159 if ( sia2045 )
160 {
161 keywordElem.setAttribute( u"vocabulary"_s, u"SIA_Geo405"_s );
162 }
163 keywordsElem.appendChild( keywordElem );
164 }
165 }
166 generalElem.appendChild( keywordsElem );
167 }
168
169 // OWSContext General element is complete
170 parentElement.appendChild( generalElem );
171
172 // OWSContext ResourceList element
173 QDomElement resourceListElem = doc.createElement( u"ResourceList"_s );
174 const QgsLayerTree *projectLayerTreeRoot = project->layerTreeRoot();
175 QgsRectangle combinedBBox;
176 appendOwsLayersFromTreeGroup( doc, resourceListElem, serverIface, project, request, projectLayerTreeRoot, combinedBBox, QString() );
177 parentElement.appendChild( resourceListElem );
178
179 // OWSContext BoundingBox
180 const QgsCoordinateReferenceSystem projectCrs = project->crs();
181 QgsRectangle mapRect = QgsServerProjectUtils::wmsExtent( *project );
182 if ( mapRect.isEmpty() )
183 {
184 mapRect = combinedBBox;
185 }
186 QDomElement bboxElem = doc.createElement( u"ows:BoundingBox"_s );
187 bboxElem.setAttribute( u"crs"_s, projectCrs.authid() );
188 if ( projectCrs.hasAxisInverted() )
189 {
190 mapRect.invert();
191 }
192 QDomElement lowerCornerElem = doc.createElement( u"ows:LowerCorner"_s );
193 const QDomText lowerCornerText = doc.createTextNode( QString::number( mapRect.xMinimum() ) + " " + QString::number( mapRect.yMinimum() ) );
194 lowerCornerElem.appendChild( lowerCornerText );
195 bboxElem.appendChild( lowerCornerElem );
196 QDomElement upperCornerElem = doc.createElement( u"ows:UpperCorner"_s );
197 const QDomText upperCornerText = doc.createTextNode( QString::number( mapRect.xMaximum() ) + " " + QString::number( mapRect.yMaximum() ) );
198 upperCornerElem.appendChild( upperCornerText );
199 bboxElem.appendChild( upperCornerElem );
200 generalElem.appendChild( bboxElem );
201 }
202
203 void appendOwsLayersFromTreeGroup( QDomDocument &doc, QDomElement &parentLayer, QgsServerInterface *serverIface, const QgsProject *project, const QgsWmsRequest &request, const QgsLayerTreeGroup *layerTreeGroup, QgsRectangle &combinedBBox, const QString &strGroup )
204 {
205 const QStringList restrictedLayers = QgsServerProjectUtils::wmsRestrictedLayers( *project );
206
207 const QList<QgsLayerTreeNode *> layerTreeGroupChildren = layerTreeGroup->children();
208 for ( int i = 0; i < layerTreeGroupChildren.size(); ++i )
209 {
210 QgsLayerTreeNode *treeNode = layerTreeGroupChildren.at( i );
211
212 if ( treeNode->nodeType() == QgsLayerTreeNode::NodeGroup )
213 {
214 QgsLayerTreeGroup *treeGroupChild = static_cast<QgsLayerTreeGroup *>( treeNode );
215
216 const QString name = treeGroupChild->name();
217 if ( restrictedLayers.contains( name ) ) //unpublished group
218 {
219 continue;
220 }
221
222 QString group;
223 if ( strGroup.isEmpty() )
224 {
225 group = name;
226 }
227 else
228 {
229 group = strGroup + "/" + name;
230 }
231
232 appendOwsLayersFromTreeGroup( doc, parentLayer, serverIface, project, request, treeGroupChild, combinedBBox, group );
233 }
234 else
235 {
236 QgsLayerTreeLayer *treeLayer = static_cast<QgsLayerTreeLayer *>( treeNode );
237 QgsMapLayer *l = treeLayer->layer();
238 if ( restrictedLayers.contains( l->name() ) ) //unpublished layer
239 {
240 continue;
241 }
242#ifdef HAVE_SERVER_PYTHON_PLUGINS
243 QgsAccessControl *accessControl = serverIface->accessControls();
244 if ( accessControl && !accessControl->layerReadPermission( l ) )
245 {
246 continue;
247 }
248#endif
249 QDomElement layerElem = doc.createElement( u"Layer"_s );
250
251 // queryable layer
252 if ( !l->flags().testFlag( QgsMapLayer::Identifiable ) )
253 {
254 layerElem.setAttribute( u"queryable"_s, u"false"_s );
255 }
256 else
257 {
258 layerElem.setAttribute( u"queryable"_s, u"true"_s );
259 }
260
261 // visibility
262 if ( treeLayer->itemVisibilityChecked() )
263 {
264 layerElem.setAttribute( u"hidden"_s, u"false"_s );
265 }
266 else
267 {
268 layerElem.setAttribute( u"hidden"_s, u"true"_s );
269 }
270
271 // layer group
272 if ( !strGroup.isEmpty() )
273 {
274 layerElem.setAttribute( u"group"_s, strGroup );
275 }
276
277 // Because Layer transparency is used for the rendering
278 // OWSContext Layer opacity is set to 1
279 layerElem.setAttribute( u"opacity"_s, 1 );
280
281 QString wmsName = l->name();
283 {
284 wmsName = l->id();
285 }
286 else if ( !l->serverProperties()->shortName().isEmpty() )
287 {
288 wmsName = l->serverProperties()->shortName();
289 }
290 // layer wms name
291 layerElem.setAttribute( u"name"_s, wmsName );
292 // define an id based on layer wms name
293 const thread_local QRegularExpression sRegEx( u"[\\W]"_s, QRegularExpression::UseUnicodePropertiesOption );
294 layerElem.setAttribute( u"id"_s, wmsName.replace( sRegEx, u"_"_s ) );
295
296 // layer title
297 QDomElement titleElem = doc.createElement( u"ows:Title"_s );
298 QString title = l->serverProperties()->title();
299 if ( title.isEmpty() )
300 {
301 title = l->name();
302 }
303 const QDomText titleText = doc.createTextNode( title );
304 titleElem.appendChild( titleText );
305 layerElem.appendChild( titleElem );
306
307 // WMS GetMap output format
308 QDomElement formatElem = doc.createElement( u"ows:OutputFormat"_s );
309 const QDomText formatText = doc.createTextNode( u"image/png"_s );
310 formatElem.appendChild( formatText );
311 layerElem.appendChild( formatElem );
312
313 // Get WMS service URL for Server Element
314 const QUrl href = serviceUrl( request, project, *serverIface->serverSettings() );
315
316 //href needs to be a prefix
317 QString hrefString = href.toString();
318 hrefString.append( href.hasQuery() ? "&" : "?" );
319
320 // COntext Server Element with WMS service URL
321 QDomElement serverElem = doc.createElement( u"Server"_s );
322 serverElem.setAttribute( u"service"_s, u"urn:ogc:serviceType:WMS"_s );
323 serverElem.setAttribute( u"version"_s, u"1.3.0"_s );
324 serverElem.setAttribute( u"default"_s, u"true"_s );
325 QDomElement orServerElem = doc.createElement( u"OnlineResource"_s );
326 orServerElem.setAttribute( u"xlink:href"_s, hrefString );
327 serverElem.appendChild( orServerElem );
328 layerElem.appendChild( serverElem );
329
330 const QString abstract = l->serverProperties()->abstract();
331 if ( !abstract.isEmpty() )
332 {
333 QDomElement abstractElem = doc.createElement( u"ows:Abstract"_s );
334 const QDomText abstractText = doc.createTextNode( abstract );
335 abstractElem.appendChild( abstractText );
336 layerElem.appendChild( abstractElem );
337 }
338
339 //min/max scale denominatorScaleBasedVisibility
340 if ( l->hasScaleBasedVisibility() )
341 {
342 const QString minScaleString = QString::number( l->maximumScale() );
343 const QString maxScaleString = QString::number( l->minimumScale() );
344 QDomElement minScaleElem = doc.createElement( u"sld:MinScaleDenominator"_s );
345 const QDomText minScaleText = doc.createTextNode( minScaleString );
346 minScaleElem.appendChild( minScaleText );
347 layerElem.appendChild( minScaleElem );
348 QDomElement maxScaleElem = doc.createElement( u"sld:MaxScaleDenominator"_s );
349 const QDomText maxScaleText = doc.createTextNode( maxScaleString );
350 maxScaleElem.appendChild( maxScaleText );
351 layerElem.appendChild( maxScaleElem );
352 }
353
354 // Style list
355 appendOwsLayerStyles( doc, layerElem, l );
356
357 //keyword list
358 if ( !l->serverProperties()->keywordList().isEmpty() )
359 {
360 const QStringList keywordStringList = l->serverProperties()->keywordList().split( ',' );
361 const bool sia2045 = QgsServerProjectUtils::wmsInfoFormatSia2045( *project );
362
363 QDomElement keywordsElem = doc.createElement( u"ows:Keywords"_s );
364 for ( int i = 0; i < keywordStringList.size(); ++i )
365 {
366 QDomElement keywordElem = doc.createElement( u"ows:Keyword"_s );
367 const QDomText keywordText = doc.createTextNode( keywordStringList.at( i ).trimmed() );
368 keywordElem.appendChild( keywordText );
369 if ( sia2045 )
370 {
371 keywordElem.setAttribute( u"vocabulary"_s, u"SIA_Geo405"_s );
372 }
373 keywordsElem.appendChild( keywordElem );
374 }
375 layerElem.appendChild( keywordsElem );
376 }
377
378 // layer data URL
379 const QString dataUrl = l->serverProperties()->dataUrl();
380 if ( !dataUrl.isEmpty() )
381 {
382 QDomElement dataUrlElem = doc.createElement( u"DataURL"_s );
383 const QString dataUrlFormat = l->serverProperties()->dataUrlFormat();
384 dataUrlElem.setAttribute( u"format"_s, dataUrlFormat );
385 QDomElement dataORElem = doc.createElement( u"OnlineResource"_s );
386 dataORElem.setAttribute( u"xmlns:xlink"_s, u"http://www.w3.org/1999/xlink"_s );
387 dataORElem.setAttribute( u"xlink:type"_s, u"simple"_s );
388 dataORElem.setAttribute( u"xlink:href"_s, dataUrl );
389 dataUrlElem.appendChild( dataORElem );
390 layerElem.appendChild( dataUrlElem );
391 }
392
393 // layer metadata URL
394 const QList<QgsMapLayerServerProperties::MetadataUrl> urls = l->serverProperties()->metadataUrls();
395 for ( const QgsMapLayerServerProperties::MetadataUrl &url : urls )
396 {
397 QDomElement metaUrlElem = doc.createElement( u"MetadataURL"_s );
398 metaUrlElem.setAttribute( u"format"_s, url.format );
399 QDomElement metaUrlORElem = doc.createElement( u"OnlineResource"_s );
400 metaUrlORElem.setAttribute( u"xmlns:xlink"_s, u"http://www.w3.org/1999/xlink"_s );
401 metaUrlORElem.setAttribute( u"xlink:type"_s, u"simple"_s );
402 metaUrlORElem.setAttribute( u"xlink:href"_s, url.url );
403 metaUrlElem.appendChild( metaUrlORElem );
404 layerElem.appendChild( metaUrlElem );
405 }
406
407 // update combineBBox
408 try
409 {
410 const QgsCoordinateTransform t( l->crs(), project->crs(), project );
411 const QgsRectangle BBox = t.transformBoundingBox( l->extent() );
412 if ( combinedBBox.isEmpty() )
413 {
414 combinedBBox = BBox;
415 }
416 else
417 {
418 combinedBBox.combineExtentWith( BBox );
419 }
420 }
421 catch ( const QgsCsException &cse )
422 {
423 Q_UNUSED( cse )
424 }
425
426 if ( parentLayer.hasChildNodes() )
427 {
428 parentLayer.insertBefore( layerElem, parentLayer.firstChild() );
429 }
430 else
431 {
432 parentLayer.appendChild( layerElem );
433 }
434 } // end of treeNode type
435 } // end of for
436 }
437
438 void appendOwsLayerStyles( QDomDocument &doc, QDomElement &layerElem, QgsMapLayer *currentLayer )
439 {
440 for ( const QString &styleName : currentLayer->styleManager()->styles() )
441 {
442 QDomElement styleListElem = doc.createElement( u"StyleList"_s );
443 //only one default style in project file mode
444 QDomElement styleElem = doc.createElement( u"Style"_s );
445 styleElem.setAttribute( u"current"_s, u"true"_s );
446 QDomElement styleNameElem = doc.createElement( u"Name"_s );
447 const QDomText styleNameText = doc.createTextNode( styleName );
448 styleNameElem.appendChild( styleNameText );
449 QDomElement styleTitleElem = doc.createElement( u"Title"_s );
450 const QDomText styleTitleText = doc.createTextNode( styleName );
451 styleTitleElem.appendChild( styleTitleText );
452 styleElem.appendChild( styleNameElem );
453 styleElem.appendChild( styleTitleElem );
454 styleListElem.appendChild( styleElem );
455 layerElem.appendChild( styleListElem );
456 }
457 }
458 } // namespace
459
460} // 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.
bool hasAxisInverted() const
Returns whether the axis order is inverted for the CRS compared to the order east/north (longitude/la...
QString name() const override
Returns the group's name.
QgsMapLayer * layer() const
Returns the map layer associated with this node.
@ NodeGroup
Container of other groups and layers.
QList< QgsLayerTreeNode * > children()
Gets list of children of the node. Children are owned by the parent.
NodeType nodeType() const
Find out about type of the node. It is usually shorter to use convenience functions from QgsLayerTree...
bool itemVisibilityChecked() const
Returns whether a node is checked (independently of its ancestors or children).
QString dataUrlFormat() const
Returns the DataUrl format of the layer used by QGIS Server in GetCapabilities request.
QString title() const
Returns the title of the layer used by QGIS Server in GetCapabilities request.
QString dataUrl() const
Returns the DataUrl of the layer used by QGIS Server in GetCapabilities request.
QString keywordList() const
Returns the keyword list of the layerused by QGIS Server in GetCapabilities request.
QString shortName() const
Returns the short name of the layer used by QGIS Server to identify the layer.
QString abstract() const
Returns the abstract of the layerused by QGIS Server in GetCapabilities request.
QStringList styles() const
Returns list of all defined style names.
QString name
Definition qgsmaplayer.h:87
virtual QgsRectangle extent() const
Returns the extent of the layer.
QgsCoordinateReferenceSystem crs
Definition qgsmaplayer.h:90
QgsMapLayerServerProperties * serverProperties()
Returns QGIS Server Properties for the map layer.
QString id
Definition qgsmaplayer.h:86
QgsMapLayer::LayerFlags flags
Definition qgsmaplayer.h:99
bool hasScaleBasedVisibility() const
Returns whether scale based visibility is enabled for the layer.
@ Identifiable
If the layer is identifiable using the identify map tool and as a WMS layer.
double minimumScale() const
Returns the minimum map scale (i.e.
QgsMapLayerStyleManager * styleManager() const
Gets access to the layer's style manager.
double maximumScale() const
Returns the maximum map scale (i.e.
Encapsulates a QGIS project, including sets of map layers and their styles, layouts,...
Definition qgsproject.h:112
QString baseName() const
Returns the base name of the project file without the path and without extension - derived from fileN...
QgsLayerTree * layerTreeRoot() const
Returns pointer to the root (invisible) node of the project's layer tree.
QgsCoordinateReferenceSystem crs
Definition qgsproject.h:118
double xMinimum
double yMinimum
double xMaximum
double yMaximum
void combineExtentWith(const QgsRectangle &rect)
Expands the rectangle so that it covers both the original rectangle and the given rectangle.
void invert()
Swap x/y coordinates in the rectangle.
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.
QList< QgsServerMetadataUrlProperties::MetadataUrl > metadataUrls() const
Returns a list of metadataUrl resources associated for the layer.
static bool wmsInfoFormatSia2045(const QgsProject &project)
Returns if the info format is SIA20145.
static QgsRectangle wmsExtent(const QgsProject &project)
Returns the WMS Extent restriction.
static bool wmsUseLayerIds(const QgsProject &project)
Returns if layer ids are used as name in WMS.
static QStringList owsServiceKeywords(const QgsProject &project)
Returns the owsService keywords defined in project.
static QStringList wmsRestrictedLayers(const QgsProject &project)
Returns the restricted layer name list.
static QString owsServiceTitle(const QgsProject &project)
Returns the owsService title defined in project.
static QString owsServiceAbstract(const QgsProject &project)
Returns the owsService abstract defined in project.
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...
Defines request interfaces passed to WMS service.
Median cut implementation.
void writeGetContext(QgsServerInterface *serverIface, const QgsProject *project, const QgsWmsRequest &request, QgsServerResponse &response)
Output GetContext response.
QDomDocument getContext(QgsServerInterface *serverIface, const QgsProject *project, const QgsWmsRequest &request)
Returns XML document for the 'GetContext' request.
QUrl serviceUrl(const QgsServerRequest &request, const QgsProject *project, const QgsServerSettings &settings)
Returns WMS service URL.