45using namespace Qt::StringLiterals;
52 void appendLayerProjectSettings( QDomDocument &doc, QDomElement &layerElem, QgsMapLayer *currentLayer );
54 void appendDrawingOrder( QDomDocument &doc, QDomElement &parentElem, QgsServerInterface *serverIface,
const QgsProject *project );
56 void appendLayerWgs84BoundingRect( QDomDocument &doc, QDomElement &layerElement,
const QgsRectangle &wgs84BoundingRect );
58 void appendLayerCrsExtents( QDomDocument &doc, QDomElement &layerElement,
const QMap<QString, QgsRectangle> &crsExtents );
60 void appendCrsElementToLayer( QDomDocument &doc, QDomElement &layerElement,
const QDomElement &precedingElement,
const QString &crsText );
62 void appendCrsElementsToLayer( QDomDocument &doc, QDomElement &layerElement,
const QStringList &crsList,
const QStringList &constrainedCrsList,
bool hasEarthCrs =
true );
64 void appendLayerStyles( QDomDocument &doc, QDomElement &layerElem,
const QgsWmsLayerInfos &layerInfos,
const QgsProject *project,
const QgsWmsRequest &request,
const QgsServerSettings *settings );
66 void appendLayersFromTreeGroup(
68 QDomElement &parentLayer,
69 QgsServerInterface *serverIface,
70 const QgsProject *project,
72 const QgsLayerTreeGroup *layerTreeGroup,
73 const QMap<QString, QgsWmsLayerInfos> &wmsLayerInfos,
75 QList<QgsDateTimeRange> &parentDateRanges
78 void addKeywordListElement(
const QgsProject *project, QDomDocument &doc, QDomElement &parent );
83#ifdef HAVE_SERVER_PYTHON_PLUGINS
88 const QDomDocument *capabilitiesDocument =
nullptr;
93 QStringList cacheKeyList;
94 cacheKeyList << ( projectSettings ? u
"projectSettings"_s : request.
wmsParameters().version() );
98#ifdef HAVE_SERVER_PYTHON_PLUGINS
102 QString
cacheKey = cacheKeyList.join(
'-' );
104#ifdef HAVE_SERVER_PYTHON_PLUGINS
106 if ( cacheManager && cacheManager->
getCachedDocument( &doc, project, request, accessControl ) )
108 capabilitiesDocument = &doc;
111 if ( !capabilitiesDocument && cache )
116 if ( !capabilitiesDocument )
120 doc =
getCapabilities( serverIface, project, request, projectSettings );
122#ifdef HAVE_SERVER_PYTHON_PLUGINS
123 if ( cacheManager && cacheManager->
setCachedDocument( &doc, project, request, accessControl ) )
125 capabilitiesDocument = &doc;
130 if ( !capabilitiesDocument )
135 if ( !capabilitiesDocument )
137 capabilitiesDocument = &doc;
149 response.
setHeader( u
"Content-Type"_s, u
"text/xml; charset=utf-8"_s );
150 response.
write( capabilitiesDocument->toByteArray() );
156 QDomElement wmsCapabilitiesElement;
162 QString hrefString = href.toString();
163 hrefString.append( href.hasQuery() ?
"&" :
"?" );
166 QDomProcessingInstruction xmlDeclaration = doc.createProcessingInstruction( u
"xml"_s, u
"version=\"1.0\" encoding=\"utf-8\""_s );
169 std::function<void( QDomElement &,
const QString & )> appendFormat = [&doc]( QDomElement &elem,
const QString &format ) {
170 QDomElement formatElem = doc.createElement( u
"Format"_s );
171 formatElem.appendChild( doc.createTextNode( format ) );
172 elem.appendChild( formatElem );
178 u
"WMT_MS_Capabilities SYSTEM 'http://schemas.opengis.net/wms/1.1.1/WMS_MS_Capabilities.dtd'"_s
180 doc.appendChild( xmlDeclaration );
181 wmsCapabilitiesElement = doc.createElement( u
"WMT_MS_Capabilities"_s );
185 doc.appendChild( xmlDeclaration );
186 wmsCapabilitiesElement = doc.createElement( u
"WMS_Capabilities"_s );
187 wmsCapabilitiesElement.setAttribute( u
"xmlns"_s, u
"http://www.opengis.net/wms"_s );
188 wmsCapabilitiesElement.setAttribute( u
"xmlns:sld"_s, u
"http://www.opengis.net/sld"_s );
189 wmsCapabilitiesElement.setAttribute( u
"xmlns:qgs"_s, u
"http://www.qgis.org/wms"_s );
190 wmsCapabilitiesElement.setAttribute( u
"xmlns:xsi"_s, u
"http://www.w3.org/2001/XMLSchema-instance"_s );
191 QString schemaLocation = u
"http://www.opengis.net/wms"_s;
192 schemaLocation +=
" http://schemas.opengis.net/wms/1.3.0/capabilities_1_3_0.xsd"_L1;
193 schemaLocation +=
" http://www.opengis.net/sld"_L1;
194 schemaLocation +=
" http://schemas.opengis.net/sld/1.1.0/sld_capabilities.xsd"_L1;
198 wmsCapabilitiesElement.setAttribute( u
"xmlns:inspire_common"_s, u
"http://inspire.ec.europa.eu/schemas/common/1.0"_s );
199 wmsCapabilitiesElement.setAttribute( u
"xmlns:inspire_vs"_s, u
"http://inspire.ec.europa.eu/schemas/inspire_vs/1.0"_s );
200 schemaLocation +=
" http://inspire.ec.europa.eu/schemas/inspire_vs/1.0"_L1;
201 schemaLocation +=
" http://inspire.ec.europa.eu/schemas/inspire_vs/1.0/inspire_vs.xsd"_L1;
204 schemaLocation +=
" http://www.qgis.org/wms"_L1;
205 schemaLocation +=
" " + hrefString +
"SERVICE=WMS&REQUEST=GetSchemaExtension";
207 wmsCapabilitiesElement.setAttribute( u
"xsi:schemaLocation"_s, schemaLocation );
210 doc.appendChild( wmsCapabilitiesElement );
216 QDomElement capabilityElement =
getCapabilityElement( doc, project, request, projectSettings, serverIface );
217 wmsCapabilitiesElement.appendChild( capabilityElement );
219 if ( projectSettings )
230 if ( projectSettings )
232 appendDrawingOrder( doc, capabilityElement, serverIface, project );
241 QDomElement serviceElem = doc.createElement( u
"Service"_s );
244 QDomElement nameElem = doc.createElement( u
"Name"_s );
245 QDomText nameText = doc.createTextNode( u
"WMS"_s );
246 nameElem.appendChild( nameText );
247 serviceElem.appendChild( nameElem );
250 QDomElement titleElem = doc.createElement( u
"Title"_s );
252 titleElem.appendChild( titleText );
253 serviceElem.appendChild( titleElem );
256 if ( !abstract.isEmpty() )
258 QDomElement abstractElem = doc.createElement( u
"Abstract"_s );
259 QDomText abstractText = doc.createCDATASection( abstract );
260 abstractElem.appendChild( abstractText );
261 serviceElem.appendChild( abstractElem );
264 addKeywordListElement( project, doc, serviceElem );
267 if ( onlineResource.isEmpty() )
269 onlineResource =
serviceUrl( request, project, *serverSettings ).toString();
271 QDomElement onlineResourceElem = doc.createElement( u
"OnlineResource"_s );
272 onlineResourceElem.setAttribute( u
"xmlns:xlink"_s, u
"http://www.w3.org/1999/xlink"_s );
273 onlineResourceElem.setAttribute( u
"xlink:type"_s, u
"simple"_s );
274 onlineResourceElem.setAttribute( u
"xlink:href"_s, onlineResource );
275 serviceElem.appendChild( onlineResourceElem );
282 if ( !contactPerson.isEmpty() || !contactOrganization.isEmpty() || !contactPosition.isEmpty() || !contactMail.isEmpty() || !contactPhone.isEmpty() )
285 QDomElement contactInfoElem = doc.createElement( u
"ContactInformation"_s );
288 if ( !contactPerson.isEmpty() || !contactOrganization.isEmpty() )
290 QDomElement contactPersonPrimaryElem = doc.createElement( u
"ContactPersonPrimary"_s );
292 QDomText contactPersonText;
293 if ( !contactPerson.isEmpty() )
295 contactPersonText = doc.createTextNode( contactPerson );
299 contactPersonText = doc.createTextNode( u
"unknown"_s );
301 QDomElement contactPersonElem = doc.createElement( u
"ContactPerson"_s );
302 contactPersonElem.appendChild( contactPersonText );
303 contactPersonPrimaryElem.appendChild( contactPersonElem );
305 QDomText contactOrganizationText;
306 if ( !contactOrganization.isEmpty() )
308 contactOrganizationText = doc.createTextNode( contactOrganization );
312 contactOrganizationText = doc.createTextNode( u
"unknown"_s );
314 QDomElement contactOrganizationElem = doc.createElement( u
"ContactOrganization"_s );
315 contactOrganizationElem.appendChild( contactOrganizationText );
316 contactPersonPrimaryElem.appendChild( contactOrganizationElem );
318 contactInfoElem.appendChild( contactPersonPrimaryElem );
321 if ( !contactPosition.isEmpty() )
323 QDomElement contactPositionElem = doc.createElement( u
"ContactPosition"_s );
324 QDomText contactPositionText = doc.createTextNode( contactPosition );
325 contactPositionElem.appendChild( contactPositionText );
326 contactInfoElem.appendChild( contactPositionElem );
329 if ( !contactPhone.isEmpty() )
331 QDomElement phoneElem = doc.createElement( u
"ContactVoiceTelephone"_s );
332 QDomText phoneText = doc.createTextNode( contactPhone );
333 phoneElem.appendChild( phoneText );
334 contactInfoElem.appendChild( phoneElem );
337 if ( !contactMail.isEmpty() )
339 QDomElement mailElem = doc.createElement( u
"ContactElectronicMailAddress"_s );
340 QDomText mailText = doc.createTextNode( contactMail );
341 mailElem.appendChild( mailText );
342 contactInfoElem.appendChild( mailElem );
345 serviceElem.appendChild( contactInfoElem );
348 QDomElement feesElem = doc.createElement( u
"Fees"_s );
349 QDomText feesText = doc.createTextNode( u
"None"_s );
351 if ( !fees.isEmpty() )
353 feesText = doc.createTextNode( fees );
355 feesElem.appendChild( feesText );
356 serviceElem.appendChild( feesElem );
358 QDomElement accessConstraintsElem = doc.createElement( u
"AccessConstraints"_s );
359 QDomText accessConstraintsText = doc.createTextNode( u
"None"_s );
361 if ( !accessConstraints.isEmpty() )
363 accessConstraintsText = doc.createTextNode( accessConstraints );
365 accessConstraintsElem.appendChild( accessConstraintsText );
366 serviceElem.appendChild( accessConstraintsElem );
373 QDomElement maxWidthElem = doc.createElement( u
"MaxWidth"_s );
374 QDomText maxWidthText = doc.createTextNode( QString::number( maxWidth ) );
375 maxWidthElem.appendChild( maxWidthText );
376 serviceElem.appendChild( maxWidthElem );
382 QDomElement maxHeightElem = doc.createElement( u
"MaxHeight"_s );
383 QDomText maxHeightText = doc.createTextNode( QString::number( maxHeight ) );
384 maxHeightElem.appendChild( maxHeightText );
385 serviceElem.appendChild( maxHeightElem );
400 QString hrefString = href.toString();
401 hrefString.append( href.hasQuery() ?
"&" :
"?" );
403 QDomElement capabilityElem = doc.createElement( u
"Capability"_s );
406 QDomElement requestElem = doc.createElement( u
"Request"_s );
407 capabilityElem.appendChild( requestElem );
409 QDomElement dcpTypeElem = doc.createElement( u
"DCPType"_s );
410 QDomElement httpElem = doc.createElement( u
"HTTP"_s );
411 dcpTypeElem.appendChild( httpElem );
414 std::function<void( QDomElement &,
const QString & )> appendFormat = [&doc]( QDomElement &elem,
const QString &format ) {
415 QDomElement formatElem = doc.createElement( u
"Format"_s );
416 formatElem.appendChild( doc.createTextNode( format ) );
417 elem.appendChild( formatElem );
423 elem = doc.createElement( u
"GetCapabilities"_s );
424 appendFormat( elem, ( version ==
"1.1.1"_L1 ?
"application/vnd.ogc.wms_xml" :
"text/xml" ) );
425 elem.appendChild( dcpTypeElem );
426 requestElem.appendChild( elem );
429 QDomElement getElem = doc.createElement( u
"Get"_s );
430 httpElem.appendChild( getElem );
431 QDomElement olResourceElem = doc.createElement( u
"OnlineResource"_s );
432 olResourceElem.setAttribute( u
"xmlns:xlink"_s, u
"http://www.w3.org/1999/xlink"_s );
433 olResourceElem.setAttribute( u
"xlink:type"_s, u
"simple"_s );
434 olResourceElem.setAttribute( u
"xlink:href"_s, hrefString );
435 getElem.appendChild( olResourceElem );
438 elem = doc.createElement( u
"GetMap"_s );
439 appendFormat( elem, u
"image/png"_s );
440 appendFormat( elem, u
"image/png; mode=16bit"_s );
441 appendFormat( elem, u
"image/png; mode=8bit"_s );
442 appendFormat( elem, u
"image/png; mode=1bit"_s );
443 appendFormat( elem, u
"image/jpeg"_s );
444 appendFormat( elem, u
"application/dxf"_s );
445 appendFormat( elem, u
"application/pdf"_s );
446 elem.appendChild( dcpTypeElem.cloneNode().toElement() );
447 requestElem.appendChild( elem );
450 elem = doc.createElement( u
"GetFeatureInfo"_s );
451 appendFormat( elem, u
"text/plain"_s );
452 appendFormat( elem, u
"text/html"_s );
453 appendFormat( elem, u
"text/xml"_s );
454 appendFormat( elem, u
"application/vnd.ogc.gml"_s );
455 appendFormat( elem, u
"application/vnd.ogc.gml/3.1.1"_s );
456 appendFormat( elem, u
"application/json"_s );
457 appendFormat( elem, u
"application/geo+json"_s );
458 elem.appendChild( dcpTypeElem.cloneNode().toElement() );
459 requestElem.appendChild( elem );
462 elem = doc.createElement( ( version ==
"1.1.1"_L1 ?
"GetLegendGraphic" :
"sld:GetLegendGraphic" ) );
463 appendFormat( elem, u
"image/jpeg"_s );
464 appendFormat( elem, u
"image/png"_s );
465 appendFormat( elem, u
"application/json"_s );
466 elem.appendChild( dcpTypeElem.cloneNode().toElement() );
467 requestElem.appendChild( elem );
470 elem = doc.createElement( ( version ==
"1.1.1"_L1 ?
"DescribeLayer" :
"sld:DescribeLayer" ) );
471 appendFormat( elem, u
"text/xml"_s );
472 elem.appendChild( dcpTypeElem.cloneNode().toElement() );
473 requestElem.appendChild( elem );
476 elem = doc.createElement( ( version ==
"1.1.1"_L1 ?
"GetStyles" :
"qgs:GetStyles" ) );
477 appendFormat( elem, u
"text/xml"_s );
478 elem.appendChild( dcpTypeElem.cloneNode().toElement() );
479 requestElem.appendChild( elem );
484 elem = doc.createElement( u
"GetPrint"_s );
485 appendFormat( elem, u
"svg"_s );
486 appendFormat( elem, u
"png"_s );
487 appendFormat( elem, u
"pdf"_s );
488 elem.appendChild( dcpTypeElem.cloneNode().toElement() );
489 requestElem.appendChild( elem );
493 elem = doc.createElement( u
"Exception"_s );
494 appendFormat( elem, ( version ==
"1.1.1"_L1 ?
"application/vnd.ogc.se_xml" :
"XML" ) );
495 capabilityElem.appendChild( elem );
498 if ( version ==
"1.3.0"_L1 )
500 elem = doc.createElement( u
"sld:UserDefinedSymbolization"_s );
501 elem.setAttribute( u
"SupportSLD"_s, u
"1"_s );
502 elem.setAttribute( u
"UserLayer"_s, u
"0"_s );
503 elem.setAttribute( u
"UserStyle"_s, u
"1"_s );
504 elem.setAttribute( u
"RemoteWFS"_s, u
"0"_s );
505 elem.setAttribute( u
"InlineFeature"_s, u
"0"_s );
506 elem.setAttribute( u
"RemoteWCS"_s, u
"0"_s );
507 capabilityElem.appendChild( elem );
515 return capabilityElem;
520 QDomElement inspireCapabilitiesElem;
523 return inspireCapabilitiesElem;
525 inspireCapabilitiesElem = doc.createElement( u
"inspire_vs:ExtendedCapabilities"_s );
529 if ( !inspireMetadataUrl.isEmpty() )
531 QDomElement inspireCommonMetadataUrlElem = doc.createElement( u
"inspire_common:MetadataUrl"_s );
532 inspireCommonMetadataUrlElem.setAttribute( u
"xsi:type"_s, u
"inspire_common:resourceLocatorType"_s );
534 QDomElement inspireCommonMetadataUrlUrlElem = doc.createElement( u
"inspire_common:URL"_s );
535 inspireCommonMetadataUrlUrlElem.appendChild( doc.createTextNode( inspireMetadataUrl ) );
536 inspireCommonMetadataUrlElem.appendChild( inspireCommonMetadataUrlUrlElem );
539 if ( !inspireMetadataUrlType.isNull() )
541 QDomElement inspireCommonMetadataUrlMediaTypeElem = doc.createElement( u
"inspire_common:MediaType"_s );
542 inspireCommonMetadataUrlMediaTypeElem.appendChild( doc.createTextNode( inspireMetadataUrlType ) );
543 inspireCommonMetadataUrlElem.appendChild( inspireCommonMetadataUrlMediaTypeElem );
546 inspireCapabilitiesElem.appendChild( inspireCommonMetadataUrlElem );
550 QDomElement inspireCommonResourceTypeElem = doc.createElement( u
"inspire_common:ResourceType"_s );
551 inspireCommonResourceTypeElem.appendChild( doc.createTextNode( u
"service"_s ) );
552 inspireCapabilitiesElem.appendChild( inspireCommonResourceTypeElem );
554 QDomElement inspireCommonSpatialDataServiceTypeElem = doc.createElement( u
"inspire_common:SpatialDataServiceType"_s );
555 inspireCommonSpatialDataServiceTypeElem.appendChild( doc.createTextNode( u
"view"_s ) );
556 inspireCapabilitiesElem.appendChild( inspireCommonSpatialDataServiceTypeElem );
559 if ( !inspireTemporalReference.isNull() )
561 QDomElement inspireCommonTemporalReferenceElem = doc.createElement( u
"inspire_common:TemporalReference"_s );
562 QDomElement inspireCommonDateOfLastRevisionElem = doc.createElement( u
"inspire_common:DateOfLastRevision"_s );
563 inspireCommonDateOfLastRevisionElem.appendChild( doc.createTextNode( inspireTemporalReference ) );
564 inspireCommonTemporalReferenceElem.appendChild( inspireCommonDateOfLastRevisionElem );
565 inspireCapabilitiesElem.appendChild( inspireCommonTemporalReferenceElem );
568 QDomElement inspireCommonMetadataPointOfContactElem = doc.createElement( u
"inspire_common:MetadataPointOfContact"_s );
571 QDomElement inspireCommonOrganisationNameElem = doc.createElement( u
"inspire_common:OrganisationName"_s );
572 if ( !contactOrganization.isNull() )
574 inspireCommonOrganisationNameElem.appendChild( doc.createTextNode( contactOrganization ) );
576 inspireCommonMetadataPointOfContactElem.appendChild( inspireCommonOrganisationNameElem );
579 QDomElement inspireCommonEmailAddressElem = doc.createElement( u
"inspire_common:EmailAddress"_s );
580 if ( !contactMail.isNull() )
582 inspireCommonEmailAddressElem.appendChild( doc.createTextNode( contactMail ) );
584 inspireCommonMetadataPointOfContactElem.appendChild( inspireCommonEmailAddressElem );
586 inspireCapabilitiesElem.appendChild( inspireCommonMetadataPointOfContactElem );
589 if ( !inspireMetadataDate.isNull() )
591 QDomElement inspireCommonMetadataDateElem = doc.createElement( u
"inspire_common:MetadataDate"_s );
592 inspireCommonMetadataDateElem.appendChild( doc.createTextNode( inspireMetadataDate ) );
593 inspireCapabilitiesElem.appendChild( inspireCommonMetadataDateElem );
598 QDomElement inspireCommonSupportedLanguagesElem = doc.createElement( u
"inspire_common:SupportedLanguages"_s );
599 inspireCommonSupportedLanguagesElem.setAttribute( u
"xsi:type"_s, u
"inspire_common:supportedLanguagesType"_s );
601 QDomElement inspireCommonLanguageElem = doc.createElement( u
"inspire_common:Language"_s );
604 QDomElement inspireCommonDefaultLanguageElem = doc.createElement( u
"inspire_common:DefaultLanguage"_s );
605 inspireCommonDefaultLanguageElem.appendChild( inspireCommonLanguageElem );
606 inspireCommonSupportedLanguagesElem.appendChild( inspireCommonDefaultLanguageElem );
610 QDomElement inspireCommonSupportedLanguageElem = doc.createElement(
"inspire_common:SupportedLanguage" );
611 inspireCommonSupportedLanguageElem.appendChild( inspireCommonLanguageElem.cloneNode().toElement() );
612 inspireCommonSupportedLanguagesElem.appendChild( inspireCommonSupportedLanguageElem );
615 inspireCapabilitiesElem.appendChild( inspireCommonSupportedLanguagesElem );
617 QDomElement inspireCommonResponseLanguageElem = doc.createElement( u
"inspire_common:ResponseLanguage"_s );
618 inspireCommonResponseLanguageElem.appendChild( inspireCommonLanguageElem.cloneNode().toElement() );
619 inspireCapabilitiesElem.appendChild( inspireCommonResponseLanguageElem );
621 return inspireCapabilitiesElem;
627 if ( projectComposers.size() == 0 )
628 return QDomElement();
632 QDomElement composerTemplatesElem = doc.createElement( u
"ComposerTemplates"_s );
633 QList<QgsPrintLayout *>::const_iterator cIt = projectComposers.constBegin();
634 for ( ; cIt != projectComposers.constEnd(); ++cIt )
637 if ( restrictedComposers.contains( layout->
name() ) )
649 QDomElement composerTemplateElem = doc.createElement( u
"ComposerTemplate"_s );
650 composerTemplateElem.setAttribute( u
"name"_s, layout->
name() );
653 composerTemplateElem.setAttribute( u
"width"_s, width.
length() );
654 composerTemplateElem.setAttribute( u
"height"_s, height.
length() );
658 if ( atlas && atlas->
enabled() )
660 composerTemplateElem.setAttribute( u
"atlasEnabled"_s, u
"1"_s );
667 layerName = cLayer->
id();
669 else if ( layerName.isEmpty() )
671 layerName = cLayer->
name();
673 composerTemplateElem.setAttribute( u
"atlasCoverageLayer"_s, layerName );
678 QList<QgsLayoutItemMap *> layoutMapList;
680 QList<QgsLayoutItemMap *>::const_iterator cmIt = layoutMapList.constBegin();
683 for ( ; cmIt != layoutMapList.constEnd(); ++cmIt )
687 QDomElement composerMapElem = doc.createElement( u
"ComposerMap"_s );
688 composerMapElem.setAttribute( u
"name"_s, u
"map%1"_s.arg( mapId ) );
689 composerMapElem.setAttribute( u
"itemName"_s, composerMap->
displayName() );
691 composerMapElem.setAttribute( u
"width"_s, composerMap->rect().width() );
692 composerMapElem.setAttribute( u
"height"_s, composerMap->rect().height() );
693 composerTemplateElem.appendChild( composerMapElem );
697 QList<QgsLayoutItemLabel *> composerLabelList;
699 QList<QgsLayoutItemLabel *>::const_iterator clIt = composerLabelList.constBegin();
700 for ( ; clIt != composerLabelList.constEnd(); ++clIt )
703 QString
id = composerLabel->
id();
707 QDomElement composerLabelElem = doc.createElement( u
"ComposerLabel"_s );
708 composerLabelElem.setAttribute( u
"name"_s,
id );
709 composerTemplateElem.appendChild( composerLabelElem );
713 QList<QgsLayoutItemHtml *> composerHtmlList;
715 QList<QgsLayoutItemHtml *>::const_iterator chIt = composerHtmlList.constBegin();
716 for ( ; chIt != composerHtmlList.constEnd(); ++chIt )
722 QString
id = composerHtml->
frame( 0 )->
id();
726 QDomElement composerHtmlElem = doc.createElement( u
"ComposerHtml"_s );
727 composerHtmlElem.setAttribute( u
"name"_s,
id );
728 composerTemplateElem.appendChild( composerHtmlElem );
731 composerTemplatesElem.appendChild( composerTemplateElem );
734 if ( composerTemplatesElem.childNodes().size() == 0 )
735 return QDomElement();
737 return composerTemplatesElem;
743 if ( wfsLayerIds.size() == 0 )
744 return QDomElement();
746 QDomElement wfsLayersElem = doc.createElement( u
"WFSLayers"_s );
747 for (
int i = 0; i < wfsLayerIds.size(); ++i )
755 QDomElement wfsLayerElem = doc.createElement( u
"WFSLayer"_s );
758 wfsLayerElem.setAttribute( u
"name"_s, layer->
id() );
762 wfsLayerElem.setAttribute( u
"name"_s, layer->
name() );
764 wfsLayersElem.appendChild( wfsLayerElem );
767 return wfsLayersElem;
772 QDomElement &parentLayer,
777 const QMap<QString, QgsWmsLayerInfos> &wmsLayerInfos,
778 bool projectSettings,
779 QList<QgsDateTimeRange> &parentDateRanges
784 parentLayer.setAttribute( u
"queryable"_s,
hasQueryableLayers( layerIds, wmsLayerInfos ) ? u
"1"_s : u
"0"_s );
787 QMap<QString, QgsRectangle> crsExtents =
combineCrsExtents( layerIds, wmsLayerInfos );
789 appendCrsElementsToLayer( doc, parentLayer, crsExtents.keys(), QStringList(), !wgs84BoundingRect.
isNull() );
790 appendLayerWgs84BoundingRect( doc, parentLayer, wgs84BoundingRect );
791 appendLayerCrsExtents( doc, parentLayer, crsExtents );
793 appendLayersFromTreeGroup( doc, parentLayer, serverIface, project, request, layerTreeGroup, wmsLayerInfos, projectSettings, parentDateRanges );
800 QDomElement layerParentElem = doc.createElement( u
"Layer"_s );
804 if ( rootLayerName.isEmpty() && !project->
title().isEmpty() )
806 rootLayerName = project->
title();
809 if ( !rootLayerName.isEmpty() )
811 QDomElement layerParentNameElem = doc.createElement( u
"Name"_s );
812 QDomText layerParentNameText = doc.createTextNode( rootLayerName );
813 layerParentNameElem.appendChild( layerParentNameText );
814 layerParentElem.appendChild( layerParentNameElem );
818 QDomElement layerParentTitleElem = doc.createElement( u
"Title"_s );
820 layerParentTitleElem.appendChild( layerParentTitleText );
821 layerParentElem.appendChild( layerParentTitleElem );
825 if ( !rootLayerAbstract.isEmpty() )
827 QDomElement layerParentAbstElem = doc.createElement( u
"Abstract"_s );
828 QDomText layerParentAbstText = doc.createCDATASection( rootLayerAbstract );
829 layerParentAbstElem.appendChild( layerParentAbstText );
830 layerParentElem.appendChild( layerParentAbstElem );
834 addKeywordListElement( project, doc, layerParentElem );
837 if ( projectSettings )
839 QDomElement treeNameElem = doc.createElement( u
"TreeName"_s );
840 QDomText treeNameText = doc.createTextNode( project->
title() );
841 treeNameElem.appendChild( treeNameText );
842 layerParentElem.appendChild( treeNameElem );
848 auto outputCrsList = QList<QgsCoordinateReferenceSystem>();
854 outputCrsList.append( crs );
882 QMap<QString, QgsRectangle> wmsCrsExtents;
894 appendCrsElementsToLayer( doc, layerParentElem, wmsCrsExtents.keys(), QStringList(), project->
crs().
isEarthCrs() );
895 appendLayerWgs84BoundingRect( doc, layerParentElem, wmsWgs84BoundingRect );
896 appendLayerCrsExtents( doc, layerParentElem, wmsCrsExtents );
898 QList<QgsDateTimeRange> parentDateRanges;
899 appendLayersFromTreeGroup( doc, layerParentElem, serverIface, project, request, projectLayerTreeRoot, wmsLayerInfos, projectSettings, parentDateRanges );
903 QList<QgsDateTimeRange> parentDateRanges;
904 handleLayersFromTreeGroup( doc, layerParentElem, serverIface, project, request, projectLayerTreeRoot, wmsLayerInfos, projectSettings, parentDateRanges );
907 return layerParentElem;
915 void writeServerProperties( QDomDocument &doc, QDomElement &layerElem,
const QgsProject *project,
const QgsMapLayerServerProperties *serverProperties,
const QString &name,
const QString &version )
917 const QString title = serverProperties->
title();
918 QDomElement titleElem = doc.createElement( u
"Title"_s );
919 QDomText titleText = doc.createTextNode( !title.isEmpty() ? title : name );
920 titleElem.appendChild( titleText );
921 layerElem.appendChild( titleElem );
923 const QString abstract = serverProperties->
abstract();
924 if ( !abstract.isEmpty() )
926 QDomElement abstractElem = doc.createElement( u
"Abstract"_s );
927 QDomText abstractText = doc.createTextNode( abstract );
928 abstractElem.appendChild( abstractText );
929 layerElem.appendChild( abstractElem );
934 const QStringList keywords = !serverProperties->
keywordList().isEmpty() ? serverProperties->
keywordList().split(
',' ) : QStringList();
935 if ( !keywords.isEmpty() )
937 QDomElement keywordListElem = doc.createElement( u
"KeywordList"_s );
938 for (
const QString &keyword : std::as_const( keywords ) )
940 QDomElement keywordElem = doc.createElement( u
"Keyword"_s );
941 QDomText keywordText = doc.createTextNode( keyword.trimmed() );
942 keywordElem.appendChild( keywordText );
945 keywordElem.setAttribute( u
"vocabulary"_s, u
"SIA_Geo405"_s );
947 keywordListElem.appendChild( keywordElem );
949 layerElem.appendChild( keywordListElem );
953 const QString dataUrl = serverProperties->
dataUrl();
954 if ( !dataUrl.isEmpty() )
956 QDomElement dataUrlElem = doc.createElement( u
"DataURL"_s );
957 QDomElement dataUrlFormatElem = doc.createElement( u
"Format"_s );
958 const QString dataUrlFormat = serverProperties->
dataUrlFormat();
959 QDomText dataUrlFormatText = doc.createTextNode( dataUrlFormat );
960 dataUrlFormatElem.appendChild( dataUrlFormatText );
961 dataUrlElem.appendChild( dataUrlFormatElem );
962 QDomElement dataORElem = doc.createElement( u
"OnlineResource"_s );
963 dataORElem.setAttribute( u
"xmlns:xlink"_s, u
"http://www.w3.org/1999/xlink"_s );
964 dataORElem.setAttribute( u
"xlink:type"_s, u
"simple"_s );
965 dataORElem.setAttribute( u
"xlink:href"_s, dataUrl );
966 dataUrlElem.appendChild( dataORElem );
967 layerElem.appendChild( dataUrlElem );
971 const QString attribution = serverProperties->
attribution();
972 if ( !attribution.isEmpty() )
974 QDomElement attribElem = doc.createElement( u
"Attribution"_s );
975 QDomElement attribTitleElem = doc.createElement( u
"Title"_s );
976 QDomText attribText = doc.createTextNode( attribution );
977 attribTitleElem.appendChild( attribText );
978 attribElem.appendChild( attribTitleElem );
979 const QString attributionUrl = serverProperties->
attributionUrl();
980 if ( !attributionUrl.isEmpty() )
982 QDomElement attribORElem = doc.createElement( u
"OnlineResource"_s );
983 attribORElem.setAttribute( u
"xmlns:xlink"_s, u
"http://www.w3.org/1999/xlink"_s );
984 attribORElem.setAttribute( u
"xlink:type"_s, u
"simple"_s );
985 attribORElem.setAttribute( u
"xlink:href"_s, attributionUrl );
986 attribElem.appendChild( attribORElem );
988 layerElem.appendChild( attribElem );
992 const QList<QgsServerMetadataUrlProperties::MetadataUrl> metadataUrls = serverProperties->
metadataUrls();
993 for (
const QgsMapLayerServerProperties::MetadataUrl &metadataUrl : std::as_const( metadataUrls ) )
995 QDomElement metaUrlElem = doc.createElement( u
"MetadataURL"_s );
996 const QString metadataUrlType = metadataUrl.type;
997 if ( version ==
"1.1.1"_L1 )
999 metaUrlElem.setAttribute( u
"type"_s, metadataUrlType );
1001 else if ( metadataUrlType ==
"FGDC"_L1 )
1003 metaUrlElem.setAttribute( u
"type"_s, u
"FGDC:1998"_s );
1005 else if ( metadataUrlType ==
"TC211"_L1 )
1007 metaUrlElem.setAttribute( u
"type"_s, u
"ISO19115:2003"_s );
1011 metaUrlElem.setAttribute( u
"type"_s, metadataUrlType );
1013 const QString metadataUrlFormat = metadataUrl.format;
1014 if ( !metadataUrlFormat.isEmpty() )
1016 QDomElement metaUrlFormatElem = doc.createElement( u
"Format"_s );
1017 QDomText metaUrlFormatText = doc.createTextNode( metadataUrlFormat );
1018 metaUrlFormatElem.appendChild( metaUrlFormatText );
1019 metaUrlElem.appendChild( metaUrlFormatElem );
1021 QDomElement metaUrlORElem = doc.createElement( u
"OnlineResource"_s );
1022 metaUrlORElem.setAttribute( u
"xmlns:xlink"_s, u
"http://www.w3.org/1999/xlink"_s );
1023 metaUrlORElem.setAttribute( u
"xlink:type"_s, u
"simple"_s );
1024 metaUrlORElem.setAttribute( u
"xlink:href"_s, metadataUrl.url );
1025 metaUrlElem.appendChild( metaUrlORElem );
1026 layerElem.appendChild( metaUrlElem );
1030 void writeLegendUrl(
1032 QDomElement &styleElem,
1033 const QString &legendUrl,
1034 const QString &legendUrlFormat,
1035 const QString &name,
1036 const QString &styleName,
1037 const QgsProject *project,
1039 const QgsServerSettings *settings
1043 QDomElement getLayerLegendGraphicElem = doc.createElement( u
"LegendURL"_s );
1045 QString customHrefString = legendUrl;
1047 QStringList getLayerLegendGraphicFormats;
1048 if ( !customHrefString.isEmpty() )
1050 getLayerLegendGraphicFormats << legendUrlFormat;
1054 getLayerLegendGraphicFormats << u
"image/png"_s;
1057 for (
const QString &getLayerLegendGraphicFormat : std::as_const( getLayerLegendGraphicFormats ) )
1059 QDomElement getLayerLegendGraphicFormatElem = doc.createElement( u
"Format"_s );
1060 QDomText getLayerLegendGraphicFormatText = doc.createTextNode( getLayerLegendGraphicFormat );
1061 getLayerLegendGraphicFormatElem.appendChild( getLayerLegendGraphicFormatText );
1062 getLayerLegendGraphicElem.appendChild( getLayerLegendGraphicFormatElem );
1066 if ( customHrefString.isEmpty() )
1069 QUrl href =
serviceUrl( request, project, *settings );
1070 const QString hrefString = href.toString() + ( href.hasQuery() ?
"&" :
"?" );
1072 QUrl mapUrl( hrefString );
1073 QUrlQuery mapUrlQuery( mapUrl.query() );
1074 mapUrlQuery.addQueryItem( u
"SERVICE"_s, u
"WMS"_s );
1075 mapUrlQuery.addQueryItem( u
"VERSION"_s, request.wmsParameters().version() );
1076 mapUrlQuery.addQueryItem( u
"REQUEST"_s, u
"GetLegendGraphic"_s );
1077 mapUrlQuery.addQueryItem( u
"LAYER"_s, name );
1078 mapUrlQuery.addQueryItem( u
"FORMAT"_s, u
"image/png"_s );
1079 mapUrlQuery.addQueryItem( u
"STYLE"_s, styleName );
1080 if ( request.wmsParameters().version() ==
"1.3.0"_L1 )
1082 mapUrlQuery.addQueryItem( u
"SLD_VERSION"_s, u
"1.1.0"_s );
1084 mapUrl.setQuery( mapUrlQuery );
1085 customHrefString = mapUrl.toString();
1088 QDomElement getLayerLegendGraphicORElem = doc.createElement( u
"OnlineResource"_s );
1089 getLayerLegendGraphicORElem.setAttribute( u
"xmlns:xlink"_s, u
"http://www.w3.org/1999/xlink"_s );
1090 getLayerLegendGraphicORElem.setAttribute( u
"xlink:type"_s, u
"simple"_s );
1091 getLayerLegendGraphicORElem.setAttribute( u
"xlink:href"_s, customHrefString );
1092 getLayerLegendGraphicElem.appendChild( getLayerLegendGraphicORElem );
1093 styleElem.appendChild( getLayerLegendGraphicElem );
1096 QDomElement createStyleElement( QDomDocument &doc,
const QString &styleName )
1098 QDomElement styleElem = doc.createElement( u
"Style"_s );
1099 QDomElement styleNameElem = doc.createElement( u
"Name"_s );
1100 QDomText styleNameText = doc.createTextNode( styleName );
1101 styleNameElem.appendChild( styleNameText );
1102 QDomElement styleTitleElem = doc.createElement( u
"Title"_s );
1103 QDomText styleTitleText = doc.createTextNode( styleName );
1104 styleTitleElem.appendChild( styleTitleText );
1105 styleElem.appendChild( styleNameElem );
1106 styleElem.appendChild( styleTitleElem );
1112 bool writeTimeDimensionNode( QDomDocument &doc, QDomElement &layerElem,
const QList<QgsDateTimeRange> &dateRanges )
1120 const bool hasDateTime = std::any_of( dateRanges.constBegin(), dateRanges.constEnd(), [](
const QgsDateTimeRange &r ) {
1121 return r.begin().time() != QTime( 0, 0 ) || ( !r.isInstant() && r.end().time() != QTime( 0, 0 ) );
1124 const QString dateFormat = hasDateTime ? u
"yyyy-MM-ddTHH:mm:ss"_s : u
"yyyy-MM-dd"_s;
1126 QStringList strValues;
1130 if ( range.begin().isValid() && range.end().isValid() )
1132 strValues << ( range.isInstant() ? range.begin().toString( dateFormat ) : u
"%1/%2"_s.arg( range.begin().toString( dateFormat ) ).arg( range.end().toString( dateFormat ) ) );
1136 QDomElement dimElem = doc.createElement( u
"Dimension"_s );
1137 dimElem.setAttribute( u
"name"_s, u
"TIME"_s );
1138 dimElem.setAttribute( u
"units"_s, u
"ISO8601"_s );
1139 QDomText dimValuesText = doc.createTextNode( strValues.join( QChar(
',' ) ) );
1140 dimElem.appendChild( dimValuesText );
1142 layerElem.appendChild( dimElem );
1144 return !hasDateTime;
1147 void appendLayersFromTreeGroup(
1149 QDomElement &parentLayer,
1150 QgsServerInterface *serverIface,
1151 const QgsProject *project,
1153 const QgsLayerTreeGroup *layerTreeGroup,
1154 const QMap<QString, QgsWmsLayerInfos> &wmsLayerInfos,
1155 bool projectSettings,
1156 QList<QgsDateTimeRange> &parentDateRanges
1159 const QString version = request.wmsParameters().version();
1164 QList<QgsLayerTreeNode *> layerTreeGroupChildren = layerTreeGroup->
children();
1165 for (
int i = 0; i < layerTreeGroupChildren.size(); ++i )
1167 QgsLayerTreeNode *treeNode = layerTreeGroupChildren.at( i );
1168 QDomElement layerElem = doc.createElement( u
"Layer"_s );
1170 if ( projectSettings )
1172 layerElem.setAttribute( u
"visible"_s, treeNode->
isVisible() );
1174 layerElem.setAttribute( u
"expanded"_s, treeNode->
isExpanded() );
1179 QgsLayerTreeGroup *treeGroupChild =
static_cast<QgsLayerTreeGroup *
>( treeNode );
1181 QString name = treeGroupChild->
name();
1182 if ( restrictedLayers.contains( name ) )
1187 if ( projectSettings )
1194 if ( !skipNameForGroup )
1196 QDomElement nameElem = doc.createElement( u
"Name"_s );
1198 if ( !shortName.isEmpty() )
1199 nameText = doc.createTextNode( shortName );
1201 nameText = doc.createTextNode( name );
1202 nameElem.appendChild( nameText );
1203 layerElem.appendChild( nameElem );
1206 writeServerProperties( doc, layerElem, project, treeGroupChild->
serverProperties(), name, version );
1209 const QString styleName = u
"default"_s;
1210 QDomElement styleElem = createStyleElement( doc, styleName );
1213 layerElem.appendChild( styleElem );
1216 if ( projectSettings )
1218 QDomElement treeNameElem = doc.createElement( u
"TreeName"_s );
1219 QDomText treeNameText = doc.createTextNode( name );
1220 treeNameElem.appendChild( treeNameText );
1221 layerElem.appendChild( treeNameElem );
1224 QList<QgsDateTimeRange> childrenDateRanges;
1225 handleLayersFromTreeGroup( doc, layerElem, serverIface, project, request, treeGroupChild, wmsLayerInfos, projectSettings, childrenDateRanges );
1229 writeTimeDimensionNode( doc, layerElem, childrenDateRanges );
1230 parentDateRanges.append( childrenDateRanges );
1234 if ( layerElem.elementsByTagName( u
"Layer"_s ).length() == 0 )
1241 QgsLayerTreeLayer *treeLayer =
static_cast<QgsLayerTreeLayer *
>( treeNode );
1242 QgsMapLayer *l = treeLayer->
layer();
1243 if ( !wmsLayerInfos.contains( treeLayer->
layerId() ) )
1248 const QgsWmsLayerInfos &layerInfos = wmsLayerInfos[treeLayer->
layerId()];
1250 layerElem.setAttribute( u
"queryable"_s, layerInfos.
queryable ? u
"1"_s : u
"0"_s );
1252 QDomElement nameElem = doc.createElement( u
"Name"_s );
1253 QDomText nameText = doc.createTextNode( layerInfos.
name );
1254 nameElem.appendChild( nameText );
1255 layerElem.appendChild( nameElem );
1262 appendCrsElementsToLayer( doc, layerElem, layerInfos.
crsExtents.keys(), QStringList(), l->
crs().
isEarthCrs() );
1266 appendLayerCrsExtents( doc, layerElem, layerInfos.
crsExtents );
1270 appendLayerStyles( doc, layerElem, layerInfos, project, request, serverIface->
serverSettings() );
1276 auto formatScale = [](
double value ) {
1277 const thread_local QRegularExpression trailingZeroRegEx = QRegularExpression( u
"0+$"_s );
1278 const thread_local QRegularExpression trailingPointRegEx = QRegularExpression( u
"[.]+$"_s );
1279 return QString::number( value,
'f' ).remove( trailingZeroRegEx ).remove( trailingPointRegEx );
1282 if ( version ==
"1.1.1"_L1 )
1285 double SCALE_TO_SCALEHINT =
OGC_PX_M * M_SQRT2;
1287 QDomElement scaleHintElem = doc.createElement( u
"ScaleHint"_s );
1288 scaleHintElem.setAttribute( u
"min"_s, formatScale( layerInfos.
maxScale * SCALE_TO_SCALEHINT ) );
1289 scaleHintElem.setAttribute( u
"max"_s, formatScale( layerInfos.
minScale * SCALE_TO_SCALEHINT ) );
1290 layerElem.appendChild( scaleHintElem );
1294 QDomElement minScaleElem = doc.createElement( u
"MinScaleDenominator"_s );
1295 QDomText minScaleText = doc.createTextNode( formatScale( layerInfos.
maxScale ) );
1296 minScaleElem.appendChild( minScaleText );
1297 layerElem.appendChild( minScaleElem );
1299 QDomElement maxScaleElem = doc.createElement( u
"MaxScaleDenominator"_s );
1300 QDomText maxScaleText = doc.createTextNode( formatScale( layerInfos.
minScale ) );
1301 maxScaleElem.appendChild( maxScaleText );
1302 layerElem.appendChild( maxScaleElem );
1306 bool timeDimensionAdded {
false };
1311 QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( l );
1312 QgsMapLayerServerProperties *serverProperties =
static_cast<QgsMapLayerServerProperties *
>( vl->
serverProperties() );
1313 const QList<QgsMapLayerServerProperties::WmsDimensionInfo> wmsDims = serverProperties->
wmsDimensions();
1314 for (
const QgsMapLayerServerProperties::WmsDimensionInfo &dim : wmsDims )
1318 if ( fieldIndex == -1 )
1323 QSet<QVariant> uniqueValues = vl->
uniqueValues( fieldIndex );
1326 if ( !dim.endFieldName.isEmpty() )
1328 int endFieldIndex = vl->
fields().
indexOf( dim.endFieldName );
1330 if ( endFieldIndex == -1 )
1334 uniqueValues.unite( vl->
uniqueValues( endFieldIndex ) );
1337 QList<QVariant> values = qgis::setToList( uniqueValues );
1338 std::sort( values.begin(), values.end() );
1340 QDomElement dimElem = doc.createElement( u
"Dimension"_s );
1341 dimElem.setAttribute( u
"name"_s, dim.name );
1343 if ( dim.name.toUpper() ==
"TIME"_L1 )
1345 timeDimensionAdded =
true;
1348 if ( !dim.units.isEmpty() )
1350 dimElem.setAttribute( u
"units"_s, dim.units );
1352 if ( !dim.unitSymbol.isEmpty() )
1354 dimElem.setAttribute( u
"unitSymbol"_s, dim.unitSymbol );
1356 if ( !values.isEmpty() && dim.defaultDisplayType == QgsMapLayerServerProperties::WmsDimensionInfo::MinValue )
1358 dimElem.setAttribute( u
"default"_s, values.first().toString() );
1360 else if ( !values.isEmpty() && dim.defaultDisplayType == QgsMapLayerServerProperties::WmsDimensionInfo::MaxValue )
1362 dimElem.setAttribute( u
"default"_s, values.last().toString() );
1364 else if ( dim.defaultDisplayType == QgsMapLayerServerProperties::WmsDimensionInfo::ReferenceValue )
1366 dimElem.setAttribute( u
"default"_s, dim.referenceValue.toString() );
1368 dimElem.setAttribute( u
"multipleValues"_s, u
"1"_s );
1369 dimElem.setAttribute( u
"nearestValue"_s, u
"0"_s );
1370 if ( projectSettings )
1372 dimElem.setAttribute( u
"fieldName"_s, dim.fieldName );
1373 dimElem.setAttribute( u
"endFieldName"_s, dim.endFieldName );
1376 QStringList strValues;
1377 for (
const QVariant &v : values )
1379 strValues << v.toString();
1381 QDomText dimValuesText = doc.createTextNode( strValues.join(
", "_L1 ) );
1382 dimElem.appendChild( dimValuesText );
1383 layerElem.appendChild( dimElem );
1394 const bool isDateList = writeTimeDimensionNode( doc, layerElem, allRanges );
1396 parentDateRanges.append( allRanges );
1398 QDomElement timeExtentElem = doc.createElement( u
"Extent"_s );
1399 timeExtentElem.setAttribute( u
"name"_s, u
"TIME"_s );
1405 extent = u
"%1/%2"_s.arg( timeExtent.
begin().date().toString( Qt::DateFormat::ISODate ), timeExtent.
end().date().toString( Qt::DateFormat::ISODate ) );
1409 extent = u
"%1/%2"_s.arg( timeExtent.
begin().toString( Qt::DateFormat::ISODate ), timeExtent.
end().toString( Qt::DateFormat::ISODate ) );
1411 QDomText extentValueText = doc.createTextNode( extent );
1412 timeExtentElem.appendChild( extentValueText );
1413 layerElem.appendChild( timeExtentElem );
1416 if ( projectSettings )
1418 appendLayerProjectSettings( doc, layerElem, l );
1422 parentLayer.appendChild( layerElem );
1426 void appendLayerStyles( QDomDocument &doc, QDomElement &layerElem,
const QgsWmsLayerInfos &layerInfos,
const QgsProject *project,
const QgsWmsRequest &request,
const QgsServerSettings *settings )
1428 for (
const QString &styleName : std::as_const( layerInfos.
styles ) )
1430 QDomElement styleElem = createStyleElement( doc, styleName );
1432 writeLegendUrl( doc, styleElem, layerInfos.
legendUrl, layerInfos.
legendUrlFormat, layerInfos.
name, styleName, project, request, settings );
1434 layerElem.appendChild( styleElem );
1438 void appendCrsElementsToLayer( QDomDocument &doc, QDomElement &layerElement,
const QStringList &crsList,
const QStringList &constrainedCrsList,
bool hasEarthCrs )
1440 if ( layerElement.isNull() )
1445 const QString version = doc.documentElement().attribute( u
"version"_s );
1448 QDomElement titleElement = layerElement.firstChildElement( u
"Title"_s );
1449 QDomElement abstractElement = layerElement.firstChildElement( u
"Abstract"_s );
1450 QDomElement keywordListElement = layerElement.firstChildElement( u
"KeywordList"_s );
1451 QDomElement CRSPrecedingElement = !keywordListElement.isNull() ? keywordListElement : !abstractElement.isNull() ? abstractElement : titleElement;
1453 if ( CRSPrecedingElement.isNull() )
1456 const QDomElement keyElement = layerElement.firstChildElement( u
"KeywordList"_s );
1457 CRSPrecedingElement = keyElement;
1461 if ( !constrainedCrsList.isEmpty() )
1463 for (
int i = constrainedCrsList.size() - 1; i >= 0; --i )
1465 appendCrsElementToLayer( doc, layerElement, CRSPrecedingElement, constrainedCrsList.at( i ) );
1470 for (
const QString &crs : crsList )
1472 appendCrsElementToLayer( doc, layerElement, CRSPrecedingElement, crs );
1478 if ( version ==
"1.3.0"_L1 && hasEarthCrs )
1480 appendCrsElementToLayer( doc, layerElement, CRSPrecedingElement, QString(
"CRS:84" ) );
1484 void appendCrsElementToLayer( QDomDocument &doc, QDomElement &layerElement,
const QDomElement &precedingElement,
const QString &crsText )
1486 if ( crsText.isEmpty() )
1488 const QString version = doc.documentElement().attribute( u
"version"_s );
1489 QDomElement crsElement = doc.createElement( version ==
"1.1.1"_L1 ?
"SRS" :
"CRS" );
1490 QDomText crsTextNode = doc.createTextNode( crsText );
1491 crsElement.appendChild( crsTextNode );
1492 layerElement.insertAfter( crsElement, precedingElement );
1495 void appendLayerWgs84BoundingRect( QDomDocument &doc, QDomElement &layerElem,
const QgsRectangle &wgs84BoundingRect )
1498 if ( wgs84BoundingRect.
isNull() )
1504 QDomElement ExGeoBBoxElement;
1505 const int wgs84precision = 6;
1506 const QString version = doc.documentElement().attribute( u
"version"_s );
1507 if ( version ==
"1.1.1"_L1 )
1509 ExGeoBBoxElement = doc.createElement( u
"LatLonBoundingBox"_s );
1517 ExGeoBBoxElement = doc.createElement( u
"EX_GeographicBoundingBox"_s );
1518 QDomElement wBoundLongitudeElement = doc.createElement( u
"westBoundLongitude"_s );
1520 wBoundLongitudeElement.appendChild( wBoundLongitudeText );
1521 ExGeoBBoxElement.appendChild( wBoundLongitudeElement );
1522 QDomElement eBoundLongitudeElement = doc.createElement( u
"eastBoundLongitude"_s );
1524 eBoundLongitudeElement.appendChild( eBoundLongitudeText );
1525 ExGeoBBoxElement.appendChild( eBoundLongitudeElement );
1526 QDomElement sBoundLatitudeElement = doc.createElement( u
"southBoundLatitude"_s );
1528 sBoundLatitudeElement.appendChild( sBoundLatitudeText );
1529 ExGeoBBoxElement.appendChild( sBoundLatitudeElement );
1530 QDomElement nBoundLatitudeElement = doc.createElement( u
"northBoundLatitude"_s );
1532 nBoundLatitudeElement.appendChild( nBoundLatitudeText );
1533 ExGeoBBoxElement.appendChild( nBoundLatitudeElement );
1536 const QDomElement lastCRSElem = layerElem.lastChildElement( version ==
"1.1.1"_L1 ?
"SRS" :
"CRS" );
1537 if ( !lastCRSElem.isNull() )
1539 layerElem.insertAfter( ExGeoBBoxElement, lastCRSElem );
1543 layerElem.appendChild( ExGeoBBoxElement );
1547 void appendLayerCrsExtents( QDomDocument &doc, QDomElement &layerElem,
const QMap<QString, QgsRectangle> &crsExtents )
1549 const QString version = doc.documentElement().attribute( u
"version"_s );
1551 const auto &keys = crsExtents.keys();
1552 for (
const QString &crsText : std::as_const( keys ) )
1555 QgsRectangle crsExtent( crsExtents[crsText] );
1557 if ( crsExtent.isNull() )
1569 QDomElement bBoxElement = doc.createElement( u
"BoundingBox"_s );
1572 bBoxElement.setAttribute( version ==
"1.1.1"_L1 ?
"SRS" :
"CRS", crs.
authid() );
1585 QDomElement lastBBoxElem = layerElem.lastChildElement( u
"BoundingBox"_s );
1586 if ( !lastBBoxElem.isNull() )
1588 layerElem.insertAfter( bBoxElement, lastBBoxElem );
1592 lastBBoxElem = layerElem.lastChildElement( version ==
"1.1.1"_L1 ?
"LatLonBoundingBox" :
"EX_GeographicBoundingBox" );
1593 if ( !lastBBoxElem.isNull() )
1595 layerElem.insertAfter( bBoxElement, lastBBoxElem );
1599 layerElem.appendChild( bBoxElement );
1605 void appendDrawingOrder( QDomDocument &doc, QDomElement &parentElem, QgsServerInterface *serverIface,
const QgsProject *project )
1607#ifdef HAVE_SERVER_PYTHON_PLUGINS
1610 ( void ) serverIface;
1615 QStringList layerList;
1617 const QgsLayerTree *projectLayerTreeRoot = project->
layerTreeRoot();
1618 QList<QgsMapLayer *> projectLayerOrder = projectLayerTreeRoot->
layerOrder();
1619 for (
int i = 0; i < projectLayerOrder.size(); ++i )
1621 QgsMapLayer *l = projectLayerOrder.at( i );
1623 if ( restrictedLayers.contains( l->
name() ) )
1627#ifdef HAVE_SERVER_PYTHON_PLUGINS
1633 QString wmsName = l->
name();
1643 layerList << wmsName;
1646 if ( !layerList.isEmpty() )
1648 QStringList reversedList;
1649 reversedList.reserve( layerList.size() );
1650 for (
int i = layerList.size() - 1; i >= 0; --i )
1651 reversedList << layerList[i];
1653 QDomElement layerDrawingOrderElem = doc.createElement( u
"LayerDrawingOrder"_s );
1654 QDomText drawingOrderText = doc.createTextNode( reversedList.join(
',' ) );
1655 layerDrawingOrderElem.appendChild( drawingOrderText );
1656 parentElem.appendChild( layerDrawingOrderElem );
1660 void appendLayerProjectSettings( QDomDocument &doc, QDomElement &layerElem, QgsMapLayer *currentLayer )
1662 if ( !currentLayer )
1668 QDomElement treeNameElem = doc.createElement( u
"TreeName"_s );
1669 QDomText treeNameText = doc.createTextNode( currentLayer->
name() );
1670 treeNameElem.appendChild( treeNameText );
1671 layerElem.appendChild( treeNameElem );
1673 switch ( currentLayer->
type() )
1677 QgsVectorLayer *vLayer =
static_cast<QgsVectorLayer *
>( currentLayer );
1679 int displayFieldIdx = -1;
1680 QString displayField = u
"maptip"_s;
1682 if ( exp.isField() )
1684 displayField =
static_cast<const QgsExpressionNodeColumnRef *
>( exp.rootNode() )->name();
1689 QDomElement attributesElem = doc.createElement( u
"Attributes"_s );
1690 const QgsFields layerFields = vLayer->
fields();
1691 for (
int idx = 0; idx < layerFields.
count(); ++idx )
1693 QgsField field = layerFields.
at( idx );
1699 if ( idx == displayFieldIdx )
1703 QDomElement attributeElem = doc.createElement( u
"Attribute"_s );
1704 attributeElem.setAttribute( u
"name"_s, field.
name() );
1705 attributeElem.setAttribute( u
"type"_s, QVariant::typeToName( field.
type() ) );
1706 attributeElem.setAttribute( u
"typeName"_s, field.
typeName() );
1707 QString alias = field.
alias();
1708 if ( !alias.isEmpty() )
1710 attributeElem.setAttribute( u
"alias"_s, alias );
1715 attributeElem.setAttribute( u
"comment"_s, field.
comment() );
1716 attributeElem.setAttribute( u
"length"_s, field.
length() );
1717 attributeElem.setAttribute( u
"precision"_s, field.
precision() );
1718 attributesElem.appendChild( attributeElem );
1722 layerElem.setAttribute( u
"displayField"_s, displayField );
1726 if ( pkAttributes.size() > 0 )
1728 QDomElement pkElem = doc.createElement( u
"PrimaryKey"_s );
1729 QgsAttributeList::const_iterator pkIt = pkAttributes.constBegin();
1730 for ( ; pkIt != pkAttributes.constEnd(); ++pkIt )
1732 QDomElement pkAttributeElem = doc.createElement( u
"PrimaryKeyAttribute"_s );
1733 QDomText pkAttName = doc.createTextNode( layerFields.
at( *pkIt ).
name() );
1734 pkAttributeElem.appendChild( pkAttName );
1735 pkElem.appendChild( pkAttributeElem );
1737 layerElem.appendChild( pkElem );
1744 layerElem.setAttribute( u
"opacity"_s, QString::number( vLayer->
opacity() ) );
1746 layerElem.appendChild( attributesElem );
1752 const QgsDataProvider *provider = currentLayer->
dataProvider();
1753 if ( provider && provider->
name() ==
"wms" )
1756 QVariant wmsBackgroundLayer = currentLayer->
customProperty( u
"WMSBackgroundLayer"_s,
false );
1757 QDomElement wmsBackgroundLayerElem = doc.createElement(
"WMSBackgroundLayer" );
1758 QDomText wmsBackgroundLayerText = doc.createTextNode( wmsBackgroundLayer.toBool() ? u
"1"_s : u
"0"_s );
1759 wmsBackgroundLayerElem.appendChild( wmsBackgroundLayerText );
1760 layerElem.appendChild( wmsBackgroundLayerElem );
1763 QVariant wmsPublishDataSourceUrl = currentLayer->
customProperty( u
"WMSPublishDataSourceUrl"_s,
false );
1764 if ( wmsPublishDataSourceUrl.toBool() )
1766 bool tiled = qobject_cast<const QgsRasterDataProvider *>( provider ) ? !qobject_cast<const QgsRasterDataProvider *>( provider )->nativeResolutions().isEmpty() :
false;
1768 QDomElement dataSourceElem = doc.createElement( tiled ? u
"WMTSDataSource"_s : u
"WMSDataSource"_s );
1769 QDomText dataSourceUri = doc.createTextNode( provider->
dataSourceUri() );
1770 dataSourceElem.appendChild( dataSourceUri );
1771 layerElem.appendChild( dataSourceElem );
1775 QVariant wmsPrintLayer = currentLayer->
customProperty( u
"WMSPrintLayer"_s );
1776 if ( wmsPrintLayer.isValid() )
1778 QDomElement wmsPrintLayerElem = doc.createElement(
"WMSPrintLayer" );
1779 QDomText wmsPrintLayerText = doc.createTextNode( wmsPrintLayer.toString() );
1780 wmsPrintLayerElem.appendChild( wmsPrintLayerText );
1781 layerElem.appendChild( wmsPrintLayerElem );
1785 QgsRasterLayer *rl =
static_cast<QgsRasterLayer *
>( currentLayer );
1786 QgsRasterRenderer *rasterRenderer = rl->
renderer();
1787 if ( rasterRenderer )
1789 layerElem.setAttribute( u
"opacity"_s, QString::number( rasterRenderer->
opacity() ) );
1805 void addKeywordListElement(
const QgsProject *project, QDomDocument &doc, QDomElement &parent )
1809 QDomElement keywordsElem = doc.createElement( u
"KeywordList"_s );
1811 QDomElement keywordElem = doc.createElement( u
"Keyword"_s );
1812 keywordElem.setAttribute( u
"vocabulary"_s, u
"ISO"_s );
1813 QDomText keywordText = doc.createTextNode( u
"infoMapAccessService"_s );
1814 keywordElem.appendChild( keywordText );
1815 keywordsElem.appendChild( keywordElem );
1816 parent.appendChild( keywordsElem );
1818 for (
const QString &keyword : std::as_const( keywords ) )
1820 if ( !keyword.isEmpty() )
1822 keywordElem = doc.createElement( u
"Keyword"_s );
1823 keywordText = doc.createTextNode( keyword );
1824 keywordElem.appendChild( keywordText );
1827 keywordElem.setAttribute( u
"vocabulary"_s, u
"SIA_Geo405"_s );
1829 keywordsElem.appendChild( keywordElem );
1832 parent.appendChild( keywordsElem );
1836 bool hasQueryableLayers(
const QStringList &layerIds,
const QMap<QString, QgsWmsLayerInfos> &wmsLayerInfos )
1838 for (
const QString &
id : std::as_const( layerIds ) )
1840 if ( !wmsLayerInfos.contains(
id ) )
1844 if ( wmsLayerInfos[
id].queryable )
1857 for (
const QString &
id : std::as_const( layerIds ) )
1859 if ( !wmsLayerInfos.contains(
id ) )
1864 QgsRectangle rect = wmsLayerInfos[id].wgs84BoundingRect;
1889 QMap<QString, QgsRectangle>
combineCrsExtents(
const QStringList &layerIds,
const QMap<QString, QgsWmsLayerInfos> &wmsLayerInfos )
1891 QMap<QString, QgsRectangle> combined;
1893 for (
const QString &
id : std::as_const( layerIds ) )
1895 if ( !wmsLayerInfos.contains(
id ) )
1901 const auto keys = layerInfos.
crsExtents.keys();
1902 for (
const QString &crs : std::as_const( keys ) )
1915 if ( !combined.contains( crs ) )
1917 combined[crs] = rect;
1921 combined[crs].combineExtentWith( rect );
@ 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.
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 Header entry Add Header entry to the response Note that it is usually an error to set Header afte...
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.
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.