45using namespace Qt::StringLiterals;
51 QString dateToString(
const QDateTime &dateTime,
bool forceToDate );
53 void appendLayerProjectSettings( QDomDocument &doc, QDomElement &layerElem, QgsMapLayer *currentLayer );
55 void appendDrawingOrder( QDomDocument &doc, QDomElement &parentElem, QgsServerInterface *serverIface,
const QgsProject *project );
57 void appendLayerWgs84BoundingRect( QDomDocument &doc, QDomElement &layerElement,
const QgsRectangle &wgs84BoundingRect );
59 void appendLayerCrsExtents( QDomDocument &doc, QDomElement &layerElement,
const QMap<QString, QgsRectangle> &crsExtents );
61 void appendCrsElementToLayer( QDomDocument &doc, QDomElement &layerElement,
const QDomElement &precedingElement,
const QString &crsText );
63 void appendCrsElementsToLayer( QDomDocument &doc, QDomElement &layerElement,
const QStringList &crsList,
const QStringList &constrainedCrsList,
bool hasEarthCrs =
true );
65 void appendLayerStyles( QDomDocument &doc, QDomElement &layerElem,
const QgsWmsLayerInfos &layerInfos,
const QgsProject *project,
const QgsWmsRequest &request,
const QgsServerSettings *settings );
67 void appendLayersFromTreeGroup(
69 QDomElement &parentLayer,
70 QgsServerInterface *serverIface,
71 const QgsProject *project,
73 const QgsLayerTreeGroup *layerTreeGroup,
74 const QMap<QString, QgsWmsLayerInfos> &wmsLayerInfos,
76 QList<QgsDateTimeRange> &parentDateRanges
79 void addKeywordListElement(
const QgsProject *project, QDomDocument &doc, QDomElement &parent );
85#ifdef HAVE_SERVER_PYTHON_PLUGINS
90 const QDomDocument *capabilitiesDocument =
nullptr;
95 QStringList cacheKeyList;
96 cacheKeyList << ( projectSettings ? u
"projectSettings"_s : request.
wmsParameters().version() );
100#ifdef HAVE_SERVER_PYTHON_PLUGINS
104 QString
cacheKey = cacheKeyList.join(
'-' );
106#ifdef HAVE_SERVER_PYTHON_PLUGINS
108 if ( cacheManager && cacheManager->
getCachedDocument( &doc, project, request, accessControl ) )
110 capabilitiesDocument = &doc;
113 if ( !capabilitiesDocument && cache )
118 if ( !capabilitiesDocument )
122 doc =
getCapabilities( serverIface, project, request, projectSettings );
124#ifdef HAVE_SERVER_PYTHON_PLUGINS
125 if ( cacheManager && cacheManager->
setCachedDocument( &doc, project, request, accessControl ) )
127 capabilitiesDocument = &doc;
132 if ( !capabilitiesDocument )
137 if ( !capabilitiesDocument )
139 capabilitiesDocument = &doc;
151 response.
setHeader( u
"Content-Type"_s, u
"text/xml; charset=utf-8"_s );
152 response.
write( capabilitiesDocument->toByteArray() );
158 QDomElement wmsCapabilitiesElement;
164 QString hrefString = href.toString();
165 hrefString.append( href.hasQuery() ?
"&" :
"?" );
168 QDomProcessingInstruction xmlDeclaration = doc.createProcessingInstruction( u
"xml"_s, u
"version=\"1.0\" encoding=\"utf-8\""_s );
171 std::function<void( QDomElement &,
const QString & )> appendFormat = [&doc]( QDomElement &elem,
const QString &format ) {
172 QDomElement formatElem = doc.createElement( u
"Format"_s );
173 formatElem.appendChild( doc.createTextNode( format ) );
174 elem.appendChild( formatElem );
180 u
"WMT_MS_Capabilities SYSTEM 'http://schemas.opengis.net/wms/1.1.1/WMS_MS_Capabilities.dtd'"_s
182 doc.appendChild( xmlDeclaration );
183 wmsCapabilitiesElement = doc.createElement( u
"WMT_MS_Capabilities"_s );
187 doc.appendChild( xmlDeclaration );
188 wmsCapabilitiesElement = doc.createElement( u
"WMS_Capabilities"_s );
189 wmsCapabilitiesElement.setAttribute( u
"xmlns"_s, u
"http://www.opengis.net/wms"_s );
190 wmsCapabilitiesElement.setAttribute( u
"xmlns:sld"_s, u
"http://www.opengis.net/sld"_s );
191 wmsCapabilitiesElement.setAttribute( u
"xmlns:qgs"_s, u
"http://www.qgis.org/wms"_s );
192 wmsCapabilitiesElement.setAttribute( u
"xmlns:xsi"_s, u
"http://www.w3.org/2001/XMLSchema-instance"_s );
193 QString schemaLocation = u
"http://www.opengis.net/wms"_s;
194 schemaLocation +=
" http://schemas.opengis.net/wms/1.3.0/capabilities_1_3_0.xsd"_L1;
195 schemaLocation +=
" http://www.opengis.net/sld"_L1;
196 schemaLocation +=
" http://schemas.opengis.net/sld/1.1.0/sld_capabilities.xsd"_L1;
200 wmsCapabilitiesElement.setAttribute( u
"xmlns:inspire_common"_s, u
"http://inspire.ec.europa.eu/schemas/common/1.0"_s );
201 wmsCapabilitiesElement.setAttribute( u
"xmlns:inspire_vs"_s, u
"http://inspire.ec.europa.eu/schemas/inspire_vs/1.0"_s );
202 schemaLocation +=
" http://inspire.ec.europa.eu/schemas/inspire_vs/1.0"_L1;
203 schemaLocation +=
" http://inspire.ec.europa.eu/schemas/inspire_vs/1.0/inspire_vs.xsd"_L1;
206 schemaLocation +=
" http://www.qgis.org/wms"_L1;
207 schemaLocation +=
" " + hrefString +
"SERVICE=WMS&REQUEST=GetSchemaExtension";
209 wmsCapabilitiesElement.setAttribute( u
"xsi:schemaLocation"_s, schemaLocation );
212 doc.appendChild( wmsCapabilitiesElement );
218 QDomElement capabilityElement =
getCapabilityElement( doc, project, request, projectSettings, serverIface );
219 wmsCapabilitiesElement.appendChild( capabilityElement );
221 if ( projectSettings )
232 if ( projectSettings )
234 appendDrawingOrder( doc, capabilityElement, serverIface, project );
243 QDomElement serviceElem = doc.createElement( u
"Service"_s );
246 QDomElement nameElem = doc.createElement( u
"Name"_s );
247 QDomText nameText = doc.createTextNode( u
"WMS"_s );
248 nameElem.appendChild( nameText );
249 serviceElem.appendChild( nameElem );
252 QDomElement titleElem = doc.createElement( u
"Title"_s );
254 titleElem.appendChild( titleText );
255 serviceElem.appendChild( titleElem );
258 if ( !abstract.isEmpty() )
260 QDomElement abstractElem = doc.createElement( u
"Abstract"_s );
261 QDomText abstractText = doc.createCDATASection( abstract );
262 abstractElem.appendChild( abstractText );
263 serviceElem.appendChild( abstractElem );
266 addKeywordListElement( project, doc, serviceElem );
269 if ( onlineResource.isEmpty() )
271 onlineResource =
serviceUrl( request, project, *serverSettings ).toString();
273 QDomElement onlineResourceElem = doc.createElement( u
"OnlineResource"_s );
274 onlineResourceElem.setAttribute( u
"xmlns:xlink"_s, u
"http://www.w3.org/1999/xlink"_s );
275 onlineResourceElem.setAttribute( u
"xlink:type"_s, u
"simple"_s );
276 onlineResourceElem.setAttribute( u
"xlink:href"_s, onlineResource );
277 serviceElem.appendChild( onlineResourceElem );
284 if ( !contactPerson.isEmpty() || !contactOrganization.isEmpty() || !contactPosition.isEmpty() || !contactMail.isEmpty() || !contactPhone.isEmpty() )
287 QDomElement contactInfoElem = doc.createElement( u
"ContactInformation"_s );
290 if ( !contactPerson.isEmpty() || !contactOrganization.isEmpty() )
292 QDomElement contactPersonPrimaryElem = doc.createElement( u
"ContactPersonPrimary"_s );
294 QDomText contactPersonText;
295 if ( !contactPerson.isEmpty() )
297 contactPersonText = doc.createTextNode( contactPerson );
301 contactPersonText = doc.createTextNode( u
"unknown"_s );
303 QDomElement contactPersonElem = doc.createElement( u
"ContactPerson"_s );
304 contactPersonElem.appendChild( contactPersonText );
305 contactPersonPrimaryElem.appendChild( contactPersonElem );
307 QDomText contactOrganizationText;
308 if ( !contactOrganization.isEmpty() )
310 contactOrganizationText = doc.createTextNode( contactOrganization );
314 contactOrganizationText = doc.createTextNode( u
"unknown"_s );
316 QDomElement contactOrganizationElem = doc.createElement( u
"ContactOrganization"_s );
317 contactOrganizationElem.appendChild( contactOrganizationText );
318 contactPersonPrimaryElem.appendChild( contactOrganizationElem );
320 contactInfoElem.appendChild( contactPersonPrimaryElem );
323 if ( !contactPosition.isEmpty() )
325 QDomElement contactPositionElem = doc.createElement( u
"ContactPosition"_s );
326 QDomText contactPositionText = doc.createTextNode( contactPosition );
327 contactPositionElem.appendChild( contactPositionText );
328 contactInfoElem.appendChild( contactPositionElem );
331 if ( !contactPhone.isEmpty() )
333 QDomElement phoneElem = doc.createElement( u
"ContactVoiceTelephone"_s );
334 QDomText phoneText = doc.createTextNode( contactPhone );
335 phoneElem.appendChild( phoneText );
336 contactInfoElem.appendChild( phoneElem );
339 if ( !contactMail.isEmpty() )
341 QDomElement mailElem = doc.createElement( u
"ContactElectronicMailAddress"_s );
342 QDomText mailText = doc.createTextNode( contactMail );
343 mailElem.appendChild( mailText );
344 contactInfoElem.appendChild( mailElem );
347 serviceElem.appendChild( contactInfoElem );
350 QDomElement feesElem = doc.createElement( u
"Fees"_s );
351 QDomText feesText = doc.createTextNode( u
"None"_s );
353 if ( !fees.isEmpty() )
355 feesText = doc.createTextNode( fees );
357 feesElem.appendChild( feesText );
358 serviceElem.appendChild( feesElem );
360 QDomElement accessConstraintsElem = doc.createElement( u
"AccessConstraints"_s );
361 QDomText accessConstraintsText = doc.createTextNode( u
"None"_s );
363 if ( !accessConstraints.isEmpty() )
365 accessConstraintsText = doc.createTextNode( accessConstraints );
367 accessConstraintsElem.appendChild( accessConstraintsText );
368 serviceElem.appendChild( accessConstraintsElem );
375 QDomElement maxWidthElem = doc.createElement( u
"MaxWidth"_s );
376 QDomText maxWidthText = doc.createTextNode( QString::number( maxWidth ) );
377 maxWidthElem.appendChild( maxWidthText );
378 serviceElem.appendChild( maxWidthElem );
384 QDomElement maxHeightElem = doc.createElement( u
"MaxHeight"_s );
385 QDomText maxHeightText = doc.createTextNode( QString::number( maxHeight ) );
386 maxHeightElem.appendChild( maxHeightText );
387 serviceElem.appendChild( maxHeightElem );
402 QString hrefString = href.toString();
403 hrefString.append( href.hasQuery() ?
"&" :
"?" );
405 QDomElement capabilityElem = doc.createElement( u
"Capability"_s );
408 QDomElement requestElem = doc.createElement( u
"Request"_s );
409 capabilityElem.appendChild( requestElem );
411 QDomElement dcpTypeElem = doc.createElement( u
"DCPType"_s );
412 QDomElement httpElem = doc.createElement( u
"HTTP"_s );
413 dcpTypeElem.appendChild( httpElem );
416 std::function<void( QDomElement &,
const QString & )> appendFormat = [&doc]( QDomElement &elem,
const QString &format ) {
417 QDomElement formatElem = doc.createElement( u
"Format"_s );
418 formatElem.appendChild( doc.createTextNode( format ) );
419 elem.appendChild( formatElem );
425 elem = doc.createElement( u
"GetCapabilities"_s );
426 appendFormat( elem, ( version ==
"1.1.1"_L1 ?
"application/vnd.ogc.wms_xml" :
"text/xml" ) );
427 elem.appendChild( dcpTypeElem );
428 requestElem.appendChild( elem );
431 QDomElement getElem = doc.createElement( u
"Get"_s );
432 httpElem.appendChild( getElem );
433 QDomElement olResourceElem = doc.createElement( u
"OnlineResource"_s );
434 olResourceElem.setAttribute( u
"xmlns:xlink"_s, u
"http://www.w3.org/1999/xlink"_s );
435 olResourceElem.setAttribute( u
"xlink:type"_s, u
"simple"_s );
436 olResourceElem.setAttribute( u
"xlink:href"_s, hrefString );
437 getElem.appendChild( olResourceElem );
440 elem = doc.createElement( u
"GetMap"_s );
441 appendFormat( elem, u
"image/png"_s );
442 appendFormat( elem, u
"image/png; mode=16bit"_s );
443 appendFormat( elem, u
"image/png; mode=8bit"_s );
444 appendFormat( elem, u
"image/png; mode=1bit"_s );
445 appendFormat( elem, u
"image/jpeg"_s );
446 appendFormat( elem, u
"application/dxf"_s );
447 appendFormat( elem, u
"application/pdf"_s );
448 elem.appendChild( dcpTypeElem.cloneNode().toElement() );
449 requestElem.appendChild( elem );
452 elem = doc.createElement( u
"GetFeatureInfo"_s );
453 appendFormat( elem, u
"text/plain"_s );
454 appendFormat( elem, u
"text/html"_s );
455 appendFormat( elem, u
"text/xml"_s );
456 appendFormat( elem, u
"application/vnd.ogc.gml"_s );
457 appendFormat( elem, u
"application/vnd.ogc.gml/3.1.1"_s );
458 appendFormat( elem, u
"application/json"_s );
459 appendFormat( elem, u
"application/geo+json"_s );
460 elem.appendChild( dcpTypeElem.cloneNode().toElement() );
461 requestElem.appendChild( elem );
464 elem = doc.createElement( ( version ==
"1.1.1"_L1 ?
"GetLegendGraphic" :
"sld:GetLegendGraphic" ) );
465 appendFormat( elem, u
"image/jpeg"_s );
466 appendFormat( elem, u
"image/png"_s );
467 appendFormat( elem, u
"application/json"_s );
468 elem.appendChild( dcpTypeElem.cloneNode().toElement() );
469 requestElem.appendChild( elem );
472 elem = doc.createElement( ( version ==
"1.1.1"_L1 ?
"DescribeLayer" :
"sld:DescribeLayer" ) );
473 appendFormat( elem, u
"text/xml"_s );
474 elem.appendChild( dcpTypeElem.cloneNode().toElement() );
475 requestElem.appendChild( elem );
478 elem = doc.createElement( ( version ==
"1.1.1"_L1 ?
"GetStyles" :
"qgs:GetStyles" ) );
479 appendFormat( elem, u
"text/xml"_s );
480 elem.appendChild( dcpTypeElem.cloneNode().toElement() );
481 requestElem.appendChild( elem );
486 elem = doc.createElement( u
"GetPrint"_s );
487 appendFormat( elem, u
"svg"_s );
488 appendFormat( elem, u
"png"_s );
489 appendFormat( elem, u
"pdf"_s );
490 elem.appendChild( dcpTypeElem.cloneNode().toElement() );
491 requestElem.appendChild( elem );
495 elem = doc.createElement( u
"Exception"_s );
496 appendFormat( elem, ( version ==
"1.1.1"_L1 ?
"application/vnd.ogc.se_xml" :
"XML" ) );
497 capabilityElem.appendChild( elem );
500 if ( version ==
"1.3.0"_L1 )
502 elem = doc.createElement( u
"sld:UserDefinedSymbolization"_s );
503 elem.setAttribute( u
"SupportSLD"_s, u
"1"_s );
504 elem.setAttribute( u
"UserLayer"_s, u
"0"_s );
505 elem.setAttribute( u
"UserStyle"_s, u
"1"_s );
506 elem.setAttribute( u
"RemoteWFS"_s, u
"0"_s );
507 elem.setAttribute( u
"InlineFeature"_s, u
"0"_s );
508 elem.setAttribute( u
"RemoteWCS"_s, u
"0"_s );
509 capabilityElem.appendChild( elem );
517 return capabilityElem;
522 QDomElement inspireCapabilitiesElem;
525 return inspireCapabilitiesElem;
527 inspireCapabilitiesElem = doc.createElement( u
"inspire_vs:ExtendedCapabilities"_s );
531 if ( !inspireMetadataUrl.isEmpty() )
533 QDomElement inspireCommonMetadataUrlElem = doc.createElement( u
"inspire_common:MetadataUrl"_s );
534 inspireCommonMetadataUrlElem.setAttribute( u
"xsi:type"_s, u
"inspire_common:resourceLocatorType"_s );
536 QDomElement inspireCommonMetadataUrlUrlElem = doc.createElement( u
"inspire_common:URL"_s );
537 inspireCommonMetadataUrlUrlElem.appendChild( doc.createTextNode( inspireMetadataUrl ) );
538 inspireCommonMetadataUrlElem.appendChild( inspireCommonMetadataUrlUrlElem );
541 if ( !inspireMetadataUrlType.isNull() )
543 QDomElement inspireCommonMetadataUrlMediaTypeElem = doc.createElement( u
"inspire_common:MediaType"_s );
544 inspireCommonMetadataUrlMediaTypeElem.appendChild( doc.createTextNode( inspireMetadataUrlType ) );
545 inspireCommonMetadataUrlElem.appendChild( inspireCommonMetadataUrlMediaTypeElem );
548 inspireCapabilitiesElem.appendChild( inspireCommonMetadataUrlElem );
552 QDomElement inspireCommonResourceTypeElem = doc.createElement( u
"inspire_common:ResourceType"_s );
553 inspireCommonResourceTypeElem.appendChild( doc.createTextNode( u
"service"_s ) );
554 inspireCapabilitiesElem.appendChild( inspireCommonResourceTypeElem );
556 QDomElement inspireCommonSpatialDataServiceTypeElem = doc.createElement( u
"inspire_common:SpatialDataServiceType"_s );
557 inspireCommonSpatialDataServiceTypeElem.appendChild( doc.createTextNode( u
"view"_s ) );
558 inspireCapabilitiesElem.appendChild( inspireCommonSpatialDataServiceTypeElem );
561 if ( !inspireTemporalReference.isNull() )
563 QDomElement inspireCommonTemporalReferenceElem = doc.createElement( u
"inspire_common:TemporalReference"_s );
564 QDomElement inspireCommonDateOfLastRevisionElem = doc.createElement( u
"inspire_common:DateOfLastRevision"_s );
565 inspireCommonDateOfLastRevisionElem.appendChild( doc.createTextNode( inspireTemporalReference ) );
566 inspireCommonTemporalReferenceElem.appendChild( inspireCommonDateOfLastRevisionElem );
567 inspireCapabilitiesElem.appendChild( inspireCommonTemporalReferenceElem );
570 QDomElement inspireCommonMetadataPointOfContactElem = doc.createElement( u
"inspire_common:MetadataPointOfContact"_s );
573 QDomElement inspireCommonOrganisationNameElem = doc.createElement( u
"inspire_common:OrganisationName"_s );
574 if ( !contactOrganization.isNull() )
576 inspireCommonOrganisationNameElem.appendChild( doc.createTextNode( contactOrganization ) );
578 inspireCommonMetadataPointOfContactElem.appendChild( inspireCommonOrganisationNameElem );
581 QDomElement inspireCommonEmailAddressElem = doc.createElement( u
"inspire_common:EmailAddress"_s );
582 if ( !contactMail.isNull() )
584 inspireCommonEmailAddressElem.appendChild( doc.createTextNode( contactMail ) );
586 inspireCommonMetadataPointOfContactElem.appendChild( inspireCommonEmailAddressElem );
588 inspireCapabilitiesElem.appendChild( inspireCommonMetadataPointOfContactElem );
591 if ( !inspireMetadataDate.isNull() )
593 QDomElement inspireCommonMetadataDateElem = doc.createElement( u
"inspire_common:MetadataDate"_s );
594 inspireCommonMetadataDateElem.appendChild( doc.createTextNode( inspireMetadataDate ) );
595 inspireCapabilitiesElem.appendChild( inspireCommonMetadataDateElem );
600 QDomElement inspireCommonSupportedLanguagesElem = doc.createElement( u
"inspire_common:SupportedLanguages"_s );
601 inspireCommonSupportedLanguagesElem.setAttribute( u
"xsi:type"_s, u
"inspire_common:supportedLanguagesType"_s );
603 QDomElement inspireCommonLanguageElem = doc.createElement( u
"inspire_common:Language"_s );
606 QDomElement inspireCommonDefaultLanguageElem = doc.createElement( u
"inspire_common:DefaultLanguage"_s );
607 inspireCommonDefaultLanguageElem.appendChild( inspireCommonLanguageElem );
608 inspireCommonSupportedLanguagesElem.appendChild( inspireCommonDefaultLanguageElem );
612 QDomElement inspireCommonSupportedLanguageElem = doc.createElement(
"inspire_common:SupportedLanguage" );
613 inspireCommonSupportedLanguageElem.appendChild( inspireCommonLanguageElem.cloneNode().toElement() );
614 inspireCommonSupportedLanguagesElem.appendChild( inspireCommonSupportedLanguageElem );
617 inspireCapabilitiesElem.appendChild( inspireCommonSupportedLanguagesElem );
619 QDomElement inspireCommonResponseLanguageElem = doc.createElement( u
"inspire_common:ResponseLanguage"_s );
620 inspireCommonResponseLanguageElem.appendChild( inspireCommonLanguageElem.cloneNode().toElement() );
621 inspireCapabilitiesElem.appendChild( inspireCommonResponseLanguageElem );
623 return inspireCapabilitiesElem;
629 if ( projectComposers.size() == 0 )
630 return QDomElement();
634 QDomElement composerTemplatesElem = doc.createElement( u
"ComposerTemplates"_s );
635 QList<QgsPrintLayout *>::const_iterator cIt = projectComposers.constBegin();
636 for ( ; cIt != projectComposers.constEnd(); ++cIt )
639 if ( restrictedComposers.contains( layout->
name() ) )
651 QDomElement composerTemplateElem = doc.createElement( u
"ComposerTemplate"_s );
652 composerTemplateElem.setAttribute( u
"name"_s, layout->
name() );
655 composerTemplateElem.setAttribute( u
"width"_s, width.
length() );
656 composerTemplateElem.setAttribute( u
"height"_s, height.
length() );
660 if ( atlas && atlas->
enabled() )
662 composerTemplateElem.setAttribute( u
"atlasEnabled"_s, u
"1"_s );
669 layerName = cLayer->
id();
671 else if ( layerName.isEmpty() )
673 layerName = cLayer->
name();
675 composerTemplateElem.setAttribute( u
"atlasCoverageLayer"_s, layerName );
680 QList<QgsLayoutItemMap *> layoutMapList;
682 QList<QgsLayoutItemMap *>::const_iterator cmIt = layoutMapList.constBegin();
685 for ( ; cmIt != layoutMapList.constEnd(); ++cmIt )
689 QDomElement composerMapElem = doc.createElement( u
"ComposerMap"_s );
690 composerMapElem.setAttribute( u
"name"_s, u
"map%1"_s.arg( mapId ) );
691 composerMapElem.setAttribute( u
"itemName"_s, composerMap->
displayName() );
693 composerMapElem.setAttribute( u
"width"_s, composerMap->rect().width() );
694 composerMapElem.setAttribute( u
"height"_s, composerMap->rect().height() );
695 composerTemplateElem.appendChild( composerMapElem );
699 QList<QgsLayoutItemLabel *> composerLabelList;
701 QList<QgsLayoutItemLabel *>::const_iterator clIt = composerLabelList.constBegin();
702 for ( ; clIt != composerLabelList.constEnd(); ++clIt )
705 QString
id = composerLabel->
id();
709 QDomElement composerLabelElem = doc.createElement( u
"ComposerLabel"_s );
710 composerLabelElem.setAttribute( u
"name"_s,
id );
711 composerTemplateElem.appendChild( composerLabelElem );
715 QList<QgsLayoutItemHtml *> composerHtmlList;
717 QList<QgsLayoutItemHtml *>::const_iterator chIt = composerHtmlList.constBegin();
718 for ( ; chIt != composerHtmlList.constEnd(); ++chIt )
724 QString
id = composerHtml->
frame( 0 )->
id();
728 QDomElement composerHtmlElem = doc.createElement( u
"ComposerHtml"_s );
729 composerHtmlElem.setAttribute( u
"name"_s,
id );
730 composerTemplateElem.appendChild( composerHtmlElem );
733 composerTemplatesElem.appendChild( composerTemplateElem );
736 if ( composerTemplatesElem.childNodes().size() == 0 )
737 return QDomElement();
739 return composerTemplatesElem;
745 if ( wfsLayerIds.size() == 0 )
746 return QDomElement();
748 QDomElement wfsLayersElem = doc.createElement( u
"WFSLayers"_s );
749 for (
int i = 0; i < wfsLayerIds.size(); ++i )
757 QDomElement wfsLayerElem = doc.createElement( u
"WFSLayer"_s );
760 wfsLayerElem.setAttribute( u
"name"_s, layer->
id() );
764 wfsLayerElem.setAttribute( u
"name"_s, layer->
name() );
766 wfsLayersElem.appendChild( wfsLayerElem );
769 return wfsLayersElem;
774 QDomElement &parentLayer,
779 const QMap<QString, QgsWmsLayerInfos> &wmsLayerInfos,
780 bool projectSettings,
781 QList<QgsDateTimeRange> &parentDateRanges
786 parentLayer.setAttribute( u
"queryable"_s,
hasQueryableLayers( layerIds, wmsLayerInfos ) ? u
"1"_s : u
"0"_s );
789 QMap<QString, QgsRectangle> crsExtents =
combineCrsExtents( layerIds, wmsLayerInfos );
791 appendCrsElementsToLayer( doc, parentLayer, crsExtents.keys(), QStringList(), !wgs84BoundingRect.
isNull() );
792 appendLayerWgs84BoundingRect( doc, parentLayer, wgs84BoundingRect );
793 appendLayerCrsExtents( doc, parentLayer, crsExtents );
797 appendLayersFromTreeGroup( doc, parentLayer, serverIface, project, request, layerTreeGroup, wmsLayerInfos, projectSettings, parentDateRanges );
804 QDomElement layerParentElem = doc.createElement( u
"Layer"_s );
807 if ( !skipNameForGroup )
811 if ( rootLayerName.isEmpty() && !project->
title().isEmpty() )
813 rootLayerName = project->
title();
816 if ( !rootLayerName.isEmpty() )
818 QDomElement layerParentNameElem = doc.createElement( u
"Name"_s );
819 QDomText layerParentNameText = doc.createTextNode( rootLayerName );
820 layerParentNameElem.appendChild( layerParentNameText );
821 layerParentElem.appendChild( layerParentNameElem );
826 QDomElement layerParentTitleElem = doc.createElement( u
"Title"_s );
828 layerParentTitleElem.appendChild( layerParentTitleText );
829 layerParentElem.appendChild( layerParentTitleElem );
833 if ( !rootLayerAbstract.isEmpty() )
835 QDomElement layerParentAbstElem = doc.createElement( u
"Abstract"_s );
836 QDomText layerParentAbstText = doc.createCDATASection( rootLayerAbstract );
837 layerParentAbstElem.appendChild( layerParentAbstText );
838 layerParentElem.appendChild( layerParentAbstElem );
842 addKeywordListElement( project, doc, layerParentElem );
845 if ( projectSettings )
847 QDomElement treeNameElem = doc.createElement( u
"TreeName"_s );
848 QDomText treeNameText = doc.createTextNode( project->
title() );
849 treeNameElem.appendChild( treeNameText );
850 layerParentElem.appendChild( treeNameElem );
856 auto outputCrsList = QList<QgsCoordinateReferenceSystem>();
862 outputCrsList.append( crs );
890 QMap<QString, QgsRectangle> wmsCrsExtents;
902 appendCrsElementsToLayer( doc, layerParentElem, wmsCrsExtents.keys(), QStringList(), project->
crs().
isEarthCrs() );
903 appendLayerWgs84BoundingRect( doc, layerParentElem, wmsWgs84BoundingRect );
904 appendLayerCrsExtents( doc, layerParentElem, wmsCrsExtents );
906 QList<QgsDateTimeRange> parentDateRanges;
907 appendLayersFromTreeGroup( doc, layerParentElem, serverIface, project, request, projectLayerTreeRoot, wmsLayerInfos, projectSettings, parentDateRanges );
911 QList<QgsDateTimeRange> parentDateRanges;
912 handleLayersFromTreeGroup( doc, layerParentElem, serverIface, project, request, projectLayerTreeRoot, wmsLayerInfos, projectSettings, parentDateRanges );
915 return layerParentElem;
923 void writeServerProperties( QDomDocument &doc, QDomElement &layerElem,
const QgsProject *project,
const QgsMapLayerServerProperties *serverProperties,
const QString &name,
const QString &version )
925 const QString title = serverProperties->
title();
926 QDomElement titleElem = doc.createElement( u
"Title"_s );
927 QDomText titleText = doc.createTextNode( !title.isEmpty() ? title : name );
928 titleElem.appendChild( titleText );
929 layerElem.appendChild( titleElem );
931 const QString abstract = serverProperties->
abstract();
932 if ( !abstract.isEmpty() )
934 QDomElement abstractElem = doc.createElement( u
"Abstract"_s );
935 QDomText abstractText = doc.createTextNode( abstract );
936 abstractElem.appendChild( abstractText );
937 layerElem.appendChild( abstractElem );
942 const QStringList keywords = !serverProperties->
keywordList().isEmpty() ? serverProperties->
keywordList().split(
',' ) : QStringList();
943 if ( !keywords.isEmpty() )
945 QDomElement keywordListElem = doc.createElement( u
"KeywordList"_s );
946 for (
const QString &keyword : std::as_const( keywords ) )
948 QDomElement keywordElem = doc.createElement( u
"Keyword"_s );
949 QDomText keywordText = doc.createTextNode( keyword.trimmed() );
950 keywordElem.appendChild( keywordText );
953 keywordElem.setAttribute( u
"vocabulary"_s, u
"SIA_Geo405"_s );
955 keywordListElem.appendChild( keywordElem );
957 layerElem.appendChild( keywordListElem );
961 const QString dataUrl = serverProperties->
dataUrl();
962 if ( !dataUrl.isEmpty() )
964 QDomElement dataUrlElem = doc.createElement( u
"DataURL"_s );
965 QDomElement dataUrlFormatElem = doc.createElement( u
"Format"_s );
966 const QString dataUrlFormat = serverProperties->
dataUrlFormat();
967 QDomText dataUrlFormatText = doc.createTextNode( dataUrlFormat );
968 dataUrlFormatElem.appendChild( dataUrlFormatText );
969 dataUrlElem.appendChild( dataUrlFormatElem );
970 QDomElement dataORElem = doc.createElement( u
"OnlineResource"_s );
971 dataORElem.setAttribute( u
"xmlns:xlink"_s, u
"http://www.w3.org/1999/xlink"_s );
972 dataORElem.setAttribute( u
"xlink:type"_s, u
"simple"_s );
973 dataORElem.setAttribute( u
"xlink:href"_s, dataUrl );
974 dataUrlElem.appendChild( dataORElem );
975 layerElem.appendChild( dataUrlElem );
979 const QString attribution = serverProperties->
attribution();
980 if ( !attribution.isEmpty() )
982 QDomElement attribElem = doc.createElement( u
"Attribution"_s );
983 QDomElement attribTitleElem = doc.createElement( u
"Title"_s );
984 QDomText attribText = doc.createTextNode( attribution );
985 attribTitleElem.appendChild( attribText );
986 attribElem.appendChild( attribTitleElem );
987 const QString attributionUrl = serverProperties->
attributionUrl();
988 if ( !attributionUrl.isEmpty() )
990 QDomElement attribORElem = doc.createElement( u
"OnlineResource"_s );
991 attribORElem.setAttribute( u
"xmlns:xlink"_s, u
"http://www.w3.org/1999/xlink"_s );
992 attribORElem.setAttribute( u
"xlink:type"_s, u
"simple"_s );
993 attribORElem.setAttribute( u
"xlink:href"_s, attributionUrl );
994 attribElem.appendChild( attribORElem );
996 layerElem.appendChild( attribElem );
1000 const QList<QgsServerMetadataUrlProperties::MetadataUrl> metadataUrls = serverProperties->
metadataUrls();
1001 for (
const QgsMapLayerServerProperties::MetadataUrl &metadataUrl : std::as_const( metadataUrls ) )
1003 QDomElement metaUrlElem = doc.createElement( u
"MetadataURL"_s );
1004 const QString metadataUrlType = metadataUrl.type;
1005 if ( version ==
"1.1.1"_L1 )
1007 metaUrlElem.setAttribute( u
"type"_s, metadataUrlType );
1009 else if ( metadataUrlType ==
"FGDC"_L1 )
1011 metaUrlElem.setAttribute( u
"type"_s, u
"FGDC:1998"_s );
1013 else if ( metadataUrlType ==
"TC211"_L1 )
1015 metaUrlElem.setAttribute( u
"type"_s, u
"ISO19115:2003"_s );
1019 metaUrlElem.setAttribute( u
"type"_s, metadataUrlType );
1021 const QString metadataUrlFormat = metadataUrl.format;
1022 if ( !metadataUrlFormat.isEmpty() )
1024 QDomElement metaUrlFormatElem = doc.createElement( u
"Format"_s );
1025 QDomText metaUrlFormatText = doc.createTextNode( metadataUrlFormat );
1026 metaUrlFormatElem.appendChild( metaUrlFormatText );
1027 metaUrlElem.appendChild( metaUrlFormatElem );
1029 QDomElement metaUrlORElem = doc.createElement( u
"OnlineResource"_s );
1030 metaUrlORElem.setAttribute( u
"xmlns:xlink"_s, u
"http://www.w3.org/1999/xlink"_s );
1031 metaUrlORElem.setAttribute( u
"xlink:type"_s, u
"simple"_s );
1032 metaUrlORElem.setAttribute( u
"xlink:href"_s, metadataUrl.url );
1033 metaUrlElem.appendChild( metaUrlORElem );
1034 layerElem.appendChild( metaUrlElem );
1038 void writeLegendUrl(
1040 QDomElement &styleElem,
1041 const QString &legendUrl,
1042 const QString &legendUrlFormat,
1043 const QString &name,
1044 const QString &styleName,
1045 const QgsProject *project,
1047 const QgsServerSettings *settings
1051 QDomElement getLayerLegendGraphicElem = doc.createElement( u
"LegendURL"_s );
1053 QString customHrefString = legendUrl;
1055 QStringList getLayerLegendGraphicFormats;
1056 if ( !customHrefString.isEmpty() )
1058 getLayerLegendGraphicFormats << legendUrlFormat;
1062 getLayerLegendGraphicFormats << u
"image/png"_s;
1065 for (
const QString &getLayerLegendGraphicFormat : std::as_const( getLayerLegendGraphicFormats ) )
1067 QDomElement getLayerLegendGraphicFormatElem = doc.createElement( u
"Format"_s );
1068 QDomText getLayerLegendGraphicFormatText = doc.createTextNode( getLayerLegendGraphicFormat );
1069 getLayerLegendGraphicFormatElem.appendChild( getLayerLegendGraphicFormatText );
1070 getLayerLegendGraphicElem.appendChild( getLayerLegendGraphicFormatElem );
1074 if ( customHrefString.isEmpty() )
1077 QUrl href =
serviceUrl( request, project, *settings );
1078 const QString hrefString = href.toString() + ( href.hasQuery() ?
"&" :
"?" );
1080 QUrl mapUrl( hrefString );
1081 QUrlQuery mapUrlQuery( mapUrl.query() );
1082 mapUrlQuery.addQueryItem( u
"SERVICE"_s, u
"WMS"_s );
1083 mapUrlQuery.addQueryItem( u
"VERSION"_s, request.wmsParameters().version() );
1084 mapUrlQuery.addQueryItem( u
"REQUEST"_s, u
"GetLegendGraphic"_s );
1085 mapUrlQuery.addQueryItem( u
"LAYER"_s, name );
1086 mapUrlQuery.addQueryItem( u
"FORMAT"_s, u
"image/png"_s );
1087 mapUrlQuery.addQueryItem( u
"STYLE"_s, styleName );
1088 if ( request.wmsParameters().version() ==
"1.3.0"_L1 )
1090 mapUrlQuery.addQueryItem( u
"SLD_VERSION"_s, u
"1.1.0"_s );
1092 mapUrl.setQuery( mapUrlQuery );
1093 customHrefString = mapUrl.toString();
1096 QDomElement getLayerLegendGraphicORElem = doc.createElement( u
"OnlineResource"_s );
1097 getLayerLegendGraphicORElem.setAttribute( u
"xmlns:xlink"_s, u
"http://www.w3.org/1999/xlink"_s );
1098 getLayerLegendGraphicORElem.setAttribute( u
"xlink:type"_s, u
"simple"_s );
1099 getLayerLegendGraphicORElem.setAttribute( u
"xlink:href"_s, customHrefString );
1100 getLayerLegendGraphicElem.appendChild( getLayerLegendGraphicORElem );
1101 styleElem.appendChild( getLayerLegendGraphicElem );
1104 QDomElement createStyleElement( QDomDocument &doc,
const QString &styleName )
1106 QDomElement styleElem = doc.createElement( u
"Style"_s );
1107 QDomElement styleNameElem = doc.createElement( u
"Name"_s );
1108 QDomText styleNameText = doc.createTextNode( styleName );
1109 styleNameElem.appendChild( styleNameText );
1110 QDomElement styleTitleElem = doc.createElement( u
"Title"_s );
1111 QDomText styleTitleText = doc.createTextNode( styleName );
1112 styleTitleElem.appendChild( styleTitleText );
1113 styleElem.appendChild( styleNameElem );
1114 styleElem.appendChild( styleTitleElem );
1122 QString dateToString(
const QDateTime &dateTime,
bool dateOnly )
1124 return dateOnly ? dateTime.date().toString( Qt::DateFormat::ISODate ) : dateTime.toString( Qt::DateFormat::ISODate );
1128 bool writeTimeDimensionNode( QDomDocument &doc, QDomElement &layerElem,
const QList<QgsDateTimeRange> &dateRanges )
1136 const bool dateOnly = std::all_of( dateRanges.constBegin(), dateRanges.constEnd(), [](
const QgsDateTimeRange &r ) {
1137 return r.begin().time() == QTime( 0, 0 ) && ( r.isInstant() || r.end().time() == QTime( 0, 0 ) );
1140 QStringList strValues;
1144 if ( range.begin().isValid() && range.end().isValid() )
1146 strValues << ( range.isInstant() ? dateToString( range.begin(), dateOnly ) : u
"%1/%2"_s.arg( dateToString( range.begin(), dateOnly ) ).arg( dateToString( range.end(), dateOnly ) ) );
1150 QDomElement dimElem = doc.createElement( u
"Dimension"_s );
1151 dimElem.setAttribute( u
"name"_s, u
"TIME"_s );
1152 dimElem.setAttribute( u
"units"_s, u
"ISO8601"_s );
1153 QDomText dimValuesText = doc.createTextNode( strValues.join( QChar(
',' ) ) );
1154 dimElem.appendChild( dimValuesText );
1156 layerElem.appendChild( dimElem );
1161 void appendLayersFromTreeGroup(
1163 QDomElement &parentLayer,
1164 QgsServerInterface *serverIface,
1165 const QgsProject *project,
1167 const QgsLayerTreeGroup *layerTreeGroup,
1168 const QMap<QString, QgsWmsLayerInfos> &wmsLayerInfos,
1169 bool projectSettings,
1170 QList<QgsDateTimeRange> &parentDateRanges
1173 const QString version = request.wmsParameters().version();
1178 QList<QgsLayerTreeNode *> layerTreeGroupChildren = layerTreeGroup->
children();
1179 for (
int i = 0; i < layerTreeGroupChildren.size(); ++i )
1181 QgsLayerTreeNode *treeNode = layerTreeGroupChildren.at( i );
1182 QDomElement layerElem = doc.createElement( u
"Layer"_s );
1184 if ( projectSettings )
1186 layerElem.setAttribute( u
"visible"_s, treeNode->
isVisible() );
1188 layerElem.setAttribute( u
"expanded"_s, treeNode->
isExpanded() );
1193 QgsLayerTreeGroup *treeGroupChild =
static_cast<QgsLayerTreeGroup *
>( treeNode );
1195 QString name = treeGroupChild->
name();
1196 if ( restrictedLayers.contains( name ) )
1201 if ( projectSettings )
1209 if ( !skipNameForGroup )
1211 QDomElement nameElem = doc.createElement( u
"Name"_s );
1213 if ( !shortName.isEmpty() )
1214 nameText = doc.createTextNode( shortName );
1216 nameText = doc.createTextNode( name );
1217 nameElem.appendChild( nameText );
1218 layerElem.appendChild( nameElem );
1221 writeServerProperties( doc, layerElem, project, treeGroupChild->
serverProperties(), name, version );
1224 const QString styleName = u
"default"_s;
1225 QDomElement styleElem = createStyleElement( doc, styleName );
1228 layerElem.appendChild( styleElem );
1231 if ( projectSettings )
1233 QDomElement treeNameElem = doc.createElement( u
"TreeName"_s );
1234 QDomText treeNameText = doc.createTextNode( name );
1235 treeNameElem.appendChild( treeNameText );
1236 layerElem.appendChild( treeNameElem );
1240 QList<QgsDateTimeRange> childrenDateRanges;
1241 handleLayersFromTreeGroup( doc, layerElem, serverIface, project, request, treeGroupChild, wmsLayerInfos, projectSettings, childrenDateRanges );
1245 writeTimeDimensionNode( doc, layerElem, childrenDateRanges );
1246 parentDateRanges.append( childrenDateRanges );
1257 QgsLayerTreeLayer *treeLayer =
static_cast<QgsLayerTreeLayer *
>( treeNode );
1258 QgsMapLayer *l = treeLayer->
layer();
1259 if ( !wmsLayerInfos.contains( treeLayer->
layerId() ) )
1264 const QgsWmsLayerInfos &layerInfos = wmsLayerInfos[treeLayer->
layerId()];
1266 layerElem.setAttribute( u
"queryable"_s, layerInfos.
queryable ? u
"1"_s : u
"0"_s );
1268 QDomElement nameElem = doc.createElement( u
"Name"_s );
1269 QDomText nameText = doc.createTextNode( layerInfos.
name );
1270 nameElem.appendChild( nameText );
1271 layerElem.appendChild( nameElem );
1278 appendCrsElementsToLayer( doc, layerElem, layerInfos.
crsExtents.keys(), QStringList(), l->
crs().
isEarthCrs() );
1282 appendLayerCrsExtents( doc, layerElem, layerInfos.
crsExtents );
1286 appendLayerStyles( doc, layerElem, layerInfos, project, request, serverIface->
serverSettings() );
1292 auto formatScale = [](
double value ) {
1293 const thread_local QRegularExpression trailingZeroRegEx = QRegularExpression( u
"0+$"_s );
1294 const thread_local QRegularExpression trailingPointRegEx = QRegularExpression( u
"[.]+$"_s );
1295 return QString::number( value,
'f' ).remove( trailingZeroRegEx ).remove( trailingPointRegEx );
1298 if ( version ==
"1.1.1"_L1 )
1301 double SCALE_TO_SCALEHINT =
OGC_PX_M * M_SQRT2;
1303 QDomElement scaleHintElem = doc.createElement( u
"ScaleHint"_s );
1304 scaleHintElem.setAttribute( u
"min"_s, formatScale( layerInfos.
maxScale * SCALE_TO_SCALEHINT ) );
1305 scaleHintElem.setAttribute( u
"max"_s, formatScale( layerInfos.
minScale * SCALE_TO_SCALEHINT ) );
1306 layerElem.appendChild( scaleHintElem );
1310 QDomElement minScaleElem = doc.createElement( u
"MinScaleDenominator"_s );
1311 QDomText minScaleText = doc.createTextNode( formatScale( layerInfos.
maxScale ) );
1312 minScaleElem.appendChild( minScaleText );
1313 layerElem.appendChild( minScaleElem );
1315 QDomElement maxScaleElem = doc.createElement( u
"MaxScaleDenominator"_s );
1316 QDomText maxScaleText = doc.createTextNode( formatScale( layerInfos.
minScale ) );
1317 maxScaleElem.appendChild( maxScaleText );
1318 layerElem.appendChild( maxScaleElem );
1322 bool timeDimensionAdded {
false };
1327 QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( l );
1328 QgsMapLayerServerProperties *serverProperties =
static_cast<QgsMapLayerServerProperties *
>( vl->
serverProperties() );
1329 const QList<QgsMapLayerServerProperties::WmsDimensionInfo> wmsDims = serverProperties->
wmsDimensions();
1330 for (
const QgsMapLayerServerProperties::WmsDimensionInfo &dim : wmsDims )
1334 if ( fieldIndex == -1 )
1339 QSet<QVariant> uniqueValues = vl->
uniqueValues( fieldIndex );
1342 if ( !dim.endFieldName.isEmpty() )
1344 int endFieldIndex = vl->
fields().
indexOf( dim.endFieldName );
1346 if ( endFieldIndex == -1 )
1350 uniqueValues.unite( vl->
uniqueValues( endFieldIndex ) );
1353 QList<QVariant> values = qgis::setToList( uniqueValues );
1354 std::sort( values.begin(), values.end() );
1356 QDomElement dimElem = doc.createElement( u
"Dimension"_s );
1357 dimElem.setAttribute( u
"name"_s, dim.name );
1359 if ( dim.name.toUpper() ==
"TIME"_L1 )
1361 timeDimensionAdded =
true;
1364 if ( !dim.units.isEmpty() )
1366 dimElem.setAttribute( u
"units"_s, dim.units );
1368 if ( !dim.unitSymbol.isEmpty() )
1370 dimElem.setAttribute( u
"unitSymbol"_s, dim.unitSymbol );
1372 if ( !values.isEmpty() && dim.defaultDisplayType == QgsMapLayerServerProperties::WmsDimensionInfo::MinValue )
1374 dimElem.setAttribute( u
"default"_s, values.first().toString() );
1376 else if ( !values.isEmpty() && dim.defaultDisplayType == QgsMapLayerServerProperties::WmsDimensionInfo::MaxValue )
1378 dimElem.setAttribute( u
"default"_s, values.last().toString() );
1380 else if ( dim.defaultDisplayType == QgsMapLayerServerProperties::WmsDimensionInfo::ReferenceValue )
1382 dimElem.setAttribute( u
"default"_s, dim.referenceValue.toString() );
1384 dimElem.setAttribute( u
"multipleValues"_s, u
"1"_s );
1385 dimElem.setAttribute( u
"nearestValue"_s, u
"0"_s );
1386 if ( projectSettings )
1388 dimElem.setAttribute( u
"fieldName"_s, dim.fieldName );
1389 dimElem.setAttribute( u
"endFieldName"_s, dim.endFieldName );
1392 QStringList strValues;
1393 for (
const QVariant &v : values )
1395 strValues << v.toString();
1397 QDomText dimValuesText = doc.createTextNode( strValues.join(
", "_L1 ) );
1398 dimElem.appendChild( dimValuesText );
1399 layerElem.appendChild( dimElem );
1410 const bool dateOnly = writeTimeDimensionNode( doc, layerElem, allRanges );
1412 parentDateRanges.append( allRanges );
1414 QDomElement timeExtentElem = doc.createElement( u
"Extent"_s );
1415 timeExtentElem.setAttribute( u
"name"_s, u
"TIME"_s );
1418 const QString extent = u
"%1/%2"_s.arg( dateToString( timeExtent.
begin(), dateOnly ) ).arg( dateToString( timeExtent.
end(), dateOnly ) );
1419 QDomText extentValueText = doc.createTextNode( extent );
1420 timeExtentElem.appendChild( extentValueText );
1421 layerElem.appendChild( timeExtentElem );
1424 if ( projectSettings )
1426 appendLayerProjectSettings( doc, layerElem, l );
1430 parentLayer.appendChild( layerElem );
1434 void appendLayerStyles( QDomDocument &doc, QDomElement &layerElem,
const QgsWmsLayerInfos &layerInfos,
const QgsProject *project,
const QgsWmsRequest &request,
const QgsServerSettings *settings )
1436 for (
const QString &styleName : std::as_const( layerInfos.
styles ) )
1438 QDomElement styleElem = createStyleElement( doc, styleName );
1440 writeLegendUrl( doc, styleElem, layerInfos.
legendUrl, layerInfos.
legendUrlFormat, layerInfos.
name, styleName, project, request, settings );
1442 layerElem.appendChild( styleElem );
1446 void appendCrsElementsToLayer( QDomDocument &doc, QDomElement &layerElement,
const QStringList &crsList,
const QStringList &constrainedCrsList,
bool hasEarthCrs )
1448 if ( layerElement.isNull() )
1453 const QString version = doc.documentElement().attribute( u
"version"_s );
1456 QDomElement titleElement = layerElement.firstChildElement( u
"Title"_s );
1457 QDomElement abstractElement = layerElement.firstChildElement( u
"Abstract"_s );
1458 QDomElement keywordListElement = layerElement.firstChildElement( u
"KeywordList"_s );
1459 QDomElement CRSPrecedingElement = !keywordListElement.isNull() ? keywordListElement : !abstractElement.isNull() ? abstractElement : titleElement;
1461 if ( CRSPrecedingElement.isNull() )
1464 const QDomElement keyElement = layerElement.firstChildElement( u
"KeywordList"_s );
1465 CRSPrecedingElement = keyElement;
1469 if ( !constrainedCrsList.isEmpty() )
1471 for (
int i = constrainedCrsList.size() - 1; i >= 0; --i )
1473 appendCrsElementToLayer( doc, layerElement, CRSPrecedingElement, constrainedCrsList.at( i ) );
1478 for (
const QString &crs : crsList )
1480 appendCrsElementToLayer( doc, layerElement, CRSPrecedingElement, crs );
1486 if ( version ==
"1.3.0"_L1 && hasEarthCrs )
1488 appendCrsElementToLayer( doc, layerElement, CRSPrecedingElement, QString(
"CRS:84" ) );
1492 void appendCrsElementToLayer( QDomDocument &doc, QDomElement &layerElement,
const QDomElement &precedingElement,
const QString &crsText )
1494 if ( crsText.isEmpty() )
1496 const QString version = doc.documentElement().attribute( u
"version"_s );
1497 QDomElement crsElement = doc.createElement( version ==
"1.1.1"_L1 ?
"SRS" :
"CRS" );
1498 QDomText crsTextNode = doc.createTextNode( crsText );
1499 crsElement.appendChild( crsTextNode );
1500 layerElement.insertAfter( crsElement, precedingElement );
1503 void appendLayerWgs84BoundingRect( QDomDocument &doc, QDomElement &layerElem,
const QgsRectangle &wgs84BoundingRect )
1506 if ( wgs84BoundingRect.
isNull() )
1512 QDomElement ExGeoBBoxElement;
1513 const int wgs84precision = 6;
1514 const QString version = doc.documentElement().attribute( u
"version"_s );
1515 if ( version ==
"1.1.1"_L1 )
1517 ExGeoBBoxElement = doc.createElement( u
"LatLonBoundingBox"_s );
1525 ExGeoBBoxElement = doc.createElement( u
"EX_GeographicBoundingBox"_s );
1526 QDomElement wBoundLongitudeElement = doc.createElement( u
"westBoundLongitude"_s );
1528 wBoundLongitudeElement.appendChild( wBoundLongitudeText );
1529 ExGeoBBoxElement.appendChild( wBoundLongitudeElement );
1530 QDomElement eBoundLongitudeElement = doc.createElement( u
"eastBoundLongitude"_s );
1532 eBoundLongitudeElement.appendChild( eBoundLongitudeText );
1533 ExGeoBBoxElement.appendChild( eBoundLongitudeElement );
1534 QDomElement sBoundLatitudeElement = doc.createElement( u
"southBoundLatitude"_s );
1536 sBoundLatitudeElement.appendChild( sBoundLatitudeText );
1537 ExGeoBBoxElement.appendChild( sBoundLatitudeElement );
1538 QDomElement nBoundLatitudeElement = doc.createElement( u
"northBoundLatitude"_s );
1540 nBoundLatitudeElement.appendChild( nBoundLatitudeText );
1541 ExGeoBBoxElement.appendChild( nBoundLatitudeElement );
1544 const QDomElement lastCRSElem = layerElem.lastChildElement( version ==
"1.1.1"_L1 ?
"SRS" :
"CRS" );
1545 if ( !lastCRSElem.isNull() )
1547 layerElem.insertAfter( ExGeoBBoxElement, lastCRSElem );
1551 layerElem.appendChild( ExGeoBBoxElement );
1555 void appendLayerCrsExtents( QDomDocument &doc, QDomElement &layerElem,
const QMap<QString, QgsRectangle> &crsExtents )
1557 const QString version = doc.documentElement().attribute( u
"version"_s );
1559 const auto &keys = crsExtents.keys();
1560 for (
const QString &crsText : std::as_const( keys ) )
1563 QgsRectangle crsExtent( crsExtents[crsText] );
1565 if ( crsExtent.isNull() )
1577 QDomElement bBoxElement = doc.createElement( u
"BoundingBox"_s );
1580 bBoxElement.setAttribute( version ==
"1.1.1"_L1 ?
"SRS" :
"CRS", crs.
authid() );
1593 QDomElement lastBBoxElem = layerElem.lastChildElement( u
"BoundingBox"_s );
1594 if ( !lastBBoxElem.isNull() )
1596 layerElem.insertAfter( bBoxElement, lastBBoxElem );
1600 lastBBoxElem = layerElem.lastChildElement( version ==
"1.1.1"_L1 ?
"LatLonBoundingBox" :
"EX_GeographicBoundingBox" );
1601 if ( !lastBBoxElem.isNull() )
1603 layerElem.insertAfter( bBoxElement, lastBBoxElem );
1607 layerElem.appendChild( bBoxElement );
1613 void appendDrawingOrder( QDomDocument &doc, QDomElement &parentElem, QgsServerInterface *serverIface,
const QgsProject *project )
1615#ifdef HAVE_SERVER_PYTHON_PLUGINS
1618 ( void ) serverIface;
1623 QStringList layerList;
1625 QHash<const QgsMapLayer *, QStringList> acceptableLayersAndRequestNames;
1628 const QgsLayerTree *projectLayerTreeRoot = project->
layerTreeRoot();
1629 QList<QgsMapLayer *> projectLayerOrder = projectLayerTreeRoot->
layerOrder();
1630 for (
int i = 0; i < projectLayerOrder.size(); ++i )
1632 QgsMapLayer *l = projectLayerOrder.at( i );
1634 if ( restrictedLayers.contains( l->
name() ) )
1640 if ( !acceptableLayersAndRequestNames.contains( l ) )
1644#ifdef HAVE_SERVER_PYTHON_PLUGINS
1650 QString wmsName = l->
name();
1660 layerList << wmsName;
1663 if ( !layerList.isEmpty() )
1665 QStringList reversedList;
1666 reversedList.reserve( layerList.size() );
1667 for (
int i = layerList.size() - 1; i >= 0; --i )
1668 reversedList << layerList[i];
1670 QDomElement layerDrawingOrderElem = doc.createElement( u
"LayerDrawingOrder"_s );
1671 QDomText drawingOrderText = doc.createTextNode( reversedList.join(
',' ) );
1672 layerDrawingOrderElem.appendChild( drawingOrderText );
1673 parentElem.appendChild( layerDrawingOrderElem );
1677 void appendLayerProjectSettings( QDomDocument &doc, QDomElement &layerElem, QgsMapLayer *currentLayer )
1679 if ( !currentLayer )
1685 QDomElement treeNameElem = doc.createElement( u
"TreeName"_s );
1686 QDomText treeNameText = doc.createTextNode( currentLayer->
name() );
1687 treeNameElem.appendChild( treeNameText );
1688 layerElem.appendChild( treeNameElem );
1690 switch ( currentLayer->
type() )
1694 QgsVectorLayer *vLayer =
static_cast<QgsVectorLayer *
>( currentLayer );
1696 int displayFieldIdx = -1;
1697 QString displayField = u
"maptip"_s;
1699 if ( exp.isField() )
1701 displayField =
static_cast<const QgsExpressionNodeColumnRef *
>( exp.rootNode() )->name();
1706 QDomElement attributesElem = doc.createElement( u
"Attributes"_s );
1707 const QgsFields layerFields = vLayer->
fields();
1708 for (
int idx = 0; idx < layerFields.
count(); ++idx )
1710 QgsField field = layerFields.
at( idx );
1716 if ( idx == displayFieldIdx )
1720 QDomElement attributeElem = doc.createElement( u
"Attribute"_s );
1721 attributeElem.setAttribute( u
"name"_s, field.
name() );
1722 attributeElem.setAttribute( u
"type"_s, QVariant::typeToName( field.
type() ) );
1723 attributeElem.setAttribute( u
"typeName"_s, field.
typeName() );
1724 QString alias = field.
alias();
1725 if ( !alias.isEmpty() )
1727 attributeElem.setAttribute( u
"alias"_s, alias );
1732 attributeElem.setAttribute( u
"comment"_s, field.
comment() );
1733 attributeElem.setAttribute( u
"length"_s, field.
length() );
1734 attributeElem.setAttribute( u
"precision"_s, field.
precision() );
1735 attributesElem.appendChild( attributeElem );
1739 layerElem.setAttribute( u
"displayField"_s, displayField );
1743 if ( pkAttributes.size() > 0 )
1745 QDomElement pkElem = doc.createElement( u
"PrimaryKey"_s );
1746 QgsAttributeList::const_iterator pkIt = pkAttributes.constBegin();
1747 for ( ; pkIt != pkAttributes.constEnd(); ++pkIt )
1749 QDomElement pkAttributeElem = doc.createElement( u
"PrimaryKeyAttribute"_s );
1750 QDomText pkAttName = doc.createTextNode( layerFields.
at( *pkIt ).
name() );
1751 pkAttributeElem.appendChild( pkAttName );
1752 pkElem.appendChild( pkAttributeElem );
1754 layerElem.appendChild( pkElem );
1761 layerElem.setAttribute( u
"opacity"_s, QString::number( vLayer->
opacity() ) );
1763 layerElem.appendChild( attributesElem );
1769 const QgsDataProvider *provider = currentLayer->
dataProvider();
1770 if ( provider && provider->
name() ==
"wms" )
1773 QVariant wmsBackgroundLayer = currentLayer->
customProperty( u
"WMSBackgroundLayer"_s,
false );
1774 QDomElement wmsBackgroundLayerElem = doc.createElement(
"WMSBackgroundLayer" );
1775 QDomText wmsBackgroundLayerText = doc.createTextNode( wmsBackgroundLayer.toBool() ? u
"1"_s : u
"0"_s );
1776 wmsBackgroundLayerElem.appendChild( wmsBackgroundLayerText );
1777 layerElem.appendChild( wmsBackgroundLayerElem );
1780 QVariant wmsPublishDataSourceUrl = currentLayer->
customProperty( u
"WMSPublishDataSourceUrl"_s,
false );
1781 if ( wmsPublishDataSourceUrl.toBool() )
1783 bool tiled = qobject_cast<const QgsRasterDataProvider *>( provider ) ? !qobject_cast<const QgsRasterDataProvider *>( provider )->nativeResolutions().isEmpty() :
false;
1785 QDomElement dataSourceElem = doc.createElement( tiled ? u
"WMTSDataSource"_s : u
"WMSDataSource"_s );
1786 QDomText dataSourceUri = doc.createTextNode( provider->
dataSourceUri() );
1787 dataSourceElem.appendChild( dataSourceUri );
1788 layerElem.appendChild( dataSourceElem );
1792 QVariant wmsPrintLayer = currentLayer->
customProperty( u
"WMSPrintLayer"_s );
1793 if ( wmsPrintLayer.isValid() )
1795 QDomElement wmsPrintLayerElem = doc.createElement(
"WMSPrintLayer" );
1796 QDomText wmsPrintLayerText = doc.createTextNode( wmsPrintLayer.toString() );
1797 wmsPrintLayerElem.appendChild( wmsPrintLayerText );
1798 layerElem.appendChild( wmsPrintLayerElem );
1802 QgsRasterLayer *rl =
static_cast<QgsRasterLayer *
>( currentLayer );
1803 QgsRasterRenderer *rasterRenderer = rl->
renderer();
1804 if ( rasterRenderer )
1806 layerElem.setAttribute( u
"opacity"_s, QString::number( rasterRenderer->
opacity() ) );
1822 void addKeywordListElement(
const QgsProject *project, QDomDocument &doc, QDomElement &parent )
1826 QDomElement keywordsElem = doc.createElement( u
"KeywordList"_s );
1828 QDomElement keywordElem = doc.createElement( u
"Keyword"_s );
1829 keywordElem.setAttribute( u
"vocabulary"_s, u
"ISO"_s );
1830 QDomText keywordText = doc.createTextNode( u
"infoMapAccessService"_s );
1831 keywordElem.appendChild( keywordText );
1832 keywordsElem.appendChild( keywordElem );
1833 parent.appendChild( keywordsElem );
1835 for (
const QString &keyword : std::as_const( keywords ) )
1837 if ( !keyword.isEmpty() )
1839 keywordElem = doc.createElement( u
"Keyword"_s );
1840 keywordText = doc.createTextNode( keyword );
1841 keywordElem.appendChild( keywordText );
1844 keywordElem.setAttribute( u
"vocabulary"_s, u
"SIA_Geo405"_s );
1846 keywordsElem.appendChild( keywordElem );
1849 parent.appendChild( keywordsElem );
1853 bool hasQueryableLayers(
const QStringList &layerIds,
const QMap<QString, QgsWmsLayerInfos> &wmsLayerInfos )
1855 for (
const QString &
id : std::as_const( layerIds ) )
1857 if ( !wmsLayerInfos.contains(
id ) )
1861 if ( wmsLayerInfos[
id].queryable )
1874 for (
const QString &
id : std::as_const( layerIds ) )
1876 if ( !wmsLayerInfos.contains(
id ) )
1881 QgsRectangle rect = wmsLayerInfos[id].wgs84BoundingRect;
1906 QMap<QString, QgsRectangle>
combineCrsExtents(
const QStringList &layerIds,
const QMap<QString, QgsWmsLayerInfos> &wmsLayerInfos )
1908 QMap<QString, QgsRectangle> combined;
1910 for (
const QString &
id : std::as_const( layerIds ) )
1912 if ( !wmsLayerInfos.contains(
id ) )
1918 const auto keys = layerInfos.
crsExtents.keys();
1919 for (
const QString &crs : std::as_const( keys ) )
1932 if ( !combined.contains( crs ) )
1934 combined[crs] = rect;
1938 combined[crs].combineExtentWith( rect );
@ Opaque
Group can be requested, children cannot (appears like a single layer).
@ Millimeters
Millimeters.
@ Warning
Warning message.
@ Group
Composite group layer. Added in QGIS 3.24.
@ Plugin
Plugin based layer.
@ TiledScene
Tiled scene layer. Added in QGIS 3.34.
@ Annotation
Contains freeform, georeferenced annotations. Added in QGIS 3.16.
@ VectorTile
Vector tile layer. Added in QGIS 3.14.
@ Mesh
Mesh layer. Added in QGIS 3.2.
@ PointCloud
Point cloud layer. Added in QGIS 3.18.
static QString geographicCrsAuthId()
Geographic coordinate system auth:id string for a default geographic CRS (EPSG:4326).
@ HideFromWms
Field is not available if layer is served as WMS from QGIS server.
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 fillCacheKey(QStringList &cacheKey) const
Fill the capabilities caching key.
A cache for capabilities xml documents (by configuration file path).
const QDomDocument * searchCapabilitiesDocument(const QString &configFilePath, const QString &key)
Returns cached capabilities document (or 0 if document for configuration file not in cache).
void insertCapabilitiesDocument(const QString &configFilePath, const QString &key, const QDomDocument *doc)
Inserts new capabilities document (creates a copy of the document, does not take ownership).
Represents a coordinate reference system (CRS).
static QgsCoordinateReferenceSystem fromOgcWmsCrs(const QString &ogcCrs)
Creates a CRS from a given OGC WMS-format Coordinate Reference System string.
bool isValid() const
Returns whether this CRS is correctly initialized and usable.
bool isEarthCrs() const
Returns true if the CRS is associated with the Earth.
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.
virtual QString name() const =0
Returns a provider name.
virtual QString dataSourceUri(bool expandAuthConfig=false) const
Gets the data source specification.
QString typeName() const
Gets the field type.
Qgis::FieldConfigurationFlags configurationFlags
Q_INVOKABLE int indexOf(const QString &fieldName) const
Gets the field index from the field name.
QgsField at(int i) const
Returns the field at particular index (must be in range 0..N-1).
Q_INVOKABLE int lookupField(const QString &fieldName) const
Looks up field's index from the field name.
Layer tree group node serves as a container for layers and further groups.
QString name() const override
Returns the group's name.
QStringList findLayerIds() const
Find layer IDs used in all layer nodes.
QgsMapLayerServerProperties * serverProperties()
Returns QGIS Server Properties for the layer tree group.
bool isMutuallyExclusive() const
Returns whether the group is mutually exclusive (only one child can be checked at a time).
bool hasWmsTimeDimension() const
Returns whether the WMS time dimension should be computed for this group or not.
Qgis::WmsGroupRequestMode wmsGroupRequestMode() const
Returns the request mode of the group.
QString layerId() const
Returns the ID for the map layer associated with this node.
QgsMapLayer * layer() const
Returns the map layer associated with this node.
@ NodeGroup
Container of other groups and layers.
bool isVisible() const
Returns whether a node is really visible (ie checked and all its ancestors checked as well).
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 isExpanded() const
Returns whether the node should be shown as expanded or collapsed in GUI.
bool itemVisibilityChecked() const
Returns whether a node is checked (independently of its ancestors or children).
Namespace with helper functions for layer tree operations.
QList< QgsMapLayer * > layerOrder() const
The order in which layers will be rendered on the canvas.
Used to render QgsLayout as an atlas, by iterating over the features from an associated vector layer.
bool enabled() const
Returns whether the atlas generation is enabled.
QgsVectorLayer * coverageLayer() const
Returns the coverage layer used for the atlas features.
A layout multiframe subclass for HTML content.
A layout item subclass for text labels.
Layout graphical items for displaying a map.
QString displayName() const override
Gets item display name.
QgsLayoutSize sizeWithUnits() const
Returns the item's current size, including units.
QString id() const
Returns the item's ID name.
QList< QgsPrintLayout * > printLayouts() const
Returns a list of all print layouts contained in the manager.
Provides a method of storing measurements for use in QGIS layouts using a variety of different measur...
double length() const
Returns the length of the measurement.
int frameCount() const
Returns the number of frames associated with this multiframe.
QgsLayoutFrame * frame(int index) const
Returns the child frame at a specified index from the multiframe.
int pageCount() const
Returns the number of pages in the collection.
QgsLayoutItemPage * page(int pageNumber)
Returns a specific page (by pageNumber) from the collection.
Provides a method of storing sizes, consisting of a width and height, for use in QGIS layouts.
double height() const
Returns the height of the size.
double width() const
Returns the width of the size.
QgsLayoutPageCollection * pageCollection()
Returns a pointer to the layout's page collection, which stores and manages page items in the layout.
void layoutItems(QList< T * > &itemList) const
Returns a list of layout items of a specific type.
void layoutObjects(QList< T * > &objectList) const
Returns a list of layout objects (items and multiframes) of a specific type.
QgsLayoutMeasurement convertFromLayoutUnits(double length, Qgis::LayoutUnit unit) const
Converts a length measurement from the layout's native units to a specified target unit.
Manages QGIS Server properties for a map layer.
QString attribution() const
Returns the attribution of the layer used by QGIS Server in GetCapabilities request.
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 legendUrlFormat() const
Returns the format for a URL based layer legend.
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 attributionUrl() const
Returns the attribution URL of the layer used by QGIS Server in GetCapabilities request.
QString legendUrl() const
Returns the URL for the layer's legend.
QString abstract() const
Returns the abstract of the layerused by QGIS Server in GetCapabilities request.
virtual QgsDateTimeRange calculateTemporalExtent(QgsMapLayer *layer) const
Attempts to calculate the overall temporal extent for the specified layer, using the settings defined...
virtual QList< QgsDateTimeRange > allTemporalRanges(QgsMapLayer *layer) const
Attempts to calculate the overall list of all temporal extents which are contained in the specified l...
Base class for all map layer types.
Q_INVOKABLE QVariant customProperty(const QString &value, const QVariant &defaultValue=QVariant()) const
Read a custom property from layer.
QgsCoordinateReferenceSystem crs
QgsMapLayerServerProperties * serverProperties()
Returns QGIS Server Properties for the map layer.
virtual QgsMapLayerTemporalProperties * temporalProperties()
Returns the layer's temporal properties.
virtual Q_INVOKABLE QgsDataProvider * dataProvider()
Returns the layer's data provider, it may be nullptr.
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::MessageLevel::Warning, bool notifyUser=true, const char *file=__builtin_FILE(), const char *function=__builtin_FUNCTION(), int line=__builtin_LINE(), Qgis::StringFormat format=Qgis::StringFormat::PlainText)
Adds a message to the log instance (and creates it if necessary).
Print layout, a QgsLayout subclass for static or atlas-based layouts.
QgsLayoutAtlas * atlas()
Returns the print layout's atlas.
Encapsulates a QGIS project, including sets of map layers and their styles, layouts,...
Q_INVOKABLE QgsMapLayer * mapLayer(const QString &layerId) const
Retrieve a pointer to a registered layer by layer ID.
QgsCoordinateTransformContext transformContext
QgsLayerTree * layerTreeRoot() const
Returns pointer to the root (invisible) node of the project's layer tree.
const QgsLayoutManager * layoutManager() const
Returns the project's layout manager, which manages print layouts, atlases and reports within the pro...
QgsCoordinateReferenceSystem crs
QgsRasterRenderer * renderer() const
Returns the raster's renderer.
double opacity() const
Returns the opacity for the renderer, where opacity is a value between 0 (totally transparent) and 1....
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.
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 QString configFilePath()=0
Returns the configuration file path.
virtual QgsAccessControl * accessControls() const =0
Gets the registered access control filters.
virtual QgsServerSettings * serverSettings()=0
Returns the server settings.
virtual QgsCapabilitiesCache * capabilitiesCache()=0
Gets pointer to the capabiblities cache.
QString service() const
Returns SERVICE parameter as a string or an empty string if not defined.
static QString wmsRootName(const QgsProject &project)
Returns the WMS root layer name defined in a QGIS project.
static bool wmsInfoFormatSia2045(const QgsProject &project)
Returns if the info format is SIA20145.
static bool wmsSkipNameForGroup(const QgsProject &project)
Returns if name attribute should be skipped for groups in WMS capabilities document.
static QString wmsInspireMetadataUrl(const QgsProject &project)
Returns the Inspire metadata URL.
static double ceilWithPrecision(double number, int places)
Returns a double greater than number to the specified number of places.
static QStringList wmsRestrictedComposers(const QgsProject &project)
Returns the restricted composer list.
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 QString owsServiceAccessConstraints(const QgsProject &project)
Returns the owsService access constraints defined in project.
static QStringList wfsLayerIds(const QgsProject &project)
Returns the Layer ids list defined in a QGIS project as published in WFS.
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 serviceUrl(const QString &service, const QgsServerRequest &request, const QgsServerSettings &settings)
Returns the service url defined in the environment variable or with HTTP header.
static QString wmsInspireTemporalReference(const QgsProject &project)
Returns the Inspire temporal reference.
static QStringList wmsOutputCrsList(const QgsProject &project)
Returns the WMS output CRS list.
static QString wmsInspireMetadataDate(const QgsProject &project)
Returns the Inspire metadata date.
static QString owsServiceContactOrganization(const QgsProject &project)
Returns the owsService contact organization defined in project.
static QStringList wmsRestrictedLayers(const QgsProject &project)
Returns the restricted layer name list.
static QString wmsInspireLanguage(const QgsProject &project)
Returns the Inspire language.
static QString wmsInspireMetadataUrlType(const QgsProject &project)
Returns the Inspire metadata URL type.
static bool wmsInspireActivate(const QgsProject &project)
Returns if Inspire is activated.
static int wmsMaxWidth(const QgsProject &project)
Returns the maximum width for WMS images defined in a QGIS 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 double floorWithPrecision(double number, int places)
Returns a double less than number to the specified number of places.
static int wmsMaxHeight(const QgsProject &project)
Returns the maximum height for WMS images defined in a QGIS project.
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.
QgsServerParameters serverParameters() const
Returns parameters.
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 a single header value replacing any existing value(s) for the same key.
Provides a way to retrieve settings by prioritizing according to environment variables,...
bool getPrintDisabled() const
Returns true if WMS GetPrint request is disabled and the project's reading flag QgsProject::ReadFlag:...
const QList< QgsServerWmsDimensionProperties::WmsDimensionInfo > wmsDimensions() const
Returns the QGIS Server WMS Dimension list.
bool isActive() const
Returns true if the temporal property is active.
T begin() const
Returns the beginning of the range.
T end() const
Returns the upper bound of the range.
Represents a vector layer which manages a vector based dataset.
Q_INVOKABLE QString attributeDisplayName(int index) const
Convenience function that returns the attribute alias if defined or the field name else.
Q_INVOKABLE Qgis::WkbType wkbType() const final
Returns the WKBType or WKBUnknown in case of error.
QString displayExpression
QgsEditorWidgetSetup editorWidgetSetup(int index) const
Returns the editor widget setup for the field at the specified index.
QgsAttributeList primaryKeyAttributes() const
Returns the list of attributes which make up the layer's primary keys.
Q_INVOKABLE QSet< QVariant > uniqueValues(int fieldIndex, int limit=-1) const final
Calculates a list of unique values contained within an attribute in the layer.
static Q_INVOKABLE QString displayString(Qgis::WkbType type)
Returns a non-translated display string type for a WKB type, e.g., the geometry name used in WKT geom...
QString legendUrlFormat
WMS layer legend URL format.
QStringList styles
WMS layer styles.
QString legendUrl
WMS layer legend URL.
static QgsRectangle transformExtent(const QgsRectangle &extent, const QgsCoordinateReferenceSystem &source, const QgsCoordinateReferenceSystem &destination, const QgsCoordinateTransformContext &context, const bool &ballparkTransformsAreAppropriate=false)
Returns a transformed extent.
double maxScale
WMS layer maximum scale (if negative, no maximum scale is defined).
QMap< QString, QgsRectangle > crsExtents
WMS layer CRS extents (can be empty).
static QMap< QString, QgsRectangle > transformExtentToCrsList(const QgsRectangle &extent, const QgsCoordinateReferenceSystem &source, const QList< QgsCoordinateReferenceSystem > &destinations, const QgsCoordinateTransformContext &context)
Returns a map with CRS authid as key and the transformed extent as value.
QString name
WMS layer name.
static QMap< QString, QgsWmsLayerInfos > buildWmsLayerInfos(QgsServerInterface *serverIface, const QgsProject *project, const QList< QgsCoordinateReferenceSystem > &outputCrsList)
Returns the WMS layers definition to build WMS capabilities.
bool hasScaleBasedVisibility
WMS layer has scale based visibility.
double minScale
WMS layer minimum scale (if negative, no maximum scale is defined).
bool queryable
WMS layer is queryable.
QgsRectangle wgs84BoundingRect
WMS layer WGS84 bounding rectangle (can be empty).
QString version() const override
Returns VERSION parameter as a string or an empty string if not defined.
Defines request interfaces passed to WMS service.
const QgsWmsParameters & wmsParameters() const
Returns the parameters interpreted for the WMS service.
Median cut implementation.
QDomElement getWFSLayersElement(QDomDocument &doc, const QgsProject *project)
Create WFSLayers element for get capabilities document.
void writeGetCapabilities(QgsServerInterface *serverIface, const QgsProject *project, const QgsWmsRequest &request, QgsServerResponse &response, bool projectSettings)
Output GetCapabilities response.
void collectAcceptableLayersAndRequestNames(QHash< const QgsMapLayer *, QStringList > &acceptableLayersAndRequestNames, const QgsProject &project, const QStringList &requestedLayerNames)
Collects the acceptableLayersAndRequestNames, a hash of all the layers that can be rendered and for e...
QDomElement getLayersAndStylesCapabilitiesElement(QDomDocument &doc, QgsServerInterface *serverIface, const QgsProject *project, const QgsWmsRequest &request, bool projectSettings)
Create element for get capabilities document.
QDomElement getInspireCapabilitiesElement(QDomDocument &doc, const QgsProject *project)
Create InspireCapabilities element for get capabilities document.
void handleLayersFromTreeGroup(QDomDocument &doc, QDomElement &parentLayer, QgsServerInterface *serverIface, const QgsProject *project, const QgsWmsRequest &request, const QgsLayerTreeGroup *layerTreeGroup, const QMap< QString, QgsWmsLayerInfos > &wmsLayerInfos, bool projectSettings, QList< QgsDateTimeRange > &parentDateRanges)
QDomElement getComposerTemplatesElement(QDomDocument &doc, const QgsProject *project)
Create ComposerTemplates element for get capabilities document.
QDomElement getServiceElement(QDomDocument &doc, const QgsProject *project, const QgsWmsRequest &request, const QgsServerSettings *serverSettings)
Create Service element for get capabilities document.
QDomElement getCapabilityElement(QDomDocument &doc, const QgsProject *project, const QgsWmsRequest &request, bool projectSettings, QgsServerInterface *serverIface)
Create Capability element for get capabilities document.
QDomDocument getCapabilities(QgsServerInterface *serverIface, const QgsProject *project, const QgsWmsRequest &request, bool projectSettings)
Creates the WMS GetCapabilities XML document.
bool hasQueryableLayers(const QStringList &layerIds, const QMap< QString, QgsWmsLayerInfos > &wmsLayerInfos)
Returns true if at least one layer from the layers ids is queryable.
QgsRectangle combineWgs84BoundingRect(const QStringList &layerIds, const QMap< QString, QgsWmsLayerInfos > &wmsLayerInfos)
Returns the combination of the WGS84 bounding rectangle of the layers from the list of layers ids.
QMap< QString, QgsRectangle > combineCrsExtents(const QStringList &layerIds, const QMap< QString, QgsWmsLayerInfos > &wmsLayerInfos)
Returns the combinations of the extent CRSes of the layers from the list of layers ids.
QUrl serviceUrl(const QgsServerRequest &request, const QgsProject *project, const QgsServerSettings &settings)
Returns WMS service URL.
QString qgsDoubleToString(double a, int precision=17)
Returns a string representation of a double.
const QString cacheKey(const QString &pathIn)
QList< int > QgsAttributeList
QgsTemporalRange< QDateTime > QgsDateTimeRange
QgsRange which stores a range of date times.