35#include <QRegularExpression>
41 void appendOwsLayerStyles( QDomDocument &doc, QDomElement &layerElem,
QgsMapLayer *currentLayer );
45 void appendOwsGeneralAndResourceList( QDomDocument &doc, QDomElement &parentElement,
QgsServerInterface *serverIface,
const QgsProject *project,
const QgsWmsRequest &request );
50#ifdef HAVE_SERVER_PYTHON_PLUGINS
55 const QDomDocument *contextDocument =
nullptr;
57#ifdef HAVE_SERVER_PYTHON_PLUGINS
59 if ( cacheManager && cacheManager->
getCachedDocument( &doc, project, request, accessControl ) )
61 contextDocument = &doc;
65 doc =
getContext( serverIface, project, request );
71 contextDocument = &doc;
74 doc =
getContext( serverIface, project, request );
75 contextDocument = &doc;
77 response.
setHeader( QStringLiteral(
"Content-Type" ), QStringLiteral(
"text/xml; charset=utf-8" ) );
78 response.
write( contextDocument->toByteArray() );
85 const QDomProcessingInstruction xmlDeclaration = doc.createProcessingInstruction( QStringLiteral(
"xml" ), QStringLiteral(
"version=\"1.0\" encoding=\"utf-8\"" ) );
87 doc.appendChild( xmlDeclaration );
89 QDomElement owsContextElem = doc.createElement( QStringLiteral(
"OWSContext" ) );
90 owsContextElem.setAttribute( QStringLiteral(
"xmlns" ), QStringLiteral(
"http://www.opengis.net/ows-context" ) );
91 owsContextElem.setAttribute( QStringLiteral(
"xmlns:ows-context" ), QStringLiteral(
"http://www.opengis.net/ows-context" ) );
92 owsContextElem.setAttribute( QStringLiteral(
"xmlns:context" ), QStringLiteral(
"http://www.opengis.net/context" ) );
93 owsContextElem.setAttribute( QStringLiteral(
"xmlns:ows" ), QStringLiteral(
"http://www.opengis.net/ows" ) );
94 owsContextElem.setAttribute( QStringLiteral(
"xmlns:sld" ), QStringLiteral(
"http://www.opengis.net/sld" ) );
95 owsContextElem.setAttribute( QStringLiteral(
"xmlns:ogc" ), QStringLiteral(
"http://www.opengis.net/ogc" ) );
96 owsContextElem.setAttribute( QStringLiteral(
"xmlns:gml" ), QStringLiteral(
"http://www.opengis.net/gml" ) );
97 owsContextElem.setAttribute( QStringLiteral(
"xmlns:kml" ), QStringLiteral(
"http://www.opengis.net/kml/2.2" ) );
98 owsContextElem.setAttribute( QStringLiteral(
"xmlns:xlink" ), QStringLiteral(
"http://www.w3.org/1999/xlink" ) );
99 owsContextElem.setAttribute( QStringLiteral(
"xmlns:ns9" ), QStringLiteral(
"http://www.w3.org/2005/Atom" ) );
100 owsContextElem.setAttribute( QStringLiteral(
"xmlns:xal" ), QStringLiteral(
"urn:oasis:names:tc:ciq:xsdschema:xAL:2.0" ) );
101 owsContextElem.setAttribute( QStringLiteral(
"xmlns:ins" ), QStringLiteral(
"http://www.inspire.org" ) );
102 owsContextElem.setAttribute( QStringLiteral(
"version" ), QStringLiteral(
"0.3.1" ) );
103 doc.appendChild( owsContextElem );
105 appendOwsGeneralAndResourceList( doc, owsContextElem, serverIface, project, request );
111 void appendOwsGeneralAndResourceList( QDomDocument &doc, QDomElement &parentElement,
QgsServerInterface *serverIface,
const QgsProject *project,
const QgsWmsRequest &request )
113 parentElement.setAttribute( QStringLiteral(
"id" ),
"ows-context-" + project->
baseName() );
116 QDomElement generalElem = doc.createElement( QStringLiteral(
"General" ) );
119 QDomElement windowElem = doc.createElement( QStringLiteral(
"Window" ) );
120 windowElem.setAttribute( QStringLiteral(
"height" ), QStringLiteral(
"600" ) );
121 windowElem.setAttribute( QStringLiteral(
"width" ), QStringLiteral(
"800" ) );
122 generalElem.appendChild( windowElem );
126 QDomElement titleElem = doc.createElement( QStringLiteral(
"ows:Title" ) );
127 const QDomText titleText = doc.createTextNode( title );
128 titleElem.appendChild( titleText );
129 generalElem.appendChild( titleElem );
133 if ( !abstract.isEmpty() )
135 QDomElement abstractElem = doc.createElement( QStringLiteral(
"ows:Abstract" ) );
136 const QDomText abstractText = doc.createCDATASection( abstract );
137 abstractElem.appendChild( abstractText );
138 generalElem.appendChild( abstractElem );
143 if ( !keywords.isEmpty() )
147 QDomElement keywordsElem = doc.createElement( QStringLiteral(
"ows:Keywords" ) );
149 for (
int i = 0; i < keywords.size(); ++i )
151 const QString keyword = keywords.at( i );
152 if ( !keyword.isEmpty() )
154 QDomElement keywordElem = doc.createElement( QStringLiteral(
"ows:Keyword" ) );
155 const QDomText keywordText = doc.createTextNode( keyword );
156 keywordElem.appendChild( keywordText );
159 keywordElem.setAttribute( QStringLiteral(
"vocabulary" ), QStringLiteral(
"SIA_Geo405" ) );
161 keywordsElem.appendChild( keywordElem );
164 generalElem.appendChild( keywordsElem );
168 parentElement.appendChild( generalElem );
171 QDomElement resourceListElem = doc.createElement( QStringLiteral(
"ResourceList" ) );
174 appendOwsLayersFromTreeGroup( doc, resourceListElem, serverIface, project, request, projectLayerTreeRoot, combinedBBox, QString() );
175 parentElement.appendChild( resourceListElem );
182 mapRect = combinedBBox;
184 QDomElement bboxElem = doc.createElement( QStringLiteral(
"ows:BoundingBox" ) );
185 bboxElem.setAttribute( QStringLiteral(
"crs" ), projectCrs.
authid() );
190 QDomElement lowerCornerElem = doc.createElement( QStringLiteral(
"ows:LowerCorner" ) );
191 const QDomText lowerCornerText = doc.createTextNode( QString::number( mapRect.
xMinimum() ) +
" " + QString::number( mapRect.
yMinimum() ) );
192 lowerCornerElem.appendChild( lowerCornerText );
193 bboxElem.appendChild( lowerCornerElem );
194 QDomElement upperCornerElem = doc.createElement( QStringLiteral(
"ows:UpperCorner" ) );
195 const QDomText upperCornerText = doc.createTextNode( QString::number( mapRect.
xMaximum() ) +
" " + QString::number( mapRect.
yMaximum() ) );
196 upperCornerElem.appendChild( upperCornerText );
197 bboxElem.appendChild( upperCornerElem );
198 generalElem.appendChild( bboxElem );
205 const QList<QgsLayerTreeNode *> layerTreeGroupChildren = layerTreeGroup->
children();
206 for (
int i = 0; i < layerTreeGroupChildren.size(); ++i )
214 const QString name = treeGroupChild->
name();
215 if ( restrictedLayers.contains( name ) )
221 if ( strGroup.isEmpty() )
227 group = strGroup +
"/" + name;
230 appendOwsLayersFromTreeGroup( doc, parentLayer, serverIface, project, request, treeGroupChild, combinedBBox, group );
236 if ( restrictedLayers.contains( l->
name() ) )
240#ifdef HAVE_SERVER_PYTHON_PLUGINS
247 QDomElement layerElem = doc.createElement( QStringLiteral(
"Layer" ) );
252 layerElem.setAttribute( QStringLiteral(
"queryable" ), QStringLiteral(
"false" ) );
256 layerElem.setAttribute( QStringLiteral(
"queryable" ), QStringLiteral(
"true" ) );
262 layerElem.setAttribute( QStringLiteral(
"hidden" ), QStringLiteral(
"false" ) );
266 layerElem.setAttribute( QStringLiteral(
"hidden" ), QStringLiteral(
"true" ) );
270 if ( !strGroup.isEmpty() )
272 layerElem.setAttribute( QStringLiteral(
"group" ), strGroup );
277 layerElem.setAttribute( QStringLiteral(
"opacity" ), 1 );
279 QString wmsName = l->
name();
289 layerElem.setAttribute( QStringLiteral(
"name" ), wmsName );
291 const thread_local QRegularExpression sRegEx( QStringLiteral(
"[\\W]" ), QRegularExpression::UseUnicodePropertiesOption );
292 layerElem.setAttribute( QStringLiteral(
"id" ), wmsName.replace( sRegEx, QStringLiteral(
"_" ) ) );
295 QDomElement titleElem = doc.createElement( QStringLiteral(
"ows:Title" ) );
297 if ( title.isEmpty() )
301 const QDomText titleText = doc.createTextNode( title );
302 titleElem.appendChild( titleText );
303 layerElem.appendChild( titleElem );
306 QDomElement formatElem = doc.createElement( QStringLiteral(
"ows:OutputFormat" ) );
307 const QDomText formatText = doc.createTextNode( QStringLiteral(
"image/png" ) );
308 formatElem.appendChild( formatText );
309 layerElem.appendChild( formatElem );
315 QString hrefString = href.toString();
316 hrefString.append( href.hasQuery() ?
"&" :
"?" );
319 QDomElement serverElem = doc.createElement( QStringLiteral(
"Server" ) );
320 serverElem.setAttribute( QStringLiteral(
"service" ), QStringLiteral(
"urn:ogc:serviceType:WMS" ) );
321 serverElem.setAttribute( QStringLiteral(
"version" ), QStringLiteral(
"1.3.0" ) );
322 serverElem.setAttribute( QStringLiteral(
"default" ), QStringLiteral(
"true" ) );
323 QDomElement orServerElem = doc.createElement( QStringLiteral(
"OnlineResource" ) );
324 orServerElem.setAttribute( QStringLiteral(
"xlink:href" ), hrefString );
325 serverElem.appendChild( orServerElem );
326 layerElem.appendChild( serverElem );
329 if ( !abstract.isEmpty() )
331 QDomElement abstractElem = doc.createElement( QStringLiteral(
"ows:Abstract" ) );
332 const QDomText abstractText = doc.createTextNode( abstract );
333 abstractElem.appendChild( abstractText );
334 layerElem.appendChild( abstractElem );
340 const QString minScaleString = QString::number( l->
maximumScale() );
341 const QString maxScaleString = QString::number( l->
minimumScale() );
342 QDomElement minScaleElem = doc.createElement( QStringLiteral(
"sld:MinScaleDenominator" ) );
343 const QDomText minScaleText = doc.createTextNode( minScaleString );
344 minScaleElem.appendChild( minScaleText );
345 layerElem.appendChild( minScaleElem );
346 QDomElement maxScaleElem = doc.createElement( QStringLiteral(
"sld:MaxScaleDenominator" ) );
347 const QDomText maxScaleText = doc.createTextNode( maxScaleString );
348 maxScaleElem.appendChild( maxScaleText );
349 layerElem.appendChild( maxScaleElem );
353 appendOwsLayerStyles( doc, layerElem, l );
361 QDomElement keywordsElem = doc.createElement( QStringLiteral(
"ows:Keywords" ) );
362 for (
int i = 0; i < keywordStringList.size(); ++i )
364 QDomElement keywordElem = doc.createElement( QStringLiteral(
"ows:Keyword" ) );
365 const QDomText keywordText = doc.createTextNode( keywordStringList.at( i ).trimmed() );
366 keywordElem.appendChild( keywordText );
369 keywordElem.setAttribute( QStringLiteral(
"vocabulary" ), QStringLiteral(
"SIA_Geo405" ) );
371 keywordsElem.appendChild( keywordElem );
373 layerElem.appendChild( keywordsElem );
378 if ( !dataUrl.isEmpty() )
380 QDomElement dataUrlElem = doc.createElement( QStringLiteral(
"DataURL" ) );
382 dataUrlElem.setAttribute( QStringLiteral(
"format" ), dataUrlFormat );
383 QDomElement dataORElem = doc.createElement( QStringLiteral(
"OnlineResource" ) );
384 dataORElem.setAttribute( QStringLiteral(
"xmlns:xlink" ), QStringLiteral(
"http://www.w3.org/1999/xlink" ) );
385 dataORElem.setAttribute( QStringLiteral(
"xlink:type" ), QStringLiteral(
"simple" ) );
386 dataORElem.setAttribute( QStringLiteral(
"xlink:href" ), dataUrl );
387 dataUrlElem.appendChild( dataORElem );
388 layerElem.appendChild( dataUrlElem );
395 QDomElement metaUrlElem = doc.createElement( QStringLiteral(
"MetadataURL" ) );
396 metaUrlElem.setAttribute( QStringLiteral(
"format" ), url.format );
397 QDomElement metaUrlORElem = doc.createElement( QStringLiteral(
"OnlineResource" ) );
398 metaUrlORElem.setAttribute( QStringLiteral(
"xmlns:xlink" ), QStringLiteral(
"http://www.w3.org/1999/xlink" ) );
399 metaUrlORElem.setAttribute( QStringLiteral(
"xlink:type" ), QStringLiteral(
"simple" ) );
400 metaUrlORElem.setAttribute( QStringLiteral(
"xlink:href" ), url.url );
401 metaUrlElem.appendChild( metaUrlORElem );
402 layerElem.appendChild( metaUrlElem );
424 if ( parentLayer.hasChildNodes() )
426 parentLayer.insertBefore( layerElem, parentLayer.firstChild() );
430 parentLayer.appendChild( layerElem );
436 void appendOwsLayerStyles( QDomDocument &doc, QDomElement &layerElem,
QgsMapLayer *currentLayer )
438 for (
const QString &styleName : currentLayer->styleManager()->styles() )
440 QDomElement styleListElem = doc.createElement( QStringLiteral(
"StyleList" ) );
442 QDomElement styleElem = doc.createElement( QStringLiteral(
"Style" ) );
443 styleElem.setAttribute( QStringLiteral(
"current" ), QStringLiteral(
"true" ) );
444 QDomElement styleNameElem = doc.createElement( QStringLiteral(
"Name" ) );
445 const QDomText styleNameText = doc.createTextNode( styleName );
446 styleNameElem.appendChild( styleNameText );
447 QDomElement styleTitleElem = doc.createElement( QStringLiteral(
"Title" ) );
448 const QDomText styleTitleText = doc.createTextNode( styleName );
449 styleTitleElem.appendChild( styleTitleText );
450 styleElem.appendChild( styleNameElem );
451 styleElem.appendChild( styleTitleElem );
452 styleListElem.appendChild( styleElem );
453 layerElem.appendChild( styleListElem );
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.
This class represents a coordinate reference system (CRS).
bool hasAxisInverted() const
Returns whether the axis order is inverted for the CRS compared to the order east/north (longitude/la...
Custom exception class for Coordinate Reference System related exceptions.
Layer tree group node serves as a container for layers and further groups.
QString name() const override
Returns the group's name.
Layer tree node points to a map layer.
QgsMapLayer * layer() const
Returns the map layer associated with this node.
This class is a base class for nodes in a layer tree.
@ 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)
Namespace with helper functions for layer tree operations.
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.
Base class for all map layer types.
virtual QgsRectangle extent() const
Returns the extent of the layer.
QgsMapLayer::LayerFlags flags() const
Returns the flags for this layer.
QgsCoordinateReferenceSystem crs
QgsMapLayerServerProperties * serverProperties()
Returns QGIS Server Properties for the map layer.
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.
double maximumScale() const
Returns the maximum map scale (i.e.
Encapsulates a QGIS project, including sets of map layers and their styles, layouts,...
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
A rectangle specified with double values.
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.
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.
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...
Class defining request interface passed to WMS service.
SERVER_EXPORT bool wmsInfoFormatSia2045(const QgsProject &project)
Returns if the info format is SIA20145.
SERVER_EXPORT QgsRectangle wmsExtent(const QgsProject &project)
Returns the WMS Extent restriction.
SERVER_EXPORT bool wmsUseLayerIds(const QgsProject &project)
Returns if layer ids are used as name in WMS.
SERVER_EXPORT QStringList owsServiceKeywords(const QgsProject &project)
Returns the owsService keywords defined in project.
SERVER_EXPORT QStringList wmsRestrictedLayers(const QgsProject &project)
Returns the restricted layer name list.
SERVER_EXPORT QString owsServiceTitle(const QgsProject &project)
Returns the owsService title defined in project.
SERVER_EXPORT QString owsServiceAbstract(const QgsProject &project)
Returns the owsService abstract defined in project.
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.