52 void appendLayerProjectSettings( QDomDocument &doc, QDomElement &layerElem,
QgsMapLayer *currentLayer );
54 void appendDrawingOrder( QDomDocument &doc, QDomElement &parentElem,
QgsServerInterface *serverIface,
57 void combineExtentAndCrsOfGroupChildren( QDomDocument &doc, QDomElement &groupElem,
const QgsProject *project,
58 bool considerMapExtent =
false );
60 bool crsSetFromLayerElement(
const QDomElement &layerElement, QSet<QString> &crsSet );
62 QgsRectangle layerBoundingBoxInProjectCrs(
const QDomDocument &doc,
const QDomElement &layerElem,
65 void appendLayerBoundingBox( QDomDocument &doc, QDomElement &layerElem,
const QgsRectangle &layerExtent,
69 void appendLayerBoundingBoxes( QDomDocument &doc, QDomElement &layerElem,
const QgsRectangle &lExtent,
71 const QStringList &constrainedCrsList,
const QgsProject *project,
74 void appendCrsElementToLayer( QDomDocument &doc, QDomElement &layerElement,
const QDomElement &precedingElement,
75 const QString &crsText );
77 void appendCrsElementsToLayer( QDomDocument &doc, QDomElement &layerElement,
78 const QStringList &crsList,
const QStringList &constrainedCrsList );
80 void appendLayerStyles( QDomDocument &doc, QDomElement &layerElem,
QgsMapLayer *currentLayer,
83 void appendLayersFromTreeGroup( QDomDocument &doc,
84 QDomElement &parentLayer,
87 const QgsWmsRequest &request,
89 bool projectSettings );
91 void addKeywordListElement(
const QgsProject *project, QDomDocument &doc, QDomElement &parent );
98 bool projectSettings )
100#ifdef HAVE_SERVER_PYTHON_PLUGINS
105 const QDomDocument *capabilitiesDocument =
nullptr;
110 QStringList cacheKeyList;
111 cacheKeyList << ( projectSettings ? QStringLiteral(
"projectSettings" ) : request.
wmsParameters().
version() );
115#ifdef HAVE_SERVER_PYTHON_PLUGINS
119 QString cacheKey = cacheKeyList.join(
'-' );
121#ifdef HAVE_SERVER_PYTHON_PLUGINS
123 if ( cacheManager && cacheManager->
getCachedDocument( &doc, project, request, accessControl ) )
125 capabilitiesDocument = &doc;
128 if ( !capabilitiesDocument && cache )
133 if ( !capabilitiesDocument )
135 QgsMessageLog::logMessage( QStringLiteral(
"WMS capabilities document not found in cache" ), QStringLiteral(
"Server" ) );
137 doc =
getCapabilities( serverIface, project, request, projectSettings );
139#ifdef HAVE_SERVER_PYTHON_PLUGINS
143 capabilitiesDocument = &doc;
148 if ( !capabilitiesDocument )
153 if ( !capabilitiesDocument )
155 capabilitiesDocument = &doc;
167 response.
setHeader( QStringLiteral(
"Content-Type" ), QStringLiteral(
"text/xml; charset=utf-8" ) );
168 response.
write( capabilitiesDocument->toByteArray() );
173 bool projectSettings )
176 QDomElement wmsCapabilitiesElement;
182 QString hrefString = href.toString();
183 hrefString.append( href.hasQuery() ?
"&" :
"?" );
186 QDomProcessingInstruction xmlDeclaration = doc.createProcessingInstruction( QStringLiteral(
"xml" ),
187 QStringLiteral(
"version=\"1.0\" encoding=\"utf-8\"" ) );
190 std::function < void ( QDomElement &,
const QString & ) > appendFormat = [&doc]( QDomElement & elem,
const QString & format )
192 QDomElement formatElem = doc.createElement( QStringLiteral(
"Format" ) );
193 formatElem.appendChild( doc.createTextNode( format ) );
194 elem.appendChild( formatElem );
199 doc = QDomDocument( QStringLiteral(
"WMT_MS_Capabilities SYSTEM 'http://schemas.opengis.net/wms/1.1.1/WMS_MS_Capabilities.dtd'" ) );
200 doc.appendChild( xmlDeclaration );
201 wmsCapabilitiesElement = doc.createElement( QStringLiteral(
"WMT_MS_Capabilities" ) );
205 doc.appendChild( xmlDeclaration );
206 wmsCapabilitiesElement = doc.createElement( QStringLiteral(
"WMS_Capabilities" ) );
207 wmsCapabilitiesElement.setAttribute( QStringLiteral(
"xmlns" ), QStringLiteral(
"http://www.opengis.net/wms" ) );
208 wmsCapabilitiesElement.setAttribute( QStringLiteral(
"xmlns:sld" ), QStringLiteral(
"http://www.opengis.net/sld" ) );
209 wmsCapabilitiesElement.setAttribute( QStringLiteral(
"xmlns:qgs" ), QStringLiteral(
"http://www.qgis.org/wms" ) );
210 wmsCapabilitiesElement.setAttribute( QStringLiteral(
"xmlns:xsi" ), QStringLiteral(
"http://www.w3.org/2001/XMLSchema-instance" ) );
211 QString schemaLocation = QStringLiteral(
"http://www.opengis.net/wms" );
212 schemaLocation += QLatin1String(
" http://schemas.opengis.net/wms/1.3.0/capabilities_1_3_0.xsd" );
213 schemaLocation += QLatin1String(
" http://www.opengis.net/sld" );
214 schemaLocation += QLatin1String(
" http://schemas.opengis.net/sld/1.1.0/sld_capabilities.xsd" );
218 wmsCapabilitiesElement.setAttribute( QStringLiteral(
"xmlns:inspire_common" ), QStringLiteral(
"http://inspire.ec.europa.eu/schemas/common/1.0" ) );
219 wmsCapabilitiesElement.setAttribute( QStringLiteral(
"xmlns:inspire_vs" ), QStringLiteral(
"http://inspire.ec.europa.eu/schemas/inspire_vs/1.0" ) );
220 schemaLocation += QLatin1String(
" http://inspire.ec.europa.eu/schemas/inspire_vs/1.0" );
221 schemaLocation += QLatin1String(
" http://inspire.ec.europa.eu/schemas/inspire_vs/1.0/inspire_vs.xsd" );
224 schemaLocation += QLatin1String(
" http://www.qgis.org/wms" );
225 schemaLocation +=
" " + hrefString +
"SERVICE=WMS&REQUEST=GetSchemaExtension";
227 wmsCapabilitiesElement.setAttribute( QStringLiteral(
"xsi:schemaLocation" ), schemaLocation );
229 wmsCapabilitiesElement.setAttribute( QStringLiteral(
"version" ), request.
wmsParameters().
version() );
230 doc.appendChild( wmsCapabilitiesElement );
236 QDomElement capabilityElement =
getCapabilityElement( doc, project, request, projectSettings, serverIface );
237 wmsCapabilitiesElement.appendChild( capabilityElement );
239 if ( projectSettings )
248 capabilityElement.appendChild(
252 if ( projectSettings )
254 appendDrawingOrder( doc, capabilityElement, serverIface, project );
264 QDomElement serviceElem = doc.createElement( QStringLiteral(
"Service" ) );
267 QDomElement nameElem = doc.createElement( QStringLiteral(
"Name" ) );
268 QDomText nameText = doc.createTextNode( QStringLiteral(
"WMS" ) );
269 nameElem.appendChild( nameText );
270 serviceElem.appendChild( nameElem );
273 QDomElement titleElem = doc.createElement( QStringLiteral(
"Title" ) );
275 titleElem.appendChild( titleText );
276 serviceElem.appendChild( titleElem );
279 if ( !abstract.isEmpty() )
281 QDomElement abstractElem = doc.createElement( QStringLiteral(
"Abstract" ) );
282 QDomText abstractText = doc.createCDATASection( abstract );
283 abstractElem.appendChild( abstractText );
284 serviceElem.appendChild( abstractElem );
287 addKeywordListElement( project, doc, serviceElem );
290 if ( onlineResource.isEmpty() )
292 onlineResource =
serviceUrl( request, project, *serverSettings ).toString();
294 QDomElement onlineResourceElem = doc.createElement( QStringLiteral(
"OnlineResource" ) );
295 onlineResourceElem.setAttribute( QStringLiteral(
"xmlns:xlink" ), QStringLiteral(
"http://www.w3.org/1999/xlink" ) );
296 onlineResourceElem.setAttribute( QStringLiteral(
"xlink:type" ), QStringLiteral(
"simple" ) );
297 onlineResourceElem.setAttribute( QStringLiteral(
"xlink:href" ), onlineResource );
298 serviceElem.appendChild( onlineResourceElem );
305 if ( !contactPerson.isEmpty() ||
306 !contactOrganization.isEmpty() ||
307 !contactPosition.isEmpty() ||
308 !contactMail.isEmpty() ||
309 !contactPhone.isEmpty() )
312 QDomElement contactInfoElem = doc.createElement( QStringLiteral(
"ContactInformation" ) );
315 if ( !contactPerson.isEmpty() ||
316 !contactOrganization.isEmpty() )
318 QDomElement contactPersonPrimaryElem = doc.createElement( QStringLiteral(
"ContactPersonPrimary" ) );
320 QDomText contactPersonText;
321 if ( !contactPerson.isEmpty() )
323 contactPersonText = doc.createTextNode( contactPerson );
327 contactPersonText = doc.createTextNode( QStringLiteral(
"unknown" ) );
329 QDomElement contactPersonElem = doc.createElement( QStringLiteral(
"ContactPerson" ) );
330 contactPersonElem.appendChild( contactPersonText );
331 contactPersonPrimaryElem.appendChild( contactPersonElem );
333 QDomText contactOrganizationText;
334 if ( !contactOrganization.isEmpty() )
336 contactOrganizationText = doc.createTextNode( contactOrganization );
340 contactOrganizationText = doc.createTextNode( QStringLiteral(
"unknown" ) );
342 QDomElement contactOrganizationElem = doc.createElement( QStringLiteral(
"ContactOrganization" ) );
343 contactOrganizationElem.appendChild( contactOrganizationText );
344 contactPersonPrimaryElem.appendChild( contactOrganizationElem );
346 contactInfoElem.appendChild( contactPersonPrimaryElem );
349 if ( !contactPosition.isEmpty() )
351 QDomElement contactPositionElem = doc.createElement( QStringLiteral(
"ContactPosition" ) );
352 QDomText contactPositionText = doc.createTextNode( contactPosition );
353 contactPositionElem.appendChild( contactPositionText );
354 contactInfoElem.appendChild( contactPositionElem );
357 if ( !contactPhone.isEmpty() )
359 QDomElement phoneElem = doc.createElement( QStringLiteral(
"ContactVoiceTelephone" ) );
360 QDomText phoneText = doc.createTextNode( contactPhone );
361 phoneElem.appendChild( phoneText );
362 contactInfoElem.appendChild( phoneElem );
365 if ( !contactMail.isEmpty() )
367 QDomElement mailElem = doc.createElement( QStringLiteral(
"ContactElectronicMailAddress" ) );
368 QDomText mailText = doc.createTextNode( contactMail );
369 mailElem.appendChild( mailText );
370 contactInfoElem.appendChild( mailElem );
373 serviceElem.appendChild( contactInfoElem );
376 QDomElement feesElem = doc.createElement( QStringLiteral(
"Fees" ) );
377 QDomText feesText = doc.createTextNode( QStringLiteral(
"None" ) );
379 if ( !fees.isEmpty() )
381 feesText = doc.createTextNode( fees );
383 feesElem.appendChild( feesText );
384 serviceElem.appendChild( feesElem );
386 QDomElement accessConstraintsElem = doc.createElement( QStringLiteral(
"AccessConstraints" ) );
387 QDomText accessConstraintsText = doc.createTextNode( QStringLiteral(
"None" ) );
389 if ( !accessConstraints.isEmpty() )
391 accessConstraintsText = doc.createTextNode( accessConstraints );
393 accessConstraintsElem.appendChild( accessConstraintsText );
394 serviceElem.appendChild( accessConstraintsElem );
401 QDomElement maxWidthElem = doc.createElement( QStringLiteral(
"MaxWidth" ) );
402 QDomText maxWidthText = doc.createTextNode( QString::number( maxWidth ) );
403 maxWidthElem.appendChild( maxWidthText );
404 serviceElem.appendChild( maxWidthElem );
410 QDomElement maxHeightElem = doc.createElement( QStringLiteral(
"MaxHeight" ) );
411 QDomText maxHeightText = doc.createTextNode( QString::number( maxHeight ) );
412 maxHeightElem.appendChild( maxHeightText );
413 serviceElem.appendChild( maxHeightElem );
430 QString hrefString = href.toString();
431 hrefString.append( href.hasQuery() ?
"&" :
"?" );
433 QDomElement capabilityElem = doc.createElement( QStringLiteral(
"Capability" ) );
436 QDomElement requestElem = doc.createElement( QStringLiteral(
"Request" ) );
437 capabilityElem.appendChild( requestElem );
439 QDomElement dcpTypeElem = doc.createElement( QStringLiteral(
"DCPType" ) );
440 QDomElement httpElem = doc.createElement( QStringLiteral(
"HTTP" ) );
441 dcpTypeElem.appendChild( httpElem );
444 std::function < void ( QDomElement &,
const QString & ) > appendFormat = [&doc]( QDomElement & elem,
const QString & format )
446 QDomElement formatElem = doc.createElement( QStringLiteral(
"Format" ) );
447 formatElem.appendChild( doc.createTextNode( format ) );
448 elem.appendChild( formatElem );
454 elem = doc.createElement( QStringLiteral(
"GetCapabilities" ) );
455 appendFormat( elem, ( version == QLatin1String(
"1.1.1" ) ?
"application/vnd.ogc.wms_xml" :
"text/xml" ) );
456 elem.appendChild( dcpTypeElem );
457 requestElem.appendChild( elem );
460 QDomElement getElem = doc.createElement( QStringLiteral(
"Get" ) );
461 httpElem.appendChild( getElem );
462 QDomElement olResourceElem = doc.createElement( QStringLiteral(
"OnlineResource" ) );
463 olResourceElem.setAttribute( QStringLiteral(
"xmlns:xlink" ), QStringLiteral(
"http://www.w3.org/1999/xlink" ) );
464 olResourceElem.setAttribute( QStringLiteral(
"xlink:type" ), QStringLiteral(
"simple" ) );
465 olResourceElem.setAttribute( QStringLiteral(
"xlink:href" ), hrefString );
466 getElem.appendChild( olResourceElem );
469 elem = doc.createElement( QStringLiteral(
"GetMap" ) );
470 appendFormat( elem, QStringLiteral(
"image/jpeg" ) );
471 appendFormat( elem, QStringLiteral(
"image/png" ) );
472 appendFormat( elem, QStringLiteral(
"image/png; mode=16bit" ) );
473 appendFormat( elem, QStringLiteral(
"image/png; mode=8bit" ) );
474 appendFormat( elem, QStringLiteral(
"image/png; mode=1bit" ) );
475 appendFormat( elem, QStringLiteral(
"application/dxf" ) );
476 elem.appendChild( dcpTypeElem.cloneNode().toElement() );
477 requestElem.appendChild( elem );
480 elem = doc.createElement( QStringLiteral(
"GetFeatureInfo" ) );
481 appendFormat( elem, QStringLiteral(
"text/plain" ) );
482 appendFormat( elem, QStringLiteral(
"text/html" ) );
483 appendFormat( elem, QStringLiteral(
"text/xml" ) );
484 appendFormat( elem, QStringLiteral(
"application/vnd.ogc.gml" ) );
485 appendFormat( elem, QStringLiteral(
"application/vnd.ogc.gml/3.1.1" ) );
486 appendFormat( elem, QStringLiteral(
"application/json" ) );
487 appendFormat( elem, QStringLiteral(
"application/geo+json" ) );
488 elem.appendChild( dcpTypeElem.cloneNode().toElement() );
489 requestElem.appendChild( elem );
492 elem = doc.createElement( ( version == QLatin1String(
"1.1.1" ) ?
"GetLegendGraphic" :
"sld:GetLegendGraphic" ) );
493 appendFormat( elem, QStringLiteral(
"image/jpeg" ) );
494 appendFormat( elem, QStringLiteral(
"image/png" ) );
495 appendFormat( elem, QStringLiteral(
"application/json" ) );
496 elem.appendChild( dcpTypeElem.cloneNode().toElement() );
497 requestElem.appendChild( elem );
500 elem = doc.createElement( ( version == QLatin1String(
"1.1.1" ) ?
"DescribeLayer" :
"sld:DescribeLayer" ) );
501 appendFormat( elem, QStringLiteral(
"text/xml" ) );
502 elem.appendChild( dcpTypeElem.cloneNode().toElement() );
503 requestElem.appendChild( elem );
506 elem = doc.createElement( ( version == QLatin1String(
"1.1.1" ) ?
"GetStyles" :
"qgs:GetStyles" ) );
507 appendFormat( elem, QStringLiteral(
"text/xml" ) );
508 elem.appendChild( dcpTypeElem.cloneNode().toElement() );
509 requestElem.appendChild( elem );
515 elem = doc.createElement( QStringLiteral(
"GetPrint" ) );
516 appendFormat( elem, QStringLiteral(
"svg" ) );
517 appendFormat( elem, QStringLiteral(
"png" ) );
518 appendFormat( elem, QStringLiteral(
"pdf" ) );
519 elem.appendChild( dcpTypeElem.cloneNode().toElement() );
520 requestElem.appendChild( elem );
524 elem = doc.createElement( QStringLiteral(
"Exception" ) );
525 appendFormat( elem, ( version == QLatin1String(
"1.1.1" ) ?
"application/vnd.ogc.se_xml" :
"XML" ) );
526 capabilityElem.appendChild( elem );
529 if ( version == QLatin1String(
"1.3.0" ) )
531 elem = doc.createElement( QStringLiteral(
"sld:UserDefinedSymbolization" ) );
532 elem.setAttribute( QStringLiteral(
"SupportSLD" ), QStringLiteral(
"1" ) );
533 elem.setAttribute( QStringLiteral(
"UserLayer" ), QStringLiteral(
"0" ) );
534 elem.setAttribute( QStringLiteral(
"UserStyle" ), QStringLiteral(
"1" ) );
535 elem.setAttribute( QStringLiteral(
"RemoteWFS" ), QStringLiteral(
"0" ) );
536 elem.setAttribute( QStringLiteral(
"InlineFeature" ), QStringLiteral(
"0" ) );
537 elem.setAttribute( QStringLiteral(
"RemoteWCS" ), QStringLiteral(
"0" ) );
538 capabilityElem.appendChild( elem );
546 return capabilityElem;
551 QDomElement inspireCapabilitiesElem;
554 return inspireCapabilitiesElem;
556 inspireCapabilitiesElem = doc.createElement( QStringLiteral(
"inspire_vs:ExtendedCapabilities" ) );
560 if ( !inspireMetadataUrl.isEmpty() )
562 QDomElement inspireCommonMetadataUrlElem = doc.createElement( QStringLiteral(
"inspire_common:MetadataUrl" ) );
563 inspireCommonMetadataUrlElem.setAttribute( QStringLiteral(
"xsi:type" ), QStringLiteral(
"inspire_common:resourceLocatorType" ) );
565 QDomElement inspireCommonMetadataUrlUrlElem = doc.createElement( QStringLiteral(
"inspire_common:URL" ) );
566 inspireCommonMetadataUrlUrlElem.appendChild( doc.createTextNode( inspireMetadataUrl ) );
567 inspireCommonMetadataUrlElem.appendChild( inspireCommonMetadataUrlUrlElem );
570 if ( !inspireMetadataUrlType.isNull() )
572 QDomElement inspireCommonMetadataUrlMediaTypeElem = doc.createElement( QStringLiteral(
"inspire_common:MediaType" ) );
573 inspireCommonMetadataUrlMediaTypeElem.appendChild( doc.createTextNode( inspireMetadataUrlType ) );
574 inspireCommonMetadataUrlElem.appendChild( inspireCommonMetadataUrlMediaTypeElem );
577 inspireCapabilitiesElem.appendChild( inspireCommonMetadataUrlElem );
581 QDomElement inspireCommonResourceTypeElem = doc.createElement( QStringLiteral(
"inspire_common:ResourceType" ) );
582 inspireCommonResourceTypeElem.appendChild( doc.createTextNode( QStringLiteral(
"service" ) ) );
583 inspireCapabilitiesElem.appendChild( inspireCommonResourceTypeElem );
585 QDomElement inspireCommonSpatialDataServiceTypeElem = doc.createElement( QStringLiteral(
"inspire_common:SpatialDataServiceType" ) );
586 inspireCommonSpatialDataServiceTypeElem.appendChild( doc.createTextNode( QStringLiteral(
"view" ) ) );
587 inspireCapabilitiesElem.appendChild( inspireCommonSpatialDataServiceTypeElem );
590 if ( !inspireTemporalReference.isNull() )
592 QDomElement inspireCommonTemporalReferenceElem = doc.createElement( QStringLiteral(
"inspire_common:TemporalReference" ) );
593 QDomElement inspireCommonDateOfLastRevisionElem = doc.createElement( QStringLiteral(
"inspire_common:DateOfLastRevision" ) );
594 inspireCommonDateOfLastRevisionElem.appendChild( doc.createTextNode( inspireTemporalReference ) );
595 inspireCommonTemporalReferenceElem.appendChild( inspireCommonDateOfLastRevisionElem );
596 inspireCapabilitiesElem.appendChild( inspireCommonTemporalReferenceElem );
599 QDomElement inspireCommonMetadataPointOfContactElem = doc.createElement( QStringLiteral(
"inspire_common:MetadataPointOfContact" ) );
602 QDomElement inspireCommonOrganisationNameElem = doc.createElement( QStringLiteral(
"inspire_common:OrganisationName" ) );
603 if ( !contactOrganization.isNull() )
605 inspireCommonOrganisationNameElem.appendChild( doc.createTextNode( contactOrganization ) );
607 inspireCommonMetadataPointOfContactElem.appendChild( inspireCommonOrganisationNameElem );
610 QDomElement inspireCommonEmailAddressElem = doc.createElement( QStringLiteral(
"inspire_common:EmailAddress" ) );
611 if ( !contactMail.isNull() )
613 inspireCommonEmailAddressElem.appendChild( doc.createTextNode( contactMail ) );
615 inspireCommonMetadataPointOfContactElem.appendChild( inspireCommonEmailAddressElem );
617 inspireCapabilitiesElem.appendChild( inspireCommonMetadataPointOfContactElem );
620 if ( !inspireMetadataDate.isNull() )
622 QDomElement inspireCommonMetadataDateElem = doc.createElement( QStringLiteral(
"inspire_common:MetadataDate" ) );
623 inspireCommonMetadataDateElem.appendChild( doc.createTextNode( inspireMetadataDate ) );
624 inspireCapabilitiesElem.appendChild( inspireCommonMetadataDateElem );
629 QDomElement inspireCommonSupportedLanguagesElem = doc.createElement( QStringLiteral(
"inspire_common:SupportedLanguages" ) );
630 inspireCommonSupportedLanguagesElem.setAttribute( QStringLiteral(
"xsi:type" ), QStringLiteral(
"inspire_common:supportedLanguagesType" ) );
632 QDomElement inspireCommonLanguageElem = doc.createElement( QStringLiteral(
"inspire_common:Language" ) );
635 QDomElement inspireCommonDefaultLanguageElem = doc.createElement( QStringLiteral(
"inspire_common:DefaultLanguage" ) );
636 inspireCommonDefaultLanguageElem.appendChild( inspireCommonLanguageElem );
637 inspireCommonSupportedLanguagesElem.appendChild( inspireCommonDefaultLanguageElem );
641 QDomElement inspireCommonSupportedLanguageElem = doc.createElement(
"inspire_common:SupportedLanguage" );
642 inspireCommonSupportedLanguageElem.appendChild( inspireCommonLanguageElem.cloneNode().toElement() );
643 inspireCommonSupportedLanguagesElem.appendChild( inspireCommonSupportedLanguageElem );
646 inspireCapabilitiesElem.appendChild( inspireCommonSupportedLanguagesElem );
648 QDomElement inspireCommonResponseLanguageElem = doc.createElement( QStringLiteral(
"inspire_common:ResponseLanguage" ) );
649 inspireCommonResponseLanguageElem.appendChild( inspireCommonLanguageElem.cloneNode().toElement() );
650 inspireCapabilitiesElem.appendChild( inspireCommonResponseLanguageElem );
652 return inspireCapabilitiesElem;
658 if ( projectComposers.size() == 0 )
659 return QDomElement();
663 QDomElement composerTemplatesElem = doc.createElement( QStringLiteral(
"ComposerTemplates" ) );
664 QList<QgsPrintLayout *>::const_iterator cIt = projectComposers.constBegin();
665 for ( ; cIt != projectComposers.constEnd(); ++cIt )
668 if ( restrictedComposers.contains( layout->
name() ) )
680 QDomElement composerTemplateElem = doc.createElement( QStringLiteral(
"ComposerTemplate" ) );
681 composerTemplateElem.setAttribute( QStringLiteral(
"name" ), layout->
name() );
684 composerTemplateElem.setAttribute( QStringLiteral(
"width" ), width.
length() );
685 composerTemplateElem.setAttribute( QStringLiteral(
"height" ), height.
length() );
689 if ( atlas && atlas->
enabled() )
691 composerTemplateElem.setAttribute( QStringLiteral(
"atlasEnabled" ), QStringLiteral(
"1" ) );
698 layerName = cLayer->
id();
700 else if ( layerName.isEmpty() )
702 layerName = cLayer->
name();
704 composerTemplateElem.setAttribute( QStringLiteral(
"atlasCoverageLayer" ), layerName );
709 QList<QgsLayoutItemMap *> layoutMapList;
711 QList<QgsLayoutItemMap *>::const_iterator cmIt = layoutMapList.constBegin();
714 for ( ; cmIt != layoutMapList.constEnd(); ++cmIt )
718 QDomElement composerMapElem = doc.createElement( QStringLiteral(
"ComposerMap" ) );
719 composerMapElem.setAttribute( QStringLiteral(
"name" ), QStringLiteral(
"map%1" ).arg( mapId ) );
720 composerMapElem.setAttribute( QStringLiteral(
"itemName" ), composerMap->
displayName() );
722 composerMapElem.setAttribute( QStringLiteral(
"width" ), composerMap->rect().width() );
723 composerMapElem.setAttribute( QStringLiteral(
"height" ), composerMap->rect().height() );
724 composerTemplateElem.appendChild( composerMapElem );
728 QList<QgsLayoutItemLabel *> composerLabelList;
730 QList<QgsLayoutItemLabel *>::const_iterator clIt = composerLabelList.constBegin();
731 for ( ; clIt != composerLabelList.constEnd(); ++clIt )
734 QString
id = composerLabel->
id();
738 QDomElement composerLabelElem = doc.createElement( QStringLiteral(
"ComposerLabel" ) );
739 composerLabelElem.setAttribute( QStringLiteral(
"name" ), id );
740 composerTemplateElem.appendChild( composerLabelElem );
744 QList<QgsLayoutItemHtml *> composerHtmlList;
746 QList<QgsLayoutItemHtml *>::const_iterator chIt = composerHtmlList.constBegin();
747 for ( ; chIt != composerHtmlList.constEnd(); ++chIt )
753 QString
id = composerHtml->
frame( 0 )->
id();
757 QDomElement composerHtmlElem = doc.createElement( QStringLiteral(
"ComposerHtml" ) );
758 composerHtmlElem.setAttribute( QStringLiteral(
"name" ), id );
759 composerTemplateElem.appendChild( composerHtmlElem );
762 composerTemplatesElem.appendChild( composerTemplateElem );
765 if ( composerTemplatesElem.childNodes().size() == 0 )
766 return QDomElement();
768 return composerTemplatesElem;
775 return QDomElement();
777 QDomElement wfsLayersElem = doc.createElement( QStringLiteral(
"WFSLayers" ) );
786 QDomElement wfsLayerElem = doc.createElement( QStringLiteral(
"WFSLayer" ) );
789 wfsLayerElem.setAttribute( QStringLiteral(
"name" ), layer->
id() );
793 wfsLayerElem.setAttribute( QStringLiteral(
"name" ), layer->
name() );
795 wfsLayersElem.appendChild( wfsLayerElem );
798 return wfsLayersElem;
807 QDomElement layerParentElem = doc.createElement( QStringLiteral(
"Layer" ) );
811 if ( rootLayerName.isEmpty() && !project->
title().isEmpty() )
813 rootLayerName = project->
title();
816 if ( !rootLayerName.isEmpty() )
818 QDomElement layerParentNameElem = doc.createElement( QStringLiteral(
"Name" ) );
819 QDomText layerParentNameText = doc.createTextNode( rootLayerName );
820 layerParentNameElem.appendChild( layerParentNameText );
821 layerParentElem.appendChild( layerParentNameElem );
825 QDomElement layerParentTitleElem = doc.createElement( QStringLiteral(
"Title" ) );
827 layerParentTitleElem.appendChild( layerParentTitleText );
828 layerParentElem.appendChild( layerParentTitleElem );
832 if ( !rootLayerAbstract.isEmpty() )
834 QDomElement layerParentAbstElem = doc.createElement( QStringLiteral(
"Abstract" ) );
835 QDomText layerParentAbstText = doc.createCDATASection( rootLayerAbstract );
836 layerParentAbstElem.appendChild( layerParentAbstText );
837 layerParentElem.appendChild( layerParentAbstElem );
841 addKeywordListElement( project, doc, layerParentElem );
844 if ( projectSettings )
846 QDomElement treeNameElem = doc.createElement( QStringLiteral(
"TreeName" ) );
847 QDomText treeNameText = doc.createTextNode( project->
title() );
848 treeNameElem.appendChild( treeNameText );
849 layerParentElem.appendChild( treeNameElem );
854 layerParentElem.setAttribute( QStringLiteral(
"queryable" ), QStringLiteral(
"1" ) );
858 layerParentElem.setAttribute( QStringLiteral(
"queryable" ), QStringLiteral(
"0" ) );
861 appendLayersFromTreeGroup( doc, layerParentElem, serverIface, project, request, projectLayerTreeRoot, projectSettings );
863 combineExtentAndCrsOfGroupChildren( doc, layerParentElem, project,
true );
865 return layerParentElem;
871 void appendLayersFromTreeGroup( QDomDocument &doc,
872 QDomElement &parentLayer,
875 const QgsWmsRequest &request,
877 bool projectSettings )
879 const QString version = request.wmsParameters().version();
885 QList< QgsLayerTreeNode * > layerTreeGroupChildren = layerTreeGroup->
children();
886 for (
int i = 0; i < layerTreeGroupChildren.size(); ++i )
889 QDomElement layerElem = doc.createElement( QStringLiteral(
"Layer" ) );
891 if ( projectSettings )
893 layerElem.setAttribute( QStringLiteral(
"visible" ), treeNode->
isVisible() );
895 layerElem.setAttribute( QStringLiteral(
"expanded" ), treeNode->
isExpanded() );
902 QString name = treeGroupChild->
name();
903 if ( restrictedLayers.contains( name ) )
908 if ( projectSettings )
910 layerElem.setAttribute( QStringLiteral(
"mutuallyExclusive" ), treeGroupChild->
isMutuallyExclusive() );
913 QString shortName = treeGroupChild->
customProperty( QStringLiteral(
"wmsShortName" ) ).toString();
914 QString title = treeGroupChild->
customProperty( QStringLiteral(
"wmsTitle" ) ).toString();
916 QDomElement nameElem = doc.createElement( QStringLiteral(
"Name" ) );
918 if ( !shortName.isEmpty() )
919 nameText = doc.createTextNode( shortName );
921 nameText = doc.createTextNode( name );
922 nameElem.appendChild( nameText );
923 layerElem.appendChild( nameElem );
925 QDomElement titleElem = doc.createElement( QStringLiteral(
"Title" ) );
927 if ( !title.isEmpty() )
928 titleText = doc.createTextNode( title );
930 titleText = doc.createTextNode( name );
931 titleElem.appendChild( titleText );
932 layerElem.appendChild( titleElem );
934 QString abstract = treeGroupChild->
customProperty( QStringLiteral(
"wmsAbstract" ) ).toString();
935 if ( !abstract.isEmpty() )
937 QDomElement abstractElem = doc.createElement( QStringLiteral(
"Abstract" ) );
938 QDomText abstractText = doc.createTextNode( abstract );
939 abstractElem.appendChild( abstractText );
940 layerElem.appendChild( abstractElem );
944 if ( projectSettings )
946 QDomElement treeNameElem = doc.createElement( QStringLiteral(
"TreeName" ) );
947 QDomText treeNameText = doc.createTextNode( name );
948 treeNameElem.appendChild( treeNameText );
949 layerElem.appendChild( treeNameElem );
955 layerElem.setAttribute( QStringLiteral(
"queryable" ), QStringLiteral(
"1" ) );
959 layerElem.setAttribute( QStringLiteral(
"queryable" ), QStringLiteral(
"0" ) );
962 appendLayersFromTreeGroup( doc, layerElem, serverIface, project, request, treeGroupChild, projectSettings );
964 combineExtentAndCrsOfGroupChildren( doc, layerElem, project );
970 if ( !l || restrictedLayers.contains( l->
name() ) )
975#ifdef HAVE_SERVER_PYTHON_PLUGINS
982 QString wmsName = l->
name();
995 layerElem.setAttribute( QStringLiteral(
"queryable" ), QStringLiteral(
"0" ) );
999 layerElem.setAttribute( QStringLiteral(
"queryable" ), QStringLiteral(
"1" ) );
1002 QDomElement nameElem = doc.createElement( QStringLiteral(
"Name" ) );
1003 QDomText nameText = doc.createTextNode( wmsName );
1004 nameElem.appendChild( nameText );
1005 layerElem.appendChild( nameElem );
1007 QDomElement titleElem = doc.createElement( QStringLiteral(
"Title" ) );
1008 QString title = l->
title();
1009 if ( title.isEmpty() )
1013 QDomText titleText = doc.createTextNode( title );
1014 titleElem.appendChild( titleText );
1015 layerElem.appendChild( titleElem );
1018 if ( !abstract.isEmpty() )
1020 QDomElement abstractElem = doc.createElement( QStringLiteral(
"Abstract" ) );
1021 QDomText abstractText = doc.createTextNode( abstract );
1022 abstractElem.appendChild( abstractText );
1023 layerElem.appendChild( abstractElem );
1029 QStringList keywordStringList = l->
keywordList().split(
',' );
1031 QDomElement keywordListElem = doc.createElement( QStringLiteral(
"KeywordList" ) );
1032 for (
int i = 0; i < keywordStringList.size(); ++i )
1034 QDomElement keywordElem = doc.createElement( QStringLiteral(
"Keyword" ) );
1035 QDomText keywordText = doc.createTextNode( keywordStringList.at( i ).trimmed() );
1036 keywordElem.appendChild( keywordText );
1039 keywordElem.setAttribute( QStringLiteral(
"vocabulary" ), QStringLiteral(
"SIA_Geo405" ) );
1041 keywordListElem.appendChild( keywordElem );
1043 layerElem.appendChild( keywordListElem );
1047 bool geometryLayer =
true;
1055 geometryLayer =
false;
1061 if ( geometryLayer )
1063 QStringList crsList;
1066 appendCrsElementsToLayer( doc, layerElem, crsList, outputCrsList );
1081 else if ( l->
crs() != project->
crs() )
1087 extent = ct.transform( extent );
1091 QgsMessageLog::logMessage( QStringLiteral(
"Error transforming extent for layer %1: %2" ).arg( l->
name() ).arg( cse.
what() ), QStringLiteral(
"Server" ), Qgis::MessageLevel::Warning );
1102 appendLayerBoundingBoxes( doc, layerElem, extent, l->
crs(), crsList, outputCrsList, project, wgs84Extent );
1106 appendLayerStyles( doc, layerElem, l, project, request, serverIface->
serverSettings() );
1111 if ( version == QLatin1String(
"1.1.1" ) )
1114 double SCALE_TO_SCALEHINT =
OGC_PX_M * M_SQRT2;
1116 QDomElement scaleHintElem = doc.createElement( QStringLiteral(
"ScaleHint" ) );
1117 scaleHintElem.setAttribute( QStringLiteral(
"min" ), QString::number( l->
maximumScale() * SCALE_TO_SCALEHINT ) );
1118 scaleHintElem.setAttribute( QStringLiteral(
"max" ), QString::number( l->
minimumScale() * SCALE_TO_SCALEHINT ) );
1119 layerElem.appendChild( scaleHintElem );
1123 QString minScaleString = QString::number( l->
maximumScale() );
1124 QDomElement minScaleElem = doc.createElement( QStringLiteral(
"MinScaleDenominator" ) );
1125 QDomText minScaleText = doc.createTextNode( minScaleString );
1126 minScaleElem.appendChild( minScaleText );
1127 layerElem.appendChild( minScaleElem );
1129 QString maxScaleString = QString::number( l->
minimumScale() );
1130 QDomElement maxScaleElem = doc.createElement( QStringLiteral(
"MaxScaleDenominator" ) );
1131 QDomText maxScaleText = doc.createTextNode( maxScaleString );
1132 maxScaleElem.appendChild( maxScaleText );
1133 layerElem.appendChild( maxScaleElem );
1138 QString dataUrl = l->
dataUrl();
1139 if ( !dataUrl.isEmpty() )
1141 QDomElement dataUrlElem = doc.createElement( QStringLiteral(
"DataURL" ) );
1142 QDomElement dataUrlFormatElem = doc.createElement( QStringLiteral(
"Format" ) );
1144 QDomText dataUrlFormatText = doc.createTextNode( dataUrlFormat );
1145 dataUrlFormatElem.appendChild( dataUrlFormatText );
1146 dataUrlElem.appendChild( dataUrlFormatElem );
1147 QDomElement dataORElem = doc.createElement( QStringLiteral(
"OnlineResource" ) );
1148 dataORElem.setAttribute( QStringLiteral(
"xmlns:xlink" ), QStringLiteral(
"http://www.w3.org/1999/xlink" ) );
1149 dataORElem.setAttribute( QStringLiteral(
"xlink:type" ), QStringLiteral(
"simple" ) );
1150 dataORElem.setAttribute( QStringLiteral(
"xlink:href" ), dataUrl );
1151 dataUrlElem.appendChild( dataORElem );
1152 layerElem.appendChild( dataUrlElem );
1157 if ( !attribution.isEmpty() )
1159 QDomElement attribElem = doc.createElement( QStringLiteral(
"Attribution" ) );
1160 QDomElement attribTitleElem = doc.createElement( QStringLiteral(
"Title" ) );
1161 QDomText attribText = doc.createTextNode( attribution );
1162 attribTitleElem.appendChild( attribText );
1163 attribElem.appendChild( attribTitleElem );
1165 if ( !attributionUrl.isEmpty() )
1167 QDomElement attribORElem = doc.createElement( QStringLiteral(
"OnlineResource" ) );
1168 attribORElem.setAttribute( QStringLiteral(
"xmlns:xlink" ), QStringLiteral(
"http://www.w3.org/1999/xlink" ) );
1169 attribORElem.setAttribute( QStringLiteral(
"xlink:type" ), QStringLiteral(
"simple" ) );
1170 attribORElem.setAttribute( QStringLiteral(
"xlink:href" ), attributionUrl );
1171 attribElem.appendChild( attribORElem );
1173 layerElem.appendChild( attribElem );
1180 QDomElement metaUrlElem = doc.createElement( QStringLiteral(
"MetadataURL" ) );
1181 QString metadataUrlType = url.type;
1182 if ( version == QLatin1String(
"1.1.1" ) )
1184 metaUrlElem.setAttribute( QStringLiteral(
"type" ), metadataUrlType );
1186 else if ( metadataUrlType == QLatin1String(
"FGDC" ) )
1188 metaUrlElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"FGDC:1998" ) );
1190 else if ( metadataUrlType == QLatin1String(
"TC211" ) )
1192 metaUrlElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"ISO19115:2003" ) );
1196 metaUrlElem.setAttribute( QStringLiteral(
"type" ), metadataUrlType );
1198 QString metadataUrlFormat = url.format;
1199 if ( !metadataUrlFormat.isEmpty() )
1201 QDomElement metaUrlFormatElem = doc.createElement( QStringLiteral(
"Format" ) );
1202 QDomText metaUrlFormatText = doc.createTextNode( metadataUrlFormat );
1203 metaUrlFormatElem.appendChild( metaUrlFormatText );
1204 metaUrlElem.appendChild( metaUrlFormatElem );
1206 QDomElement metaUrlORElem = doc.createElement( QStringLiteral(
"OnlineResource" ) );
1207 metaUrlORElem.setAttribute( QStringLiteral(
"xmlns:xlink" ), QStringLiteral(
"http://www.w3.org/1999/xlink" ) );
1208 metaUrlORElem.setAttribute( QStringLiteral(
"xlink:type" ), QStringLiteral(
"simple" ) );
1209 metaUrlORElem.setAttribute( QStringLiteral(
"xlink:href" ), url.url );
1210 metaUrlElem.appendChild( metaUrlORElem );
1211 layerElem.appendChild( metaUrlElem );
1214 bool timeDimensionAdded {
false };
1221 const QList<QgsMapLayerServerProperties::WmsDimensionInfo> wmsDims = serverProperties->
wmsDimensions();
1227 if ( fieldIndex == -1 )
1232 QSet<QVariant> uniqueValues = vl->
uniqueValues( fieldIndex );
1235 if ( !dim.endFieldName.isEmpty() )
1237 int endFieldIndex = vl->
fields().
indexOf( dim.endFieldName );
1239 if ( endFieldIndex == -1 )
1243 uniqueValues.unite( vl->
uniqueValues( endFieldIndex ) );
1246 QList<QVariant> values = qgis::setToList( uniqueValues );
1247 std::sort( values.begin(), values.end() );
1249 QDomElement dimElem = doc.createElement( QStringLiteral(
"Dimension" ) );
1250 dimElem.setAttribute( QStringLiteral(
"name" ), dim.name );
1252 if ( dim.name.toUpper() == QLatin1String(
"TIME" ) )
1254 timeDimensionAdded =
true;
1257 if ( !dim.units.isEmpty() )
1259 dimElem.setAttribute( QStringLiteral(
"units" ), dim.units );
1261 if ( !dim.unitSymbol.isEmpty() )
1263 dimElem.setAttribute( QStringLiteral(
"unitSymbol" ), dim.unitSymbol );
1267 dimElem.setAttribute( QStringLiteral(
"default" ), values.first().toString() );
1271 dimElem.setAttribute( QStringLiteral(
"default" ), values.last().toString() );
1275 dimElem.setAttribute( QStringLiteral(
"default" ), dim.referenceValue.toString() );
1277 dimElem.setAttribute( QStringLiteral(
"multipleValues" ), QStringLiteral(
"1" ) );
1278 dimElem.setAttribute( QStringLiteral(
"nearestValue" ), QStringLiteral(
"0" ) );
1279 if ( projectSettings )
1281 dimElem.setAttribute( QStringLiteral(
"fieldName" ), dim.fieldName );
1282 dimElem.setAttribute( QStringLiteral(
"endFieldName" ), dim.endFieldName );
1285 QStringList strValues;
1286 for (
const QVariant &v : values )
1288 strValues << v.toString();
1290 QDomText dimValuesText = doc.createTextNode( strValues.join( QLatin1String(
", " ) ) );
1291 dimElem.appendChild( dimValuesText );
1292 layerElem.appendChild( dimElem );
1297 if ( ! timeDimensionAdded
1302 QDomElement dimElem = doc.createElement( QStringLiteral(
"Dimension" ) );
1303 dimElem.setAttribute( QStringLiteral(
"name" ), QStringLiteral(
"TIME" ) );
1304 dimElem.setAttribute( QStringLiteral(
"units" ), QStringLiteral(
"ISO8601" ) );
1314 bool isDateList {
true };
1315 bool isInstantList {
true };
1317 QList<QDateTime> values;
1318 for (
const auto &r : std::as_const( allRanges ) )
1320 if ( r.isInstant() )
1322 if ( r.begin().time() != QTime( 0, 0, 0, 0 ) )
1326 values.append( r.begin() );
1330 isInstantList =
false;
1337 if ( isInstantList )
1340 QStringList strValues;
1341 for (
const auto &v : values )
1345 strValues << v.date().toString( Qt::DateFormat::ISODate );
1349 strValues << v.toString( Qt::DateFormat::ISODate );
1352 QDomText dimValuesText = doc.createTextNode( strValues.join( QChar(
',' ) ) );
1353 dimElem.appendChild( dimValuesText );
1356 layerElem.appendChild( dimElem );
1358 QDomElement timeExtentElem = doc.createElement( QStringLiteral(
"Extent" ) );
1359 timeExtentElem.setAttribute( QStringLiteral(
"name" ), QStringLiteral(
"TIME" ) );
1365 extent = QStringLiteral(
"%1/%2" ).arg( timeExtent.begin().date().toString( Qt::DateFormat::ISODate ), timeExtent.end().date().toString( Qt::DateFormat::ISODate ) );
1369 extent = QStringLiteral(
"%1/%2" ).arg( timeExtent.begin().toString( Qt::DateFormat::ISODate ), timeExtent.end().toString( Qt::DateFormat::ISODate ) );
1371 QDomText extentValueText = doc.createTextNode( extent );
1372 timeExtentElem.appendChild( extentValueText );
1373 layerElem.appendChild( timeExtentElem );
1377 if ( projectSettings )
1379 appendLayerProjectSettings( doc, layerElem, l );
1383 parentLayer.appendChild( layerElem );
1387 void appendLayerStyles( QDomDocument &doc, QDomElement &layerElem,
QgsMapLayer *currentLayer,
1391 QUrl href =
serviceUrl( request, project, *settings );
1394 QString hrefString = href.toString();
1395 hrefString.append( href.hasQuery() ?
"&" :
"?" );
1398 QDomElement styleElem = doc.createElement( QStringLiteral(
"Style" ) );
1399 QDomElement styleNameElem = doc.createElement( QStringLiteral(
"Name" ) );
1400 QDomText styleNameText = doc.createTextNode( styleName );
1401 styleNameElem.appendChild( styleNameText );
1402 QDomElement styleTitleElem = doc.createElement( QStringLiteral(
"Title" ) );
1403 QDomText styleTitleText = doc.createTextNode( styleName );
1404 styleTitleElem.appendChild( styleTitleText );
1405 styleElem.appendChild( styleNameElem );
1406 styleElem.appendChild( styleTitleElem );
1409 QDomElement getLayerLegendGraphicElem = doc.createElement( QStringLiteral(
"LegendURL" ) );
1411 QString customHrefString = currentLayer->
legendUrl();
1413 QStringList getLayerLegendGraphicFormats;
1414 if ( !customHrefString.isEmpty() )
1420 getLayerLegendGraphicFormats << QStringLiteral(
"image/png" );
1423 for (
int i = 0; i < getLayerLegendGraphicFormats.size(); ++i )
1425 QDomElement getLayerLegendGraphicFormatElem = doc.createElement( QStringLiteral(
"Format" ) );
1426 QString getLayerLegendGraphicFormat = getLayerLegendGraphicFormats[i];
1427 QDomText getLayerLegendGraphicFormatText = doc.createTextNode( getLayerLegendGraphicFormat );
1428 getLayerLegendGraphicFormatElem.appendChild( getLayerLegendGraphicFormatText );
1429 getLayerLegendGraphicElem.appendChild( getLayerLegendGraphicFormatElem );
1433 if ( customHrefString.isEmpty() )
1435 QString layerName = currentLayer->
name();
1437 layerName = currentLayer->
id();
1438 else if ( !currentLayer->
shortName().isEmpty() )
1440 QUrl mapUrl( hrefString );
1441 QUrlQuery mapUrlQuery( mapUrl.query() );
1442 mapUrlQuery.addQueryItem( QStringLiteral(
"SERVICE" ), QStringLiteral(
"WMS" ) );
1443 mapUrlQuery.addQueryItem( QStringLiteral(
"VERSION" ), request.wmsParameters().version() );
1444 mapUrlQuery.addQueryItem( QStringLiteral(
"REQUEST" ), QStringLiteral(
"GetLegendGraphic" ) );
1445 mapUrlQuery.addQueryItem( QStringLiteral(
"LAYER" ), layerName );
1446 mapUrlQuery.addQueryItem( QStringLiteral(
"FORMAT" ), QStringLiteral(
"image/png" ) );
1447 mapUrlQuery.addQueryItem( QStringLiteral(
"STYLE" ), styleNameText.data() );
1448 if ( request.wmsParameters().version() == QLatin1String(
"1.3.0" ) )
1450 mapUrlQuery.addQueryItem( QStringLiteral(
"SLD_VERSION" ), QStringLiteral(
"1.1.0" ) );
1452 mapUrl.setQuery( mapUrlQuery );
1453 customHrefString = mapUrl.toString();
1456 QDomElement getLayerLegendGraphicORElem = doc.createElement( QStringLiteral(
"OnlineResource" ) );
1457 getLayerLegendGraphicORElem.setAttribute( QStringLiteral(
"xmlns:xlink" ), QStringLiteral(
"http://www.w3.org/1999/xlink" ) );
1458 getLayerLegendGraphicORElem.setAttribute( QStringLiteral(
"xlink:type" ), QStringLiteral(
"simple" ) );
1459 getLayerLegendGraphicORElem.setAttribute( QStringLiteral(
"xlink:href" ), customHrefString );
1460 getLayerLegendGraphicElem.appendChild( getLayerLegendGraphicORElem );
1461 styleElem.appendChild( getLayerLegendGraphicElem );
1463 layerElem.appendChild( styleElem );
1467 void appendCrsElementsToLayer( QDomDocument &doc, QDomElement &layerElement,
1468 const QStringList &crsList,
const QStringList &constrainedCrsList )
1470 if ( layerElement.isNull() )
1475 const QString version = doc.documentElement().attribute( QStringLiteral(
"version" ) );
1478 QDomElement titleElement = layerElement.firstChildElement( QStringLiteral(
"Title" ) );
1479 QDomElement abstractElement = layerElement.firstChildElement( QStringLiteral(
"Abstract" ) );
1480 QDomElement keywordListElement = layerElement.firstChildElement( QStringLiteral(
"KeywordList" ) );
1481 QDomElement CRSPrecedingElement = !keywordListElement.isNull() ? keywordListElement : !abstractElement.isNull() ? abstractElement : titleElement;
1483 if ( CRSPrecedingElement.isNull() )
1486 const QDomElement keyElement = layerElement.firstChildElement( QStringLiteral(
"KeywordList" ) );
1487 CRSPrecedingElement = keyElement;
1491 if ( !constrainedCrsList.isEmpty() )
1493 for (
int i = constrainedCrsList.size() - 1; i >= 0; --i )
1495 appendCrsElementToLayer( doc, layerElement, CRSPrecedingElement, constrainedCrsList.at( i ) );
1500 for (
const QString &
crs : crsList )
1502 appendCrsElementToLayer( doc, layerElement, CRSPrecedingElement,
crs );
1508 if ( version == QLatin1String(
"1.3.0" ) )
1510 appendCrsElementToLayer( doc, layerElement, CRSPrecedingElement, QString(
"CRS:84" ) );
1514 void appendCrsElementToLayer( QDomDocument &doc, QDomElement &layerElement,
const QDomElement &precedingElement,
1515 const QString &crsText )
1517 if ( crsText.isEmpty() )
1519 const QString version = doc.documentElement().attribute( QStringLiteral(
"version" ) );
1520 QDomElement crsElement = doc.createElement( version == QLatin1String(
"1.1.1" ) ?
"SRS" :
"CRS" );
1521 QDomText crsTextNode = doc.createTextNode( crsText );
1522 crsElement.appendChild( crsTextNode );
1523 layerElement.insertAfter( crsElement, precedingElement );
1526 void appendLayerBoundingBoxes( QDomDocument &doc, QDomElement &layerElem,
const QgsRectangle &lExtent,
1528 const QStringList &constrainedCrsList,
const QgsProject *project,
1531 if ( layerElem.isNull() )
1540 layerExtent.
grow( 0.000001 );
1544 if ( wgs84BoundingRect.
isNull() )
1549 if ( !layerExtent.
isNull() )
1554 wgs84BoundingRect = exGeoTransform.transformBoundingBox( layerExtent );
1558 QgsMessageLog::logMessage( QStringLiteral(
"Error transforming extent: %1" ).arg( cse.
what() ), QStringLiteral(
"Server" ), Qgis::MessageLevel::Warning );
1567 wgs84BoundingRect.
grow( 0.000001 );
1571 QDomElement ExGeoBBoxElement;
1572 const int wgs84precision = 6;
1573 const QString version = doc.documentElement().attribute( QStringLiteral(
"version" ) );
1574 if ( version == QLatin1String(
"1.1.1" ) )
1576 ExGeoBBoxElement = doc.createElement( QStringLiteral(
"LatLonBoundingBox" ) );
1584 ExGeoBBoxElement = doc.createElement( QStringLiteral(
"EX_GeographicBoundingBox" ) );
1585 QDomElement wBoundLongitudeElement = doc.createElement( QStringLiteral(
"westBoundLongitude" ) );
1587 wBoundLongitudeElement.appendChild( wBoundLongitudeText );
1588 ExGeoBBoxElement.appendChild( wBoundLongitudeElement );
1589 QDomElement eBoundLongitudeElement = doc.createElement( QStringLiteral(
"eastBoundLongitude" ) );
1591 eBoundLongitudeElement.appendChild( eBoundLongitudeText );
1592 ExGeoBBoxElement.appendChild( eBoundLongitudeElement );
1593 QDomElement sBoundLatitudeElement = doc.createElement( QStringLiteral(
"southBoundLatitude" ) );
1595 sBoundLatitudeElement.appendChild( sBoundLatitudeText );
1596 ExGeoBBoxElement.appendChild( sBoundLatitudeElement );
1597 QDomElement nBoundLatitudeElement = doc.createElement( QStringLiteral(
"northBoundLatitude" ) );
1599 nBoundLatitudeElement.appendChild( nBoundLatitudeText );
1600 ExGeoBBoxElement.appendChild( nBoundLatitudeElement );
1603 if ( !wgs84BoundingRect.
isNull() )
1605 QDomElement lastCRSElem = layerElem.lastChildElement( version == QLatin1String(
"1.1.1" ) ?
"SRS" :
"CRS" );
1606 if ( !lastCRSElem.isNull() )
1608 layerElem.insertAfter( ExGeoBBoxElement, lastCRSElem );
1612 layerElem.appendChild( ExGeoBBoxElement );
1617 if ( !constrainedCrsList.isEmpty() )
1619 for (
int i = constrainedCrsList.size() - 1; i >= 0; --i )
1621 appendLayerBoundingBox( doc, layerElem, layerExtent, layerCRS, constrainedCrsList.at( i ), project );
1626 for (
const QString &
crs : crsList )
1628 appendLayerBoundingBox( doc, layerElem, layerExtent, layerCRS,
crs, project );
1634 void appendLayerBoundingBox( QDomDocument &doc, QDomElement &layerElem,
const QgsRectangle &layerExtent,
1638 if ( layerElem.isNull() )
1643 if ( crsText.isEmpty() )
1648 const QString version = doc.documentElement().attribute( QStringLiteral(
"version" ) );
1654 if ( !layerExtent.
isNull() )
1659 crsExtent = crsTransform.transformBoundingBox( layerExtent );
1663 QgsMessageLog::logMessage( QStringLiteral(
"Error transforming extent: %1" ).arg( cse.
what() ), QStringLiteral(
"Server" ), Qgis::MessageLevel::Warning );
1668 if ( crsExtent.
isNull() )
1680 QDomElement bBoxElement = doc.createElement( QStringLiteral(
"BoundingBox" ) );
1683 bBoxElement.setAttribute( version == QLatin1String(
"1.1.1" ) ?
"SRS" :
"CRS",
crs.
authid() );
1696 QDomElement lastBBoxElem = layerElem.lastChildElement( QStringLiteral(
"BoundingBox" ) );
1697 if ( !lastBBoxElem.isNull() )
1699 layerElem.insertAfter( bBoxElement, lastBBoxElem );
1703 lastBBoxElem = layerElem.lastChildElement( version == QLatin1String(
"1.1.1" ) ?
"LatLonBoundingBox" :
"EX_GeographicBoundingBox" );
1704 if ( !lastBBoxElem.isNull() )
1706 layerElem.insertAfter( bBoxElement, lastBBoxElem );
1710 layerElem.appendChild( bBoxElement );
1715 QgsRectangle layerBoundingBoxInProjectCrs(
const QDomDocument &doc,
const QDomElement &layerElem,
1719 if ( layerElem.isNull() )
1725 QDomElement boundingBoxElem = layerElem.firstChildElement( QStringLiteral(
"BoundingBox" ) );
1726 if ( boundingBoxElem.isNull() )
1731 double minx, miny, maxx, maxy;
1733 minx = boundingBoxElem.attribute( QStringLiteral(
"minx" ) ).toDouble( &conversionOk );
1734 if ( !conversionOk )
1738 miny = boundingBoxElem.attribute( QStringLiteral(
"miny" ) ).toDouble( &conversionOk );
1739 if ( !conversionOk )
1743 maxx = boundingBoxElem.attribute( QStringLiteral(
"maxx" ) ).toDouble( &conversionOk );
1744 if ( !conversionOk )
1748 maxy = boundingBoxElem.attribute( QStringLiteral(
"maxy" ) ).toDouble( &conversionOk );
1749 if ( !conversionOk )
1755 const QString version = doc.documentElement().attribute( QStringLiteral(
"version" ) );
1769 if ( version != QLatin1String(
"1.1.1" ) && layerCrs.
hasAxisInverted() )
1780 BBox = t.transformBoundingBox( BBox );
1784 QgsMessageLog::logMessage( QStringLiteral(
"Error transforming extent: %1" ).arg( cse.
what() ), QStringLiteral(
"Server" ), Qgis::MessageLevel::Warning );
1791 bool crsSetFromLayerElement(
const QDomElement &layerElement, QSet<QString> &crsSet )
1793 if ( layerElement.isNull() )
1800 QDomNodeList crsNodeList;
1801 crsNodeList = layerElement.elementsByTagName( QStringLiteral(
"CRS" ) );
1802 for (
int i = 0; i < crsNodeList.size(); ++i )
1804 crsSet.insert( crsNodeList.at( i ).toElement().text() );
1807 crsNodeList = layerElement.elementsByTagName( QStringLiteral(
"SRS" ) );
1808 for (
int i = 0; i < crsNodeList.size(); ++i )
1810 crsSet.insert( crsNodeList.at( i ).toElement().text() );
1816 void combineExtentAndCrsOfGroupChildren( QDomDocument &doc, QDomElement &groupElem,
const QgsProject *project,
1817 bool considerMapExtent )
1820 QSet<QString> combinedCRSSet;
1821 bool firstBBox =
true;
1822 bool firstCRSSet =
true;
1824 QDomNodeList layerChildren = groupElem.childNodes();
1825 for (
int j = 0; j < layerChildren.size(); ++j )
1827 QDomElement childElem = layerChildren.at( j ).toElement();
1829 if ( childElem.tagName() != QLatin1String(
"Layer" ) )
1832 QgsRectangle bbox = layerBoundingBoxInProjectCrs( doc, childElem, project );
1842 combinedBBox = bbox;
1852 QSet<QString> crsSet;
1853 if ( crsSetFromLayerElement( childElem, crsSet ) )
1857 combinedCRSSet = crsSet;
1858 firstCRSSet =
false;
1862 combinedCRSSet.intersect( crsSet );
1868 appendCrsElementsToLayer( doc, groupElem, qgis::setToList( combinedCRSSet ), outputCrsList );
1871 if ( considerMapExtent )
1876 combinedBBox = mapRect;
1879 appendLayerBoundingBoxes( doc, groupElem, combinedBBox, groupCRS, qgis::setToList( combinedCRSSet ), outputCrsList, project );
1883 void appendDrawingOrder( QDomDocument &doc, QDomElement &parentElem,
QgsServerInterface *serverIface,
1886#ifdef HAVE_SERVER_PYTHON_PLUGINS
1889 ( void )serverIface;
1894 QStringList layerList;
1897 QList< QgsMapLayer * > projectLayerOrder = projectLayerTreeRoot->
layerOrder();
1898 for (
int i = 0; i < projectLayerOrder.size(); ++i )
1902 if ( restrictedLayers.contains( l->
name() ) )
1906#ifdef HAVE_SERVER_PYTHON_PLUGINS
1912 QString wmsName = l->
name();
1922 layerList << wmsName;
1925 if ( !layerList.isEmpty() )
1927 QStringList reversedList;
1928 reversedList.reserve( layerList.size() );
1929 for (
int i = layerList.size() - 1; i >= 0; --i )
1930 reversedList << layerList[ i ];
1932 QDomElement layerDrawingOrderElem = doc.createElement( QStringLiteral(
"LayerDrawingOrder" ) );
1933 QDomText drawingOrderText = doc.createTextNode( reversedList.join(
',' ) );
1934 layerDrawingOrderElem.appendChild( drawingOrderText );
1935 parentElem.appendChild( layerDrawingOrderElem );
1939 void appendLayerProjectSettings( QDomDocument &doc, QDomElement &layerElem,
QgsMapLayer *currentLayer )
1941 if ( !currentLayer )
1947 QDomElement treeNameElem = doc.createElement( QStringLiteral(
"TreeName" ) );
1948 QDomText treeNameText = doc.createTextNode( currentLayer->
name() );
1949 treeNameElem.appendChild( treeNameText );
1950 layerElem.appendChild( treeNameElem );
1952 switch ( currentLayer->
type() )
1958 int displayFieldIdx = -1;
1959 QString displayField = QStringLiteral(
"maptip" );
1961 if ( exp.isField() )
1968 QDomElement attributesElem = doc.createElement( QStringLiteral(
"Attributes" ) );
1970 for (
int idx = 0; idx < layerFields.
count(); ++idx )
1978 if ( idx == displayFieldIdx )
1982 QDomElement attributeElem = doc.createElement( QStringLiteral(
"Attribute" ) );
1983 attributeElem.setAttribute( QStringLiteral(
"name" ),
field.
name() );
1984 attributeElem.setAttribute( QStringLiteral(
"type" ), QVariant::typeToName(
field.
type() ) );
1985 attributeElem.setAttribute( QStringLiteral(
"typeName" ),
field.
typeName() );
1987 if ( !alias.isEmpty() )
1989 attributeElem.setAttribute( QStringLiteral(
"alias" ), alias );
1993 attributeElem.setAttribute( QStringLiteral(
"editType" ), vLayer->
editorWidgetSetup( idx ).
type() );
1994 attributeElem.setAttribute( QStringLiteral(
"comment" ),
field.
comment() );
1995 attributeElem.setAttribute( QStringLiteral(
"length" ),
field.
length() );
1996 attributeElem.setAttribute( QStringLiteral(
"precision" ),
field.
precision() );
1997 attributesElem.appendChild( attributeElem );
2001 layerElem.setAttribute( QStringLiteral(
"displayField" ), displayField );
2005 if ( pkAttributes.size() > 0 )
2007 QDomElement pkElem = doc.createElement( QStringLiteral(
"PrimaryKey" ) );
2008 QgsAttributeList::const_iterator pkIt = pkAttributes.constBegin();
2009 for ( ; pkIt != pkAttributes.constEnd(); ++pkIt )
2011 QDomElement pkAttributeElem = doc.createElement( QStringLiteral(
"PrimaryKeyAttribute" ) );
2012 QDomText pkAttName = doc.createTextNode( layerFields.
at( *pkIt ).
name() );
2013 pkAttributeElem.appendChild( pkAttName );
2014 pkElem.appendChild( pkAttributeElem );
2016 layerElem.appendChild( pkElem );
2023 layerElem.setAttribute( QStringLiteral(
"opacity" ), QString::number( vLayer->
opacity() ) );
2025 layerElem.appendChild( attributesElem );
2032 if ( provider && provider->
name() ==
"wms" )
2035 QVariant wmsBackgroundLayer = currentLayer->
customProperty( QStringLiteral(
"WMSBackgroundLayer" ), false );
2036 QDomElement wmsBackgroundLayerElem = doc.createElement(
"WMSBackgroundLayer" );
2037 QDomText wmsBackgroundLayerText = doc.createTextNode( wmsBackgroundLayer.toBool() ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) );
2038 wmsBackgroundLayerElem.appendChild( wmsBackgroundLayerText );
2039 layerElem.appendChild( wmsBackgroundLayerElem );
2042 QVariant wmsPublishDataSourceUrl = currentLayer->
customProperty( QStringLiteral(
"WMSPublishDataSourceUrl" ),
false );
2043 if ( wmsPublishDataSourceUrl.toBool() )
2045 bool tiled = qobject_cast< const QgsRasterDataProvider * >( provider )
2046 ? !qobject_cast< const QgsRasterDataProvider * >( provider )->nativeResolutions().isEmpty()
2049 QDomElement dataSourceElem = doc.createElement( tiled ? QStringLiteral(
"WMTSDataSource" ) : QStringLiteral(
"WMSDataSource" ) );
2050 QDomText dataSourceUri = doc.createTextNode( provider->
dataSourceUri() );
2051 dataSourceElem.appendChild( dataSourceUri );
2052 layerElem.appendChild( dataSourceElem );
2056 QVariant wmsPrintLayer = currentLayer->
customProperty( QStringLiteral(
"WMSPrintLayer" ) );
2057 if ( wmsPrintLayer.isValid() )
2059 QDomElement wmsPrintLayerElem = doc.createElement(
"WMSPrintLayer" );
2060 QDomText wmsPrintLayerText = doc.createTextNode( wmsPrintLayer.toString() );
2061 wmsPrintLayerElem.appendChild( wmsPrintLayerText );
2062 layerElem.appendChild( wmsPrintLayerElem );
2068 if ( rasterRenderer )
2070 layerElem.setAttribute( QStringLiteral(
"opacity" ), QString::number( rasterRenderer->
opacity() ) );
2085 void addKeywordListElement(
const QgsProject *project, QDomDocument &doc, QDomElement &parent )
2089 QDomElement keywordsElem = doc.createElement( QStringLiteral(
"KeywordList" ) );
2091 QDomElement keywordElem = doc.createElement( QStringLiteral(
"Keyword" ) );
2092 keywordElem.setAttribute( QStringLiteral(
"vocabulary" ), QStringLiteral(
"ISO" ) );
2093 QDomText keywordText = doc.createTextNode( QStringLiteral(
"infoMapAccessService" ) );
2094 keywordElem.appendChild( keywordText );
2095 keywordsElem.appendChild( keywordElem );
2096 parent.appendChild( keywordsElem );
2098 for (
const QString &keyword : std::as_const( keywords ) )
2100 if ( !keyword.isEmpty() )
2102 keywordElem = doc.createElement( QStringLiteral(
"Keyword" ) );
2103 keywordText = doc.createTextNode( keyword );
2104 keywordElem.appendChild( keywordText );
2107 keywordElem.setAttribute( QStringLiteral(
"vocabulary" ), QStringLiteral(
"SIA_Geo405" ) );
2109 keywordsElem.appendChild( keywordElem );
2112 parent.appendChild( keywordsElem );
2120 for (
int j = 0; j < childNode->
children().size(); ++j )
2130 const auto l { treeLayer->
layer() };
2137 QgsMessageLog::logMessage( QStringLiteral(
"Broken/corrupted layer tree, layer '%1' does not exist: check your project!" ).arg( treeLayer->
name() ), QStringLiteral(
"Server" ), Qgis::MessageLevel::Warning );
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)
This class 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.
QgsRectangle bounds() const
Returns the approximate bounds for the region the CRS is usable within.
bool hasAxisInverted() const
Returns whether axis is inverted (e.g., for WMS 1.3) for the CRS.
Custom exception class for Coordinate Reference System related exceptions.
Abstract base class for spatial data provider implementations.
virtual QString name() const =0
Returns a provider name.
virtual QString dataSourceUri(bool expandAuthConfig=false) const
Gets the data source specification.
An expression node which takes it value from a feature's field.
Class for parsing and evaluation of expressions (formerly called "search strings").
Encapsulate a field in an attribute table or data source.
QString typeName() const
Gets the field type.
ConfigurationFlags configurationFlags
@ HideFromWms
Field is not available if layer is served as WMS from QGIS server.
Container of fields for a vector layer.
int indexOf(const QString &fieldName) const
Gets the field index from the field name.
int count() const
Returns number of items.
QgsField at(int i) const
Returns the field at particular index (must be in range 0..N-1).
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.
bool isMutuallyExclusive() const
Returns whether the group is mutually exclusive (only one child can be checked at a time)
Layer tree node points to a map layer.
QString name() const override
Returns the layer's name.
QgsMapLayer * layer() const
Returns the map layer associated with this node.
This class is a base class for nodes in a layer tree.
@ NodeGroup
Container of other groups and layers.
@ NodeLayer
Leaf node pointing to a layer.
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.
QVariant customProperty(const QString &key, const QVariant &defaultValue=QVariant()) const
Read a custom property from layer. Properties are stored in a map and saved in project file.
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.
Class used to render QgsLayout as an atlas, by iterating over the features from an associated vector ...
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.
This class provides a method of storing measurements for use in QGIS layouts using a variety of diffe...
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.
This class provides a method of storing sizes, consisting of a width and height, for use in QGIS layo...
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, QgsUnitTypes::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.
QStringList styles() const
Returns list of all defined style names.
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.
QString legendUrlFormat() const
Returns the format for a URL based layer legend.
QgsRectangle wgs84Extent(bool forceRecalculate=false) const
Returns the WGS84 extent (EPSG:4326) of the layer according to ReadFlag::FlagTrustLayerMetadata.
virtual QgsRectangle extent() const
Returns the extent of the layer.
Q_INVOKABLE QVariant customProperty(const QString &value, const QVariant &defaultValue=QVariant()) const
Read a custom property from layer.
QgsMapLayer::LayerFlags flags() const
Returns the flags for this layer.
QgsCoordinateReferenceSystem crs
QgsMapLayerServerProperties * serverProperties()
Returns QGIS Server Properties for the map layer.
QString attribution() const
Returns the attribution of the layer used by QGIS Server in GetCapabilities request.
QString id() const
Returns the layer's unique ID, which is used to access this layer from QgsProject.
QString abstract() const
Returns the abstract 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 shortName() const
Returns the short name of the layer used by QGIS Server to identify the layer.
QString title() const
Returns the title of the layer used by QGIS Server in GetCapabilities request.
QString dataUrl() const
Returns the DataUrl of the layer used by QGIS Server in GetCapabilities request.
bool hasScaleBasedVisibility() const
Returns whether scale based visibility is enabled for the layer.
virtual QgsMapLayerTemporalProperties * temporalProperties()
Returns the layer's temporal properties.
@ Identifiable
If the layer is identifiable using the identify map tool and as a WMS layer.
QString attributionUrl() const
Returns the attribution URL of the layer used by QGIS Server in GetCapabilities request.
double minimumScale() const
Returns the minimum map scale (i.e.
QgsMapLayerStyleManager * styleManager() const
Gets access to the layer's style manager.
QString legendUrl() const
Returns the URL for the layer's legend.
virtual Q_INVOKABLE QgsDataProvider * dataProvider()
Returns the layer's data provider, it may be nullptr.
double maximumScale() const
Returns the maximum map scale (i.e.
QString keywordList() const
Returns the keyword list of the layer used by QGIS Server in GetCapabilities request.
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::MessageLevel::Warning, bool notifyUser=true)
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,...
QString title() const
Returns the project's title.
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
Represents a raster layer.
QgsRasterRenderer * renderer() const
Returns the raster's renderer.
Raster renderer pipe that applies colors to a raster.
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.
double yMaximum() const SIP_HOLDGIL
Returns the y maximum value (top side of rectangle).
double xMaximum() const SIP_HOLDGIL
Returns the x maximum value (right side of rectangle).
double xMinimum() const SIP_HOLDGIL
Returns the x minimum value (left side of rectangle).
double yMinimum() const SIP_HOLDGIL
Returns the y minimum value (bottom side of rectangle).
void setYMinimum(double y) SIP_HOLDGIL
Set the minimum y value.
bool isNull() const
Test if the rectangle is null (all coordinates zero or after call to setMinimal()).
void setXMaximum(double x) SIP_HOLDGIL
Set the maximum x value.
void setXMinimum(double x) SIP_HOLDGIL
Set the minimum x value.
void grow(double delta)
Grows the rectangle in place by the specified amount.
void setYMaximum(double y) SIP_HOLDGIL
Set the maximum y value.
void combineExtentWith(const QgsRectangle &rect)
Expands the rectangle so that it covers both the original rectangle and the given rectangle.
bool isEmpty() const
Returns true if the rectangle is empty.
void invert()
Swap x/y coordinates in the rectangle.
A helper class that centralizes caches accesses given by all the server cache filter plugins.
bool setCachedDocument(const QDomDocument *doc, const QgsProject *project, const QgsServerRequest &request, QgsAccessControl *accessControl) const
Updates or inserts the document in cache like capabilities.
bool getCachedDocument(QDomDocument *doc, const QgsProject *project, const QgsServerRequest &request, QgsAccessControl *accessControl) const
Returns cached document (or 0 if document not in cache) like capabilities.
QgsServerInterface Class defining interfaces exposed by QGIS Server and made available to plugins.
virtual QgsServerCacheManager * cacheManager() const =0
Gets the registered server cache filters.
virtual 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.
QgsServerParameters serverParameters() const
Returns parameters.
QgsServerResponse Class defining response interface passed to services QgsService::executeRequest() m...
virtual void write(const QString &data)
Write string This is a convenient method that will write directly to the underlying I/O device.
virtual void setHeader(const QString &key, const QString &value)=0
Set Header entry Add Header entry to the response Note that it is usually an error to set Header afte...
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.
Represents a vector layer which manages a vector based data sets.
QString attributeDisplayName(int index) const
Convenience function that returns the attribute alias if defined or the field name else.
Q_INVOKABLE QgsWkbTypes::Type wkbType() const FINAL
Returns the WKBType or WKBUnknown in case of error.
QgsFields fields() const FINAL
Returns the list of fields of this layer.
QString displayExpression
QgsEditorWidgetSetup editorWidgetSetup(int index) const
The editor widget setup defines which QgsFieldFormatter and editor widget will be used for the field ...
QgsAttributeList primaryKeyAttributes() const
Returns the list of attributes which make up the layer's primary keys.
QSet< QVariant > uniqueValues(int fieldIndex, int limit=-1) const FINAL
Calculates a list of unique values contained within an attribute in the layer.
static QString displayString(Type type) SIP_HOLDGIL
Returns a non-translated display string type for a WKB type, e.g., the geometry name used in WKT geom...
QString version() const override
Returns VERSION parameter as a string or an empty string if not defined.
Class defining request interface passed to WMS service.
const QgsWmsParameters & wmsParameters() const
Returns the parameters interpreted for the WMS service.
@ PointCloudLayer
Point cloud layer. Added in QGIS 3.18.
@ MeshLayer
Mesh layer. Added in QGIS 3.2.
@ VectorLayer
Vector layer.
@ RasterLayer
Raster layer.
@ GroupLayer
Composite group layer. Added in QGIS 3.24.
@ VectorTileLayer
Vector tile layer. Added in QGIS 3.14.
@ AnnotationLayer
Contains freeform, georeferenced annotations. Added in QGIS 3.16.
@ PluginLayer
Plugin based layer.
SERVER_EXPORT QString wmsRootName(const QgsProject &project)
Returns the WMS root layer name defined in a QGIS project.
SERVER_EXPORT bool wmsInfoFormatSia2045(const QgsProject &project)
Returns if the info format is SIA20145.
SERVER_EXPORT QString wmsInspireMetadataUrl(const QgsProject &project)
Returns the Inspire metadata URL.
SERVER_EXPORT double ceilWithPrecision(double number, int places)
Returns a double greater than number to the specified number of places.
SERVER_EXPORT QStringList wmsRestrictedComposers(const QgsProject &project)
Returns the restricted composer list.
SERVER_EXPORT QgsRectangle wmsExtent(const QgsProject &project)
Returns the WMS Extent restriction.
SERVER_EXPORT bool wmsUseLayerIds(const QgsProject &project)
Returns if layer ids are used as name in WMS.
SERVER_EXPORT QString owsServiceAccessConstraints(const QgsProject &project)
Returns the owsService access constraints defined in project.
SERVER_EXPORT QStringList wfsLayerIds(const QgsProject &project)
Returns the Layer ids list defined in a QGIS project as published in WFS.
SERVER_EXPORT QString owsServiceOnlineResource(const QgsProject &project)
Returns the owsService online resource defined in project.
SERVER_EXPORT QString owsServiceFees(const QgsProject &project)
Returns the owsService fees defined in project.
SERVER_EXPORT QStringList owsServiceKeywords(const QgsProject &project)
Returns the owsService keywords defined in project.
SERVER_EXPORT QString owsServiceContactPosition(const QgsProject &project)
Returns the owsService contact position defined in project.
SERVER_EXPORT QString serviceUrl(const QString &service, const QgsServerRequest &request, const QgsServerSettings &settings)
Returns the service url defined in the environment variable or with HTTP header.
SERVER_EXPORT QString wmsInspireTemporalReference(const QgsProject &project)
Returns the Inspire temporal reference.
SERVER_EXPORT QStringList wmsOutputCrsList(const QgsProject &project)
Returns the WMS output CRS list.
SERVER_EXPORT QString wmsInspireMetadataDate(const QgsProject &project)
Returns the Inspire metadata date.
SERVER_EXPORT QString owsServiceContactOrganization(const QgsProject &project)
Returns the owsService contact organization defined in project.
SERVER_EXPORT QStringList wmsRestrictedLayers(const QgsProject &project)
Returns the restricted layer name list.
SERVER_EXPORT QString wmsInspireLanguage(const QgsProject &project)
Returns the Inspire language.
SERVER_EXPORT QString wmsInspireMetadataUrlType(const QgsProject &project)
Returns the Inspire metadata URL type.
SERVER_EXPORT bool wmsInspireActivate(const QgsProject &project)
Returns if Inspire is activated.
SERVER_EXPORT int wmsMaxWidth(const QgsProject &project)
Returns the maximum width for WMS images defined in a QGIS project.
SERVER_EXPORT QString owsServiceTitle(const QgsProject &project)
Returns the owsService title defined in project.
SERVER_EXPORT QString owsServiceContactMail(const QgsProject &project)
Returns the owsService contact mail defined in project.
SERVER_EXPORT QString owsServiceAbstract(const QgsProject &project)
Returns the owsService abstract defined in project.
SERVER_EXPORT double floorWithPrecision(double number, int places)
Returns a double less than number to the specified number of places.
SERVER_EXPORT int wmsMaxHeight(const QgsProject &project)
Returns the maximum height for WMS images defined in a QGIS project.
SERVER_EXPORT QString owsServiceContactPhone(const QgsProject &project)
Returns the owsService contact phone defined in project.
SERVER_EXPORT QString owsServiceContactPerson(const QgsProject &project)
Returns the owsService contact person defined in project.
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.
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.
bool hasQueryableChildren(const QgsLayerTreeNode *childNode, const QStringList &wmsRestrictedLayers)
QDomDocument getCapabilities(QgsServerInterface *serverIface, const QgsProject *project, const QgsWmsRequest &request, bool projectSettings)
Creates the WMS GetCapabilities XML document.
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.
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
CONSTLATIN1STRING geoEpsgCrsAuthId()
Geographic coord sys from EPSG authority.
QList< int > QgsAttributeList
const QgsCoordinateReferenceSystem & crs
Setting to define QGIS Server WMS Dimension.
@ MinValue
Add selection to current selection.
@ MaxValue
Modify current selection to include only select features which match.
@ ReferenceValue
Remove from current selection.