48 void appendLayerProjectSettings( QDomDocument &doc, QDomElement &layerElem,
QgsMapLayer *currentLayer );
52 void appendLayerWgs84BoundingRect( QDomDocument &doc, QDomElement &layerElement,
const QgsRectangle &wgs84BoundingRect );
54 void appendLayerCrsExtents( QDomDocument &doc, QDomElement &layerElement,
const QMap<QString, QgsRectangle> &crsExtents );
56 void appendCrsElementToLayer( QDomDocument &doc, QDomElement &layerElement,
const QDomElement &precedingElement,
const QString &crsText );
58 void appendCrsElementsToLayer( QDomDocument &doc, QDomElement &layerElement,
const QStringList &crsList,
const QStringList &constrainedCrsList );
62 void appendLayersFromTreeGroup( 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 );
64 void addKeywordListElement(
const QgsProject *project, QDomDocument &doc, QDomElement &parent );
69#ifdef HAVE_SERVER_PYTHON_PLUGINS
74 const QDomDocument *capabilitiesDocument =
nullptr;
79 QStringList cacheKeyList;
80 cacheKeyList << ( projectSettings ? QStringLiteral(
"projectSettings" ) : request.
wmsParameters().
version() );
84#ifdef HAVE_SERVER_PYTHON_PLUGINS
88 QString cacheKey = cacheKeyList.join(
'-' );
90#ifdef HAVE_SERVER_PYTHON_PLUGINS
92 if ( cacheManager && cacheManager->
getCachedDocument( &doc, project, request, accessControl ) )
94 capabilitiesDocument = &doc;
97 if ( !capabilitiesDocument && cache )
102 if ( !capabilitiesDocument )
104 QgsMessageLog::logMessage( QStringLiteral(
"WMS capabilities document not found in cache" ), QStringLiteral(
"Server" ) );
106 doc =
getCapabilities( serverIface, project, request, projectSettings );
108#ifdef HAVE_SERVER_PYTHON_PLUGINS
109 if ( cacheManager && cacheManager->
setCachedDocument( &doc, project, request, accessControl ) )
111 capabilitiesDocument = &doc;
116 if ( !capabilitiesDocument )
121 if ( !capabilitiesDocument )
123 capabilitiesDocument = &doc;
135 response.
setHeader( QStringLiteral(
"Content-Type" ), QStringLiteral(
"text/xml; charset=utf-8" ) );
136 response.
write( capabilitiesDocument->toByteArray() );
142 QDomElement wmsCapabilitiesElement;
148 QString hrefString = href.toString();
149 hrefString.append( href.hasQuery() ?
"&" :
"?" );
152 QDomProcessingInstruction xmlDeclaration = doc.createProcessingInstruction( QStringLiteral(
"xml" ), QStringLiteral(
"version=\"1.0\" encoding=\"utf-8\"" ) );
155 std::function<void( QDomElement &,
const QString & )> appendFormat = [&doc]( QDomElement &elem,
const QString &format ) {
156 QDomElement formatElem = doc.createElement( QStringLiteral(
"Format" ) );
157 formatElem.appendChild( doc.createTextNode( format ) );
158 elem.appendChild( formatElem );
163 doc = QDomDocument( QStringLiteral(
"WMT_MS_Capabilities SYSTEM 'http://schemas.opengis.net/wms/1.1.1/WMS_MS_Capabilities.dtd'" ) );
164 doc.appendChild( xmlDeclaration );
165 wmsCapabilitiesElement = doc.createElement( QStringLiteral(
"WMT_MS_Capabilities" ) );
169 doc.appendChild( xmlDeclaration );
170 wmsCapabilitiesElement = doc.createElement( QStringLiteral(
"WMS_Capabilities" ) );
171 wmsCapabilitiesElement.setAttribute( QStringLiteral(
"xmlns" ), QStringLiteral(
"http://www.opengis.net/wms" ) );
172 wmsCapabilitiesElement.setAttribute( QStringLiteral(
"xmlns:sld" ), QStringLiteral(
"http://www.opengis.net/sld" ) );
173 wmsCapabilitiesElement.setAttribute( QStringLiteral(
"xmlns:qgs" ), QStringLiteral(
"http://www.qgis.org/wms" ) );
174 wmsCapabilitiesElement.setAttribute( QStringLiteral(
"xmlns:xsi" ), QStringLiteral(
"http://www.w3.org/2001/XMLSchema-instance" ) );
175 QString schemaLocation = QStringLiteral(
"http://www.opengis.net/wms" );
176 schemaLocation += QLatin1String(
" http://schemas.opengis.net/wms/1.3.0/capabilities_1_3_0.xsd" );
177 schemaLocation += QLatin1String(
" http://www.opengis.net/sld" );
178 schemaLocation += QLatin1String(
" http://schemas.opengis.net/sld/1.1.0/sld_capabilities.xsd" );
182 wmsCapabilitiesElement.setAttribute( QStringLiteral(
"xmlns:inspire_common" ), QStringLiteral(
"http://inspire.ec.europa.eu/schemas/common/1.0" ) );
183 wmsCapabilitiesElement.setAttribute( QStringLiteral(
"xmlns:inspire_vs" ), QStringLiteral(
"http://inspire.ec.europa.eu/schemas/inspire_vs/1.0" ) );
184 schemaLocation += QLatin1String(
" http://inspire.ec.europa.eu/schemas/inspire_vs/1.0" );
185 schemaLocation += QLatin1String(
" http://inspire.ec.europa.eu/schemas/inspire_vs/1.0/inspire_vs.xsd" );
188 schemaLocation += QLatin1String(
" http://www.qgis.org/wms" );
189 schemaLocation +=
" " + hrefString +
"SERVICE=WMS&REQUEST=GetSchemaExtension";
191 wmsCapabilitiesElement.setAttribute( QStringLiteral(
"xsi:schemaLocation" ), schemaLocation );
193 wmsCapabilitiesElement.setAttribute( QStringLiteral(
"version" ), request.
wmsParameters().
version() );
194 doc.appendChild( wmsCapabilitiesElement );
200 QDomElement capabilityElement =
getCapabilityElement( doc, project, request, projectSettings, serverIface );
201 wmsCapabilitiesElement.appendChild( capabilityElement );
203 if ( projectSettings )
212 capabilityElement.appendChild(
216 if ( projectSettings )
218 appendDrawingOrder( doc, capabilityElement, serverIface, project );
227 QDomElement serviceElem = doc.createElement( QStringLiteral(
"Service" ) );
230 QDomElement nameElem = doc.createElement( QStringLiteral(
"Name" ) );
231 QDomText nameText = doc.createTextNode( QStringLiteral(
"WMS" ) );
232 nameElem.appendChild( nameText );
233 serviceElem.appendChild( nameElem );
236 QDomElement titleElem = doc.createElement( QStringLiteral(
"Title" ) );
238 titleElem.appendChild( titleText );
239 serviceElem.appendChild( titleElem );
242 if ( !abstract.isEmpty() )
244 QDomElement abstractElem = doc.createElement( QStringLiteral(
"Abstract" ) );
245 QDomText abstractText = doc.createCDATASection( abstract );
246 abstractElem.appendChild( abstractText );
247 serviceElem.appendChild( abstractElem );
250 addKeywordListElement( project, doc, serviceElem );
253 if ( onlineResource.isEmpty() )
255 onlineResource =
serviceUrl( request, project, *serverSettings ).toString();
257 QDomElement onlineResourceElem = doc.createElement( QStringLiteral(
"OnlineResource" ) );
258 onlineResourceElem.setAttribute( QStringLiteral(
"xmlns:xlink" ), QStringLiteral(
"http://www.w3.org/1999/xlink" ) );
259 onlineResourceElem.setAttribute( QStringLiteral(
"xlink:type" ), QStringLiteral(
"simple" ) );
260 onlineResourceElem.setAttribute( QStringLiteral(
"xlink:href" ), onlineResource );
261 serviceElem.appendChild( onlineResourceElem );
268 if ( !contactPerson.isEmpty() || !contactOrganization.isEmpty() || !contactPosition.isEmpty() || !contactMail.isEmpty() || !contactPhone.isEmpty() )
271 QDomElement contactInfoElem = doc.createElement( QStringLiteral(
"ContactInformation" ) );
274 if ( !contactPerson.isEmpty() || !contactOrganization.isEmpty() )
276 QDomElement contactPersonPrimaryElem = doc.createElement( QStringLiteral(
"ContactPersonPrimary" ) );
278 QDomText contactPersonText;
279 if ( !contactPerson.isEmpty() )
281 contactPersonText = doc.createTextNode( contactPerson );
285 contactPersonText = doc.createTextNode( QStringLiteral(
"unknown" ) );
287 QDomElement contactPersonElem = doc.createElement( QStringLiteral(
"ContactPerson" ) );
288 contactPersonElem.appendChild( contactPersonText );
289 contactPersonPrimaryElem.appendChild( contactPersonElem );
291 QDomText contactOrganizationText;
292 if ( !contactOrganization.isEmpty() )
294 contactOrganizationText = doc.createTextNode( contactOrganization );
298 contactOrganizationText = doc.createTextNode( QStringLiteral(
"unknown" ) );
300 QDomElement contactOrganizationElem = doc.createElement( QStringLiteral(
"ContactOrganization" ) );
301 contactOrganizationElem.appendChild( contactOrganizationText );
302 contactPersonPrimaryElem.appendChild( contactOrganizationElem );
304 contactInfoElem.appendChild( contactPersonPrimaryElem );
307 if ( !contactPosition.isEmpty() )
309 QDomElement contactPositionElem = doc.createElement( QStringLiteral(
"ContactPosition" ) );
310 QDomText contactPositionText = doc.createTextNode( contactPosition );
311 contactPositionElem.appendChild( contactPositionText );
312 contactInfoElem.appendChild( contactPositionElem );
315 if ( !contactPhone.isEmpty() )
317 QDomElement phoneElem = doc.createElement( QStringLiteral(
"ContactVoiceTelephone" ) );
318 QDomText phoneText = doc.createTextNode( contactPhone );
319 phoneElem.appendChild( phoneText );
320 contactInfoElem.appendChild( phoneElem );
323 if ( !contactMail.isEmpty() )
325 QDomElement mailElem = doc.createElement( QStringLiteral(
"ContactElectronicMailAddress" ) );
326 QDomText mailText = doc.createTextNode( contactMail );
327 mailElem.appendChild( mailText );
328 contactInfoElem.appendChild( mailElem );
331 serviceElem.appendChild( contactInfoElem );
334 QDomElement feesElem = doc.createElement( QStringLiteral(
"Fees" ) );
335 QDomText feesText = doc.createTextNode( QStringLiteral(
"None" ) );
337 if ( !fees.isEmpty() )
339 feesText = doc.createTextNode( fees );
341 feesElem.appendChild( feesText );
342 serviceElem.appendChild( feesElem );
344 QDomElement accessConstraintsElem = doc.createElement( QStringLiteral(
"AccessConstraints" ) );
345 QDomText accessConstraintsText = doc.createTextNode( QStringLiteral(
"None" ) );
347 if ( !accessConstraints.isEmpty() )
349 accessConstraintsText = doc.createTextNode( accessConstraints );
351 accessConstraintsElem.appendChild( accessConstraintsText );
352 serviceElem.appendChild( accessConstraintsElem );
359 QDomElement maxWidthElem = doc.createElement( QStringLiteral(
"MaxWidth" ) );
360 QDomText maxWidthText = doc.createTextNode( QString::number( maxWidth ) );
361 maxWidthElem.appendChild( maxWidthText );
362 serviceElem.appendChild( maxWidthElem );
368 QDomElement maxHeightElem = doc.createElement( QStringLiteral(
"MaxHeight" ) );
369 QDomText maxHeightText = doc.createTextNode( QString::number( maxHeight ) );
370 maxHeightElem.appendChild( maxHeightText );
371 serviceElem.appendChild( maxHeightElem );
386 QString hrefString = href.toString();
387 hrefString.append( href.hasQuery() ?
"&" :
"?" );
389 QDomElement capabilityElem = doc.createElement( QStringLiteral(
"Capability" ) );
392 QDomElement requestElem = doc.createElement( QStringLiteral(
"Request" ) );
393 capabilityElem.appendChild( requestElem );
395 QDomElement dcpTypeElem = doc.createElement( QStringLiteral(
"DCPType" ) );
396 QDomElement httpElem = doc.createElement( QStringLiteral(
"HTTP" ) );
397 dcpTypeElem.appendChild( httpElem );
400 std::function<void( QDomElement &,
const QString & )> appendFormat = [&doc]( QDomElement &elem,
const QString &format ) {
401 QDomElement formatElem = doc.createElement( QStringLiteral(
"Format" ) );
402 formatElem.appendChild( doc.createTextNode( format ) );
403 elem.appendChild( formatElem );
409 elem = doc.createElement( QStringLiteral(
"GetCapabilities" ) );
410 appendFormat( elem, ( version == QLatin1String(
"1.1.1" ) ?
"application/vnd.ogc.wms_xml" :
"text/xml" ) );
411 elem.appendChild( dcpTypeElem );
412 requestElem.appendChild( elem );
415 QDomElement getElem = doc.createElement( QStringLiteral(
"Get" ) );
416 httpElem.appendChild( getElem );
417 QDomElement olResourceElem = doc.createElement( QStringLiteral(
"OnlineResource" ) );
418 olResourceElem.setAttribute( QStringLiteral(
"xmlns:xlink" ), QStringLiteral(
"http://www.w3.org/1999/xlink" ) );
419 olResourceElem.setAttribute( QStringLiteral(
"xlink:type" ), QStringLiteral(
"simple" ) );
420 olResourceElem.setAttribute( QStringLiteral(
"xlink:href" ), hrefString );
421 getElem.appendChild( olResourceElem );
424 elem = doc.createElement( QStringLiteral(
"GetMap" ) );
425 appendFormat( elem, QStringLiteral(
"image/jpeg" ) );
426 appendFormat( elem, QStringLiteral(
"image/png" ) );
427 appendFormat( elem, QStringLiteral(
"image/png; mode=16bit" ) );
428 appendFormat( elem, QStringLiteral(
"image/png; mode=8bit" ) );
429 appendFormat( elem, QStringLiteral(
"image/png; mode=1bit" ) );
430 appendFormat( elem, QStringLiteral(
"application/dxf" ) );
431 appendFormat( elem, QStringLiteral(
"application/pdf" ) );
432 elem.appendChild( dcpTypeElem.cloneNode().toElement() );
433 requestElem.appendChild( elem );
436 elem = doc.createElement( QStringLiteral(
"GetFeatureInfo" ) );
437 appendFormat( elem, QStringLiteral(
"text/plain" ) );
438 appendFormat( elem, QStringLiteral(
"text/html" ) );
439 appendFormat( elem, QStringLiteral(
"text/xml" ) );
440 appendFormat( elem, QStringLiteral(
"application/vnd.ogc.gml" ) );
441 appendFormat( elem, QStringLiteral(
"application/vnd.ogc.gml/3.1.1" ) );
442 appendFormat( elem, QStringLiteral(
"application/json" ) );
443 appendFormat( elem, QStringLiteral(
"application/geo+json" ) );
444 elem.appendChild( dcpTypeElem.cloneNode().toElement() );
445 requestElem.appendChild( elem );
448 elem = doc.createElement( ( version == QLatin1String(
"1.1.1" ) ?
"GetLegendGraphic" :
"sld:GetLegendGraphic" ) );
449 appendFormat( elem, QStringLiteral(
"image/jpeg" ) );
450 appendFormat( elem, QStringLiteral(
"image/png" ) );
451 appendFormat( elem, QStringLiteral(
"application/json" ) );
452 elem.appendChild( dcpTypeElem.cloneNode().toElement() );
453 requestElem.appendChild( elem );
456 elem = doc.createElement( ( version == QLatin1String(
"1.1.1" ) ?
"DescribeLayer" :
"sld:DescribeLayer" ) );
457 appendFormat( elem, QStringLiteral(
"text/xml" ) );
458 elem.appendChild( dcpTypeElem.cloneNode().toElement() );
459 requestElem.appendChild( elem );
462 elem = doc.createElement( ( version == QLatin1String(
"1.1.1" ) ?
"GetStyles" :
"qgs:GetStyles" ) );
463 appendFormat( elem, QStringLiteral(
"text/xml" ) );
464 elem.appendChild( dcpTypeElem.cloneNode().toElement() );
465 requestElem.appendChild( elem );
470 elem = doc.createElement( QStringLiteral(
"GetPrint" ) );
471 appendFormat( elem, QStringLiteral(
"svg" ) );
472 appendFormat( elem, QStringLiteral(
"png" ) );
473 appendFormat( elem, QStringLiteral(
"pdf" ) );
474 elem.appendChild( dcpTypeElem.cloneNode().toElement() );
475 requestElem.appendChild( elem );
479 elem = doc.createElement( QStringLiteral(
"Exception" ) );
480 appendFormat( elem, ( version == QLatin1String(
"1.1.1" ) ?
"application/vnd.ogc.se_xml" :
"XML" ) );
481 capabilityElem.appendChild( elem );
484 if ( version == QLatin1String(
"1.3.0" ) )
486 elem = doc.createElement( QStringLiteral(
"sld:UserDefinedSymbolization" ) );
487 elem.setAttribute( QStringLiteral(
"SupportSLD" ), QStringLiteral(
"1" ) );
488 elem.setAttribute( QStringLiteral(
"UserLayer" ), QStringLiteral(
"0" ) );
489 elem.setAttribute( QStringLiteral(
"UserStyle" ), QStringLiteral(
"1" ) );
490 elem.setAttribute( QStringLiteral(
"RemoteWFS" ), QStringLiteral(
"0" ) );
491 elem.setAttribute( QStringLiteral(
"InlineFeature" ), QStringLiteral(
"0" ) );
492 elem.setAttribute( QStringLiteral(
"RemoteWCS" ), QStringLiteral(
"0" ) );
493 capabilityElem.appendChild( elem );
501 return capabilityElem;
506 QDomElement inspireCapabilitiesElem;
509 return inspireCapabilitiesElem;
511 inspireCapabilitiesElem = doc.createElement( QStringLiteral(
"inspire_vs:ExtendedCapabilities" ) );
515 if ( !inspireMetadataUrl.isEmpty() )
517 QDomElement inspireCommonMetadataUrlElem = doc.createElement( QStringLiteral(
"inspire_common:MetadataUrl" ) );
518 inspireCommonMetadataUrlElem.setAttribute( QStringLiteral(
"xsi:type" ), QStringLiteral(
"inspire_common:resourceLocatorType" ) );
520 QDomElement inspireCommonMetadataUrlUrlElem = doc.createElement( QStringLiteral(
"inspire_common:URL" ) );
521 inspireCommonMetadataUrlUrlElem.appendChild( doc.createTextNode( inspireMetadataUrl ) );
522 inspireCommonMetadataUrlElem.appendChild( inspireCommonMetadataUrlUrlElem );
525 if ( !inspireMetadataUrlType.isNull() )
527 QDomElement inspireCommonMetadataUrlMediaTypeElem = doc.createElement( QStringLiteral(
"inspire_common:MediaType" ) );
528 inspireCommonMetadataUrlMediaTypeElem.appendChild( doc.createTextNode( inspireMetadataUrlType ) );
529 inspireCommonMetadataUrlElem.appendChild( inspireCommonMetadataUrlMediaTypeElem );
532 inspireCapabilitiesElem.appendChild( inspireCommonMetadataUrlElem );
536 QDomElement inspireCommonResourceTypeElem = doc.createElement( QStringLiteral(
"inspire_common:ResourceType" ) );
537 inspireCommonResourceTypeElem.appendChild( doc.createTextNode( QStringLiteral(
"service" ) ) );
538 inspireCapabilitiesElem.appendChild( inspireCommonResourceTypeElem );
540 QDomElement inspireCommonSpatialDataServiceTypeElem = doc.createElement( QStringLiteral(
"inspire_common:SpatialDataServiceType" ) );
541 inspireCommonSpatialDataServiceTypeElem.appendChild( doc.createTextNode( QStringLiteral(
"view" ) ) );
542 inspireCapabilitiesElem.appendChild( inspireCommonSpatialDataServiceTypeElem );
545 if ( !inspireTemporalReference.isNull() )
547 QDomElement inspireCommonTemporalReferenceElem = doc.createElement( QStringLiteral(
"inspire_common:TemporalReference" ) );
548 QDomElement inspireCommonDateOfLastRevisionElem = doc.createElement( QStringLiteral(
"inspire_common:DateOfLastRevision" ) );
549 inspireCommonDateOfLastRevisionElem.appendChild( doc.createTextNode( inspireTemporalReference ) );
550 inspireCommonTemporalReferenceElem.appendChild( inspireCommonDateOfLastRevisionElem );
551 inspireCapabilitiesElem.appendChild( inspireCommonTemporalReferenceElem );
554 QDomElement inspireCommonMetadataPointOfContactElem = doc.createElement( QStringLiteral(
"inspire_common:MetadataPointOfContact" ) );
557 QDomElement inspireCommonOrganisationNameElem = doc.createElement( QStringLiteral(
"inspire_common:OrganisationName" ) );
558 if ( !contactOrganization.isNull() )
560 inspireCommonOrganisationNameElem.appendChild( doc.createTextNode( contactOrganization ) );
562 inspireCommonMetadataPointOfContactElem.appendChild( inspireCommonOrganisationNameElem );
565 QDomElement inspireCommonEmailAddressElem = doc.createElement( QStringLiteral(
"inspire_common:EmailAddress" ) );
566 if ( !contactMail.isNull() )
568 inspireCommonEmailAddressElem.appendChild( doc.createTextNode( contactMail ) );
570 inspireCommonMetadataPointOfContactElem.appendChild( inspireCommonEmailAddressElem );
572 inspireCapabilitiesElem.appendChild( inspireCommonMetadataPointOfContactElem );
575 if ( !inspireMetadataDate.isNull() )
577 QDomElement inspireCommonMetadataDateElem = doc.createElement( QStringLiteral(
"inspire_common:MetadataDate" ) );
578 inspireCommonMetadataDateElem.appendChild( doc.createTextNode( inspireMetadataDate ) );
579 inspireCapabilitiesElem.appendChild( inspireCommonMetadataDateElem );
584 QDomElement inspireCommonSupportedLanguagesElem = doc.createElement( QStringLiteral(
"inspire_common:SupportedLanguages" ) );
585 inspireCommonSupportedLanguagesElem.setAttribute( QStringLiteral(
"xsi:type" ), QStringLiteral(
"inspire_common:supportedLanguagesType" ) );
587 QDomElement inspireCommonLanguageElem = doc.createElement( QStringLiteral(
"inspire_common:Language" ) );
590 QDomElement inspireCommonDefaultLanguageElem = doc.createElement( QStringLiteral(
"inspire_common:DefaultLanguage" ) );
591 inspireCommonDefaultLanguageElem.appendChild( inspireCommonLanguageElem );
592 inspireCommonSupportedLanguagesElem.appendChild( inspireCommonDefaultLanguageElem );
596 QDomElement inspireCommonSupportedLanguageElem = doc.createElement(
"inspire_common:SupportedLanguage" );
597 inspireCommonSupportedLanguageElem.appendChild( inspireCommonLanguageElem.cloneNode().toElement() );
598 inspireCommonSupportedLanguagesElem.appendChild( inspireCommonSupportedLanguageElem );
601 inspireCapabilitiesElem.appendChild( inspireCommonSupportedLanguagesElem );
603 QDomElement inspireCommonResponseLanguageElem = doc.createElement( QStringLiteral(
"inspire_common:ResponseLanguage" ) );
604 inspireCommonResponseLanguageElem.appendChild( inspireCommonLanguageElem.cloneNode().toElement() );
605 inspireCapabilitiesElem.appendChild( inspireCommonResponseLanguageElem );
607 return inspireCapabilitiesElem;
613 if ( projectComposers.size() == 0 )
614 return QDomElement();
618 QDomElement composerTemplatesElem = doc.createElement( QStringLiteral(
"ComposerTemplates" ) );
619 QList<QgsPrintLayout *>::const_iterator cIt = projectComposers.constBegin();
620 for ( ; cIt != projectComposers.constEnd(); ++cIt )
623 if ( restrictedComposers.contains( layout->
name() ) )
635 QDomElement composerTemplateElem = doc.createElement( QStringLiteral(
"ComposerTemplate" ) );
636 composerTemplateElem.setAttribute( QStringLiteral(
"name" ), layout->
name() );
639 composerTemplateElem.setAttribute( QStringLiteral(
"width" ), width.
length() );
640 composerTemplateElem.setAttribute( QStringLiteral(
"height" ), height.
length() );
644 if ( atlas && atlas->
enabled() )
646 composerTemplateElem.setAttribute( QStringLiteral(
"atlasEnabled" ), QStringLiteral(
"1" ) );
653 layerName = cLayer->
id();
655 else if ( layerName.isEmpty() )
657 layerName = cLayer->
name();
659 composerTemplateElem.setAttribute( QStringLiteral(
"atlasCoverageLayer" ), layerName );
664 QList<QgsLayoutItemMap *> layoutMapList;
666 QList<QgsLayoutItemMap *>::const_iterator cmIt = layoutMapList.constBegin();
669 for ( ; cmIt != layoutMapList.constEnd(); ++cmIt )
673 QDomElement composerMapElem = doc.createElement( QStringLiteral(
"ComposerMap" ) );
674 composerMapElem.setAttribute( QStringLiteral(
"name" ), QStringLiteral(
"map%1" ).arg( mapId ) );
675 composerMapElem.setAttribute( QStringLiteral(
"itemName" ), composerMap->
displayName() );
677 composerMapElem.setAttribute( QStringLiteral(
"width" ), composerMap->rect().width() );
678 composerMapElem.setAttribute( QStringLiteral(
"height" ), composerMap->rect().height() );
679 composerTemplateElem.appendChild( composerMapElem );
683 QList<QgsLayoutItemLabel *> composerLabelList;
685 QList<QgsLayoutItemLabel *>::const_iterator clIt = composerLabelList.constBegin();
686 for ( ; clIt != composerLabelList.constEnd(); ++clIt )
689 QString
id = composerLabel->
id();
693 QDomElement composerLabelElem = doc.createElement( QStringLiteral(
"ComposerLabel" ) );
694 composerLabelElem.setAttribute( QStringLiteral(
"name" ), id );
695 composerTemplateElem.appendChild( composerLabelElem );
699 QList<QgsLayoutItemHtml *> composerHtmlList;
701 QList<QgsLayoutItemHtml *>::const_iterator chIt = composerHtmlList.constBegin();
702 for ( ; chIt != composerHtmlList.constEnd(); ++chIt )
708 QString
id = composerHtml->
frame( 0 )->
id();
712 QDomElement composerHtmlElem = doc.createElement( QStringLiteral(
"ComposerHtml" ) );
713 composerHtmlElem.setAttribute( QStringLiteral(
"name" ), id );
714 composerTemplateElem.appendChild( composerHtmlElem );
717 composerTemplatesElem.appendChild( composerTemplateElem );
720 if ( composerTemplatesElem.childNodes().size() == 0 )
721 return QDomElement();
723 return composerTemplatesElem;
729 if ( wfsLayerIds.size() == 0 )
730 return QDomElement();
732 QDomElement wfsLayersElem = doc.createElement( QStringLiteral(
"WFSLayers" ) );
733 for (
int i = 0; i < wfsLayerIds.size(); ++i )
741 QDomElement wfsLayerElem = doc.createElement( QStringLiteral(
"WFSLayer" ) );
744 wfsLayerElem.setAttribute( QStringLiteral(
"name" ), layer->
id() );
748 wfsLayerElem.setAttribute( QStringLiteral(
"name" ), layer->
name() );
750 wfsLayersElem.appendChild( wfsLayerElem );
753 return wfsLayersElem;
760 parentLayer.setAttribute(
761 QStringLiteral(
"queryable" ),
762 hasQueryableLayers( layerIds, wmsLayerInfos ) ? QStringLiteral(
"1" ) : QStringLiteral(
"0" )
766 QMap<QString, QgsRectangle> crsExtents =
combineCrsExtents( layerIds, wmsLayerInfos );
768 appendCrsElementsToLayer( doc, parentLayer, crsExtents.keys(), QStringList() );
769 appendLayerWgs84BoundingRect( doc, parentLayer, wgs84BoundingRect );
770 appendLayerCrsExtents( doc, parentLayer, crsExtents );
772 appendLayersFromTreeGroup( doc, parentLayer, serverIface, project, request, layerTreeGroup, wmsLayerInfos, projectSettings, parentDateRanges );
779 QDomElement layerParentElem = doc.createElement( QStringLiteral(
"Layer" ) );
783 if ( rootLayerName.isEmpty() && !project->
title().isEmpty() )
785 rootLayerName = project->
title();
788 if ( !rootLayerName.isEmpty() )
790 QDomElement layerParentNameElem = doc.createElement( QStringLiteral(
"Name" ) );
791 QDomText layerParentNameText = doc.createTextNode( rootLayerName );
792 layerParentNameElem.appendChild( layerParentNameText );
793 layerParentElem.appendChild( layerParentNameElem );
797 QDomElement layerParentTitleElem = doc.createElement( QStringLiteral(
"Title" ) );
799 layerParentTitleElem.appendChild( layerParentTitleText );
800 layerParentElem.appendChild( layerParentTitleElem );
804 if ( !rootLayerAbstract.isEmpty() )
806 QDomElement layerParentAbstElem = doc.createElement( QStringLiteral(
"Abstract" ) );
807 QDomText layerParentAbstText = doc.createCDATASection( rootLayerAbstract );
808 layerParentAbstElem.appendChild( layerParentAbstText );
809 layerParentElem.appendChild( layerParentAbstElem );
813 addKeywordListElement( project, doc, layerParentElem );
816 if ( projectSettings )
818 QDomElement treeNameElem = doc.createElement( QStringLiteral(
"TreeName" ) );
819 QDomText treeNameText = doc.createTextNode( project->
title() );
820 treeNameElem.appendChild( treeNameText );
821 layerParentElem.appendChild( treeNameElem );
827 auto outputCrsList = QList<QgsCoordinateReferenceSystem>();
833 outputCrsList.append(
crs );
857 QStringLiteral(
"Error transforming extent: %1" ).arg( cse.
what() ),
858 QStringLiteral(
"Server" ),
864 QMap<QString, QgsRectangle> wmsCrsExtents;
876 layerParentElem.setAttribute(
877 QStringLiteral(
"queryable" ),
881 appendCrsElementsToLayer( doc, layerParentElem, wmsCrsExtents.keys(), QStringList() );
882 appendLayerWgs84BoundingRect( doc, layerParentElem, wmsWgs84BoundingRect );
883 appendLayerCrsExtents( doc, layerParentElem, wmsCrsExtents );
885 QList<QgsDateTimeRange> parentDateRanges;
886 appendLayersFromTreeGroup( doc, layerParentElem, serverIface, project, request, projectLayerTreeRoot, wmsLayerInfos, projectSettings, parentDateRanges );
890 QList<QgsDateTimeRange> parentDateRanges;
891 handleLayersFromTreeGroup( doc, layerParentElem, serverIface, project, request, projectLayerTreeRoot, wmsLayerInfos, projectSettings, parentDateRanges );
894 return layerParentElem;
902 void writeServerProperties( QDomDocument &doc, QDomElement &layerElem,
const QgsProject *project,
const QgsMapLayerServerProperties *serverProperties,
const QString &name,
const QString &version )
904 const QString title = serverProperties->
title();
905 QDomElement titleElem = doc.createElement( QStringLiteral(
"Title" ) );
906 QDomText titleText = doc.createTextNode( !title.isEmpty() ? title : name );
907 titleElem.appendChild( titleText );
908 layerElem.appendChild( titleElem );
910 const QString abstract = serverProperties->
abstract();
911 if ( !abstract.isEmpty() )
913 QDomElement abstractElem = doc.createElement( QStringLiteral(
"Abstract" ) );
914 QDomText abstractText = doc.createTextNode( abstract );
915 abstractElem.appendChild( abstractText );
916 layerElem.appendChild( abstractElem );
921 const QStringList keywords = !serverProperties->
keywordList().isEmpty() ? serverProperties->
keywordList().split(
',' ) : QStringList();
922 if ( !keywords.isEmpty() )
924 QDomElement keywordListElem = doc.createElement( QStringLiteral(
"KeywordList" ) );
925 for (
const QString &keyword : std::as_const( keywords ) )
927 QDomElement keywordElem = doc.createElement( QStringLiteral(
"Keyword" ) );
928 QDomText keywordText = doc.createTextNode( keyword.trimmed() );
929 keywordElem.appendChild( keywordText );
932 keywordElem.setAttribute( QStringLiteral(
"vocabulary" ), QStringLiteral(
"SIA_Geo405" ) );
934 keywordListElem.appendChild( keywordElem );
936 layerElem.appendChild( keywordListElem );
940 const QString dataUrl = serverProperties->
dataUrl();
941 if ( !dataUrl.isEmpty() )
943 QDomElement dataUrlElem = doc.createElement( QStringLiteral(
"DataURL" ) );
944 QDomElement dataUrlFormatElem = doc.createElement( QStringLiteral(
"Format" ) );
945 const QString dataUrlFormat = serverProperties->
dataUrlFormat();
946 QDomText dataUrlFormatText = doc.createTextNode( dataUrlFormat );
947 dataUrlFormatElem.appendChild( dataUrlFormatText );
948 dataUrlElem.appendChild( dataUrlFormatElem );
949 QDomElement dataORElem = doc.createElement( QStringLiteral(
"OnlineResource" ) );
950 dataORElem.setAttribute( QStringLiteral(
"xmlns:xlink" ), QStringLiteral(
"http://www.w3.org/1999/xlink" ) );
951 dataORElem.setAttribute( QStringLiteral(
"xlink:type" ), QStringLiteral(
"simple" ) );
952 dataORElem.setAttribute( QStringLiteral(
"xlink:href" ), dataUrl );
953 dataUrlElem.appendChild( dataORElem );
954 layerElem.appendChild( dataUrlElem );
958 const QString attribution = serverProperties->
attribution();
959 if ( !attribution.isEmpty() )
961 QDomElement attribElem = doc.createElement( QStringLiteral(
"Attribution" ) );
962 QDomElement attribTitleElem = doc.createElement( QStringLiteral(
"Title" ) );
963 QDomText attribText = doc.createTextNode( attribution );
964 attribTitleElem.appendChild( attribText );
965 attribElem.appendChild( attribTitleElem );
966 const QString attributionUrl = serverProperties->
attributionUrl();
967 if ( !attributionUrl.isEmpty() )
969 QDomElement attribORElem = doc.createElement( QStringLiteral(
"OnlineResource" ) );
970 attribORElem.setAttribute( QStringLiteral(
"xmlns:xlink" ), QStringLiteral(
"http://www.w3.org/1999/xlink" ) );
971 attribORElem.setAttribute( QStringLiteral(
"xlink:type" ), QStringLiteral(
"simple" ) );
972 attribORElem.setAttribute( QStringLiteral(
"xlink:href" ), attributionUrl );
973 attribElem.appendChild( attribORElem );
975 layerElem.appendChild( attribElem );
979 const QList<QgsServerMetadataUrlProperties::MetadataUrl> metadataUrls = serverProperties->
metadataUrls();
982 QDomElement metaUrlElem = doc.createElement( QStringLiteral(
"MetadataURL" ) );
983 const QString metadataUrlType = metadataUrl.type;
984 if ( version == QLatin1String(
"1.1.1" ) )
986 metaUrlElem.setAttribute( QStringLiteral(
"type" ), metadataUrlType );
988 else if ( metadataUrlType == QLatin1String(
"FGDC" ) )
990 metaUrlElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"FGDC:1998" ) );
992 else if ( metadataUrlType == QLatin1String(
"TC211" ) )
994 metaUrlElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"ISO19115:2003" ) );
998 metaUrlElem.setAttribute( QStringLiteral(
"type" ), metadataUrlType );
1000 const QString metadataUrlFormat = metadataUrl.format;
1001 if ( !metadataUrlFormat.isEmpty() )
1003 QDomElement metaUrlFormatElem = doc.createElement( QStringLiteral(
"Format" ) );
1004 QDomText metaUrlFormatText = doc.createTextNode( metadataUrlFormat );
1005 metaUrlFormatElem.appendChild( metaUrlFormatText );
1006 metaUrlElem.appendChild( metaUrlFormatElem );
1008 QDomElement metaUrlORElem = doc.createElement( QStringLiteral(
"OnlineResource" ) );
1009 metaUrlORElem.setAttribute( QStringLiteral(
"xmlns:xlink" ), QStringLiteral(
"http://www.w3.org/1999/xlink" ) );
1010 metaUrlORElem.setAttribute( QStringLiteral(
"xlink:type" ), QStringLiteral(
"simple" ) );
1011 metaUrlORElem.setAttribute( QStringLiteral(
"xlink:href" ), metadataUrl.url );
1012 metaUrlElem.appendChild( metaUrlORElem );
1013 layerElem.appendChild( metaUrlElem );
1017 void writeLegendUrl( QDomDocument &doc, QDomElement &styleElem,
const QString &legendUrl,
const QString &legendUrlFormat,
const QString &name,
const QString &styleName,
const QgsProject *project,
const QgsWmsRequest &request,
const QgsServerSettings *settings )
1020 QDomElement getLayerLegendGraphicElem = doc.createElement( QStringLiteral(
"LegendURL" ) );
1022 QString customHrefString = legendUrl;
1024 QStringList getLayerLegendGraphicFormats;
1025 if ( !customHrefString.isEmpty() )
1027 getLayerLegendGraphicFormats << legendUrlFormat;
1031 getLayerLegendGraphicFormats << QStringLiteral(
"image/png" );
1034 for (
const QString &getLayerLegendGraphicFormat : std::as_const( getLayerLegendGraphicFormats ) )
1036 QDomElement getLayerLegendGraphicFormatElem = doc.createElement( QStringLiteral(
"Format" ) );
1037 QDomText getLayerLegendGraphicFormatText = doc.createTextNode( getLayerLegendGraphicFormat );
1038 getLayerLegendGraphicFormatElem.appendChild( getLayerLegendGraphicFormatText );
1039 getLayerLegendGraphicElem.appendChild( getLayerLegendGraphicFormatElem );
1043 if ( customHrefString.isEmpty() )
1046 QUrl href =
serviceUrl( request, project, *settings );
1047 const QString hrefString = href.toString() + ( href.hasQuery() ?
"&" :
"?" );
1049 QUrl mapUrl( hrefString );
1050 QUrlQuery mapUrlQuery( mapUrl.query() );
1051 mapUrlQuery.addQueryItem( QStringLiteral(
"SERVICE" ), QStringLiteral(
"WMS" ) );
1052 mapUrlQuery.addQueryItem( QStringLiteral(
"VERSION" ), request.wmsParameters().version() );
1053 mapUrlQuery.addQueryItem( QStringLiteral(
"REQUEST" ), QStringLiteral(
"GetLegendGraphic" ) );
1054 mapUrlQuery.addQueryItem( QStringLiteral(
"LAYER" ), name );
1055 mapUrlQuery.addQueryItem( QStringLiteral(
"FORMAT" ), QStringLiteral(
"image/png" ) );
1056 mapUrlQuery.addQueryItem( QStringLiteral(
"STYLE" ), styleName );
1057 if ( request.wmsParameters().version() == QLatin1String(
"1.3.0" ) )
1059 mapUrlQuery.addQueryItem( QStringLiteral(
"SLD_VERSION" ), QStringLiteral(
"1.1.0" ) );
1061 mapUrl.setQuery( mapUrlQuery );
1062 customHrefString = mapUrl.toString();
1065 QDomElement getLayerLegendGraphicORElem = doc.createElement( QStringLiteral(
"OnlineResource" ) );
1066 getLayerLegendGraphicORElem.setAttribute( QStringLiteral(
"xmlns:xlink" ), QStringLiteral(
"http://www.w3.org/1999/xlink" ) );
1067 getLayerLegendGraphicORElem.setAttribute( QStringLiteral(
"xlink:type" ), QStringLiteral(
"simple" ) );
1068 getLayerLegendGraphicORElem.setAttribute( QStringLiteral(
"xlink:href" ), customHrefString );
1069 getLayerLegendGraphicElem.appendChild( getLayerLegendGraphicORElem );
1070 styleElem.appendChild( getLayerLegendGraphicElem );
1073 QDomElement createStyleElement( QDomDocument &doc,
const QString &styleName )
1075 QDomElement styleElem = doc.createElement( QStringLiteral(
"Style" ) );
1076 QDomElement styleNameElem = doc.createElement( QStringLiteral(
"Name" ) );
1077 QDomText styleNameText = doc.createTextNode( styleName );
1078 styleNameElem.appendChild( styleNameText );
1079 QDomElement styleTitleElem = doc.createElement( QStringLiteral(
"Title" ) );
1080 QDomText styleTitleText = doc.createTextNode( styleName );
1081 styleTitleElem.appendChild( styleTitleText );
1082 styleElem.appendChild( styleNameElem );
1083 styleElem.appendChild( styleTitleElem );
1089 bool writeTimeDimensionNode( QDomDocument &doc, QDomElement &layerElem,
const QList<QgsDateTimeRange> &dateRanges )
1097 const bool hasDateTime = std::any_of( dateRanges.constBegin(), dateRanges.constEnd(), [](
const QgsDateTimeRange &r ) { return r.begin().time() != QTime( 0, 0 )
1098 || ( !r.isInstant() && r.end().time() != QTime( 0, 0 ) ); } );
1100 const QString dateFormat = hasDateTime ? QStringLiteral(
"yyyy-MM-ddTHH:mm:ss" ) : QStringLiteral(
"yyyy-MM-dd" );
1102 QStringList strValues;
1106 if ( range.begin().isValid() && range.end().isValid() )
1108 strValues << ( range.isInstant() ? range.begin().toString( dateFormat ) : QStringLiteral(
"%1/%2" ).arg( range.begin().toString( dateFormat ) ).arg( range.end().toString( dateFormat ) ) );
1112 QDomElement dimElem = doc.createElement( QStringLiteral(
"Dimension" ) );
1113 dimElem.setAttribute( QStringLiteral(
"name" ), QStringLiteral(
"TIME" ) );
1114 dimElem.setAttribute( QStringLiteral(
"units" ), QStringLiteral(
"ISO8601" ) );
1115 QDomText dimValuesText = doc.createTextNode( strValues.join( QChar(
',' ) ) );
1116 dimElem.appendChild( dimValuesText );
1118 layerElem.appendChild( dimElem );
1120 return !hasDateTime;
1123 void appendLayersFromTreeGroup( 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 )
1125 const QString version = request.wmsParameters().version();
1130 QList<QgsLayerTreeNode *> layerTreeGroupChildren = layerTreeGroup->
children();
1131 for (
int i = 0; i < layerTreeGroupChildren.size(); ++i )
1134 QDomElement layerElem = doc.createElement( QStringLiteral(
"Layer" ) );
1136 if ( projectSettings )
1138 layerElem.setAttribute( QStringLiteral(
"visible" ), treeNode->
isVisible() );
1140 layerElem.setAttribute( QStringLiteral(
"expanded" ), treeNode->
isExpanded() );
1147 QString name = treeGroupChild->
name();
1148 if ( restrictedLayers.contains( name ) )
1153 if ( projectSettings )
1155 layerElem.setAttribute( QStringLiteral(
"mutuallyExclusive" ), treeGroupChild->
isMutuallyExclusive() );
1160 if ( !skipNameForGroup )
1162 QDomElement nameElem = doc.createElement( QStringLiteral(
"Name" ) );
1164 if ( !shortName.isEmpty() )
1165 nameText = doc.createTextNode( shortName );
1167 nameText = doc.createTextNode( name );
1168 nameElem.appendChild( nameText );
1169 layerElem.appendChild( nameElem );
1172 writeServerProperties( doc, layerElem, project, treeGroupChild->
serverProperties(), name, version );
1175 const QString styleName = QStringLiteral(
"default" );
1176 QDomElement styleElem = createStyleElement( doc, styleName );
1179 layerElem.appendChild( styleElem );
1182 if ( projectSettings )
1184 QDomElement treeNameElem = doc.createElement( QStringLiteral(
"TreeName" ) );
1185 QDomText treeNameText = doc.createTextNode( name );
1186 treeNameElem.appendChild( treeNameText );
1187 layerElem.appendChild( treeNameElem );
1190 QList<QgsDateTimeRange> childrenDateRanges;
1191 handleLayersFromTreeGroup( doc, layerElem, serverIface, project, request, treeGroupChild, wmsLayerInfos, projectSettings, childrenDateRanges );
1195 writeTimeDimensionNode( doc, layerElem, childrenDateRanges );
1196 parentDateRanges.append( childrenDateRanges );
1200 if ( layerElem.elementsByTagName( QStringLiteral(
"Layer" ) ).length() == 0 )
1209 if ( !wmsLayerInfos.contains( treeLayer->
layerId() ) )
1216 layerElem.setAttribute(
1217 QStringLiteral(
"queryable" ),
1218 layerInfos.
queryable ? QStringLiteral(
"1" ) : QStringLiteral(
"0" )
1221 QDomElement nameElem = doc.createElement( QStringLiteral(
"Name" ) );
1222 QDomText nameText = doc.createTextNode( layerInfos.
name );
1223 nameElem.appendChild( nameText );
1224 layerElem.appendChild( nameElem );
1231 appendCrsElementsToLayer( doc, layerElem, layerInfos.
crsExtents.keys(), QStringList() );
1235 appendLayerCrsExtents( doc, layerElem, layerInfos.
crsExtents );
1239 appendLayerStyles( doc, layerElem, layerInfos, project, request, serverIface->
serverSettings() );
1245 auto formatScale = [](
double value ) {
1246 const thread_local QRegularExpression trailingZeroRegEx = QRegularExpression( QStringLiteral(
"0+$" ) );
1247 const thread_local QRegularExpression trailingPointRegEx = QRegularExpression( QStringLiteral(
"[.]+$" ) );
1248 return QString::number( value,
'f' ).remove( trailingZeroRegEx ).remove( trailingPointRegEx );
1251 if ( version == QLatin1String(
"1.1.1" ) )
1254 double SCALE_TO_SCALEHINT =
OGC_PX_M * M_SQRT2;
1256 QDomElement scaleHintElem = doc.createElement( QStringLiteral(
"ScaleHint" ) );
1257 scaleHintElem.setAttribute( QStringLiteral(
"min" ), formatScale( layerInfos.
maxScale * SCALE_TO_SCALEHINT ) );
1258 scaleHintElem.setAttribute( QStringLiteral(
"max" ), formatScale( layerInfos.
minScale * SCALE_TO_SCALEHINT ) );
1259 layerElem.appendChild( scaleHintElem );
1263 QDomElement minScaleElem = doc.createElement( QStringLiteral(
"MinScaleDenominator" ) );
1264 QDomText minScaleText = doc.createTextNode( formatScale( layerInfos.
maxScale ) );
1265 minScaleElem.appendChild( minScaleText );
1266 layerElem.appendChild( minScaleElem );
1268 QDomElement maxScaleElem = doc.createElement( QStringLiteral(
"MaxScaleDenominator" ) );
1269 QDomText maxScaleText = doc.createTextNode( formatScale( layerInfos.
minScale ) );
1270 maxScaleElem.appendChild( maxScaleText );
1271 layerElem.appendChild( maxScaleElem );
1275 bool timeDimensionAdded {
false };
1282 const QList<QgsMapLayerServerProperties::WmsDimensionInfo> wmsDims = serverProperties->
wmsDimensions();
1287 if ( fieldIndex == -1 )
1292 QSet<QVariant> uniqueValues = vl->
uniqueValues( fieldIndex );
1295 if ( !dim.endFieldName.isEmpty() )
1297 int endFieldIndex = vl->
fields().
indexOf( dim.endFieldName );
1299 if ( endFieldIndex == -1 )
1303 uniqueValues.unite( vl->
uniqueValues( endFieldIndex ) );
1306 QList<QVariant> values = qgis::setToList( uniqueValues );
1307 std::sort( values.begin(), values.end() );
1309 QDomElement dimElem = doc.createElement( QStringLiteral(
"Dimension" ) );
1310 dimElem.setAttribute( QStringLiteral(
"name" ), dim.name );
1312 if ( dim.name.toUpper() == QLatin1String(
"TIME" ) )
1314 timeDimensionAdded =
true;
1317 if ( !dim.units.isEmpty() )
1319 dimElem.setAttribute( QStringLiteral(
"units" ), dim.units );
1321 if ( !dim.unitSymbol.isEmpty() )
1323 dimElem.setAttribute( QStringLiteral(
"unitSymbol" ), dim.unitSymbol );
1325 if ( !values.isEmpty() && dim.defaultDisplayType == QgsMapLayerServerProperties::WmsDimensionInfo::MinValue )
1327 dimElem.setAttribute( QStringLiteral(
"default" ), values.first().toString() );
1329 else if ( !values.isEmpty() && dim.defaultDisplayType == QgsMapLayerServerProperties::WmsDimensionInfo::MaxValue )
1331 dimElem.setAttribute( QStringLiteral(
"default" ), values.last().toString() );
1333 else if ( dim.defaultDisplayType == QgsMapLayerServerProperties::WmsDimensionInfo::ReferenceValue )
1335 dimElem.setAttribute( QStringLiteral(
"default" ), dim.referenceValue.toString() );
1337 dimElem.setAttribute( QStringLiteral(
"multipleValues" ), QStringLiteral(
"1" ) );
1338 dimElem.setAttribute( QStringLiteral(
"nearestValue" ), QStringLiteral(
"0" ) );
1339 if ( projectSettings )
1341 dimElem.setAttribute( QStringLiteral(
"fieldName" ), dim.fieldName );
1342 dimElem.setAttribute( QStringLiteral(
"endFieldName" ), dim.endFieldName );
1345 QStringList strValues;
1346 for (
const QVariant &v : values )
1348 strValues << v.toString();
1350 QDomText dimValuesText = doc.createTextNode( strValues.join( QLatin1String(
", " ) ) );
1351 dimElem.appendChild( dimValuesText );
1352 layerElem.appendChild( dimElem );
1357 if ( !timeDimensionAdded
1365 const bool isDateList = writeTimeDimensionNode( doc, layerElem, allRanges );
1367 parentDateRanges.append( allRanges );
1369 QDomElement timeExtentElem = doc.createElement( QStringLiteral(
"Extent" ) );
1370 timeExtentElem.setAttribute( QStringLiteral(
"name" ), QStringLiteral(
"TIME" ) );
1376 extent = QStringLiteral(
"%1/%2" ).arg( timeExtent.begin().date().toString( Qt::DateFormat::ISODate ), timeExtent.end().date().toString( Qt::DateFormat::ISODate ) );
1380 extent = QStringLiteral(
"%1/%2" ).arg( timeExtent.begin().toString( Qt::DateFormat::ISODate ), timeExtent.end().toString( Qt::DateFormat::ISODate ) );
1382 QDomText extentValueText = doc.createTextNode( extent );
1383 timeExtentElem.appendChild( extentValueText );
1384 layerElem.appendChild( timeExtentElem );
1387 if ( projectSettings )
1389 appendLayerProjectSettings( doc, layerElem, l );
1393 parentLayer.appendChild( layerElem );
1399 for (
const QString &styleName : std::as_const( layerInfos.styles ) )
1401 QDomElement styleElem = createStyleElement( doc, styleName );
1403 writeLegendUrl( doc, styleElem, layerInfos.
legendUrl, layerInfos.
legendUrlFormat, layerInfos.
name, styleName, project, request, settings );
1405 layerElem.appendChild( styleElem );
1409 void appendCrsElementsToLayer( QDomDocument &doc, QDomElement &layerElement,
const QStringList &crsList,
const QStringList &constrainedCrsList )
1411 if ( layerElement.isNull() )
1416 const QString version = doc.documentElement().attribute( QStringLiteral(
"version" ) );
1419 QDomElement titleElement = layerElement.firstChildElement( QStringLiteral(
"Title" ) );
1420 QDomElement abstractElement = layerElement.firstChildElement( QStringLiteral(
"Abstract" ) );
1421 QDomElement keywordListElement = layerElement.firstChildElement( QStringLiteral(
"KeywordList" ) );
1422 QDomElement CRSPrecedingElement = !keywordListElement.isNull() ? keywordListElement : !abstractElement.isNull() ? abstractElement
1425 if ( CRSPrecedingElement.isNull() )
1428 const QDomElement keyElement = layerElement.firstChildElement( QStringLiteral(
"KeywordList" ) );
1429 CRSPrecedingElement = keyElement;
1433 if ( !constrainedCrsList.isEmpty() )
1435 for (
int i = constrainedCrsList.size() - 1; i >= 0; --i )
1437 appendCrsElementToLayer( doc, layerElement, CRSPrecedingElement, constrainedCrsList.at( i ) );
1442 for (
const QString &
crs : crsList )
1444 appendCrsElementToLayer( doc, layerElement, CRSPrecedingElement,
crs );
1450 if ( version == QLatin1String(
"1.3.0" ) )
1452 appendCrsElementToLayer( doc, layerElement, CRSPrecedingElement, QString(
"CRS:84" ) );
1456 void appendCrsElementToLayer( QDomDocument &doc, QDomElement &layerElement,
const QDomElement &precedingElement,
const QString &crsText )
1458 if ( crsText.isEmpty() )
1460 const QString version = doc.documentElement().attribute( QStringLiteral(
"version" ) );
1461 QDomElement crsElement = doc.createElement( version == QLatin1String(
"1.1.1" ) ?
"SRS" :
"CRS" );
1462 QDomText crsTextNode = doc.createTextNode( crsText );
1463 crsElement.appendChild( crsTextNode );
1464 layerElement.insertAfter( crsElement, precedingElement );
1467 void appendLayerWgs84BoundingRect( QDomDocument &doc, QDomElement &layerElem,
const QgsRectangle &wgs84BoundingRect )
1470 if ( wgs84BoundingRect.
isNull() )
1476 QDomElement ExGeoBBoxElement;
1477 const int wgs84precision = 6;
1478 const QString version = doc.documentElement().attribute( QStringLiteral(
"version" ) );
1479 if ( version == QLatin1String(
"1.1.1" ) )
1481 ExGeoBBoxElement = doc.createElement( QStringLiteral(
"LatLonBoundingBox" ) );
1489 ExGeoBBoxElement = doc.createElement( QStringLiteral(
"EX_GeographicBoundingBox" ) );
1490 QDomElement wBoundLongitudeElement = doc.createElement( QStringLiteral(
"westBoundLongitude" ) );
1492 wBoundLongitudeElement.appendChild( wBoundLongitudeText );
1493 ExGeoBBoxElement.appendChild( wBoundLongitudeElement );
1494 QDomElement eBoundLongitudeElement = doc.createElement( QStringLiteral(
"eastBoundLongitude" ) );
1496 eBoundLongitudeElement.appendChild( eBoundLongitudeText );
1497 ExGeoBBoxElement.appendChild( eBoundLongitudeElement );
1498 QDomElement sBoundLatitudeElement = doc.createElement( QStringLiteral(
"southBoundLatitude" ) );
1500 sBoundLatitudeElement.appendChild( sBoundLatitudeText );
1501 ExGeoBBoxElement.appendChild( sBoundLatitudeElement );
1502 QDomElement nBoundLatitudeElement = doc.createElement( QStringLiteral(
"northBoundLatitude" ) );
1504 nBoundLatitudeElement.appendChild( nBoundLatitudeText );
1505 ExGeoBBoxElement.appendChild( nBoundLatitudeElement );
1508 const QDomElement lastCRSElem = layerElem.lastChildElement( version == QLatin1String(
"1.1.1" ) ?
"SRS" :
"CRS" );
1509 if ( !lastCRSElem.isNull() )
1511 layerElem.insertAfter( ExGeoBBoxElement, lastCRSElem );
1515 layerElem.appendChild( ExGeoBBoxElement );
1519 void appendLayerCrsExtents( QDomDocument &doc, QDomElement &layerElem,
const QMap<QString, QgsRectangle> &crsExtents )
1521 const QString version = doc.documentElement().attribute( QStringLiteral(
"version" ) );
1523 const auto &keys = crsExtents.keys();
1524 for (
const QString &crsText : std::as_const( keys ) )
1529 if ( crsExtent.isNull() )
1541 QDomElement bBoxElement = doc.createElement( QStringLiteral(
"BoundingBox" ) );
1544 bBoxElement.setAttribute( version == QLatin1String(
"1.1.1" ) ?
"SRS" :
"CRS",
crs.authid() );
1557 QDomElement lastBBoxElem = layerElem.lastChildElement( QStringLiteral(
"BoundingBox" ) );
1558 if ( !lastBBoxElem.isNull() )
1560 layerElem.insertAfter( bBoxElement, lastBBoxElem );
1564 lastBBoxElem = layerElem.lastChildElement( version == QLatin1String(
"1.1.1" ) ?
"LatLonBoundingBox" :
"EX_GeographicBoundingBox" );
1565 if ( !lastBBoxElem.isNull() )
1567 layerElem.insertAfter( bBoxElement, lastBBoxElem );
1571 layerElem.appendChild( bBoxElement );
1579#ifdef HAVE_SERVER_PYTHON_PLUGINS
1582 ( void ) serverIface;
1587 QStringList layerList;
1590 QList<QgsMapLayer *> projectLayerOrder = projectLayerTreeRoot->
layerOrder();
1591 for (
int i = 0; i < projectLayerOrder.size(); ++i )
1595 if ( restrictedLayers.contains( l->
name() ) )
1599#ifdef HAVE_SERVER_PYTHON_PLUGINS
1605 QString wmsName = l->
name();
1615 layerList << wmsName;
1618 if ( !layerList.isEmpty() )
1620 QStringList reversedList;
1621 reversedList.reserve( layerList.size() );
1622 for (
int i = layerList.size() - 1; i >= 0; --i )
1623 reversedList << layerList[i];
1625 QDomElement layerDrawingOrderElem = doc.createElement( QStringLiteral(
"LayerDrawingOrder" ) );
1626 QDomText drawingOrderText = doc.createTextNode( reversedList.join(
',' ) );
1627 layerDrawingOrderElem.appendChild( drawingOrderText );
1628 parentElem.appendChild( layerDrawingOrderElem );
1632 void appendLayerProjectSettings( QDomDocument &doc, QDomElement &layerElem,
QgsMapLayer *currentLayer )
1634 if ( !currentLayer )
1640 QDomElement treeNameElem = doc.createElement( QStringLiteral(
"TreeName" ) );
1641 QDomText treeNameText = doc.createTextNode( currentLayer->
name() );
1642 treeNameElem.appendChild( treeNameText );
1643 layerElem.appendChild( treeNameElem );
1645 switch ( currentLayer->
type() )
1651 int displayFieldIdx = -1;
1652 QString displayField = QStringLiteral(
"maptip" );
1654 if ( exp.isField() )
1661 QDomElement attributesElem = doc.createElement( QStringLiteral(
"Attributes" ) );
1663 for (
int idx = 0; idx < layerFields.
count(); ++idx )
1671 if ( idx == displayFieldIdx )
1675 QDomElement attributeElem = doc.createElement( QStringLiteral(
"Attribute" ) );
1676 attributeElem.setAttribute( QStringLiteral(
"name" ), field.
name() );
1677 attributeElem.setAttribute( QStringLiteral(
"type" ), QVariant::typeToName( field.
type() ) );
1678 attributeElem.setAttribute( QStringLiteral(
"typeName" ), field.
typeName() );
1679 QString alias = field.
alias();
1680 if ( !alias.isEmpty() )
1682 attributeElem.setAttribute( QStringLiteral(
"alias" ), alias );
1686 attributeElem.setAttribute( QStringLiteral(
"editType" ), vLayer->
editorWidgetSetup( idx ).
type() );
1687 attributeElem.setAttribute( QStringLiteral(
"comment" ), field.
comment() );
1688 attributeElem.setAttribute( QStringLiteral(
"length" ), field.
length() );
1689 attributeElem.setAttribute( QStringLiteral(
"precision" ), field.
precision() );
1690 attributesElem.appendChild( attributeElem );
1694 layerElem.setAttribute( QStringLiteral(
"displayField" ), displayField );
1698 if ( pkAttributes.size() > 0 )
1700 QDomElement pkElem = doc.createElement( QStringLiteral(
"PrimaryKey" ) );
1701 QgsAttributeList::const_iterator pkIt = pkAttributes.constBegin();
1702 for ( ; pkIt != pkAttributes.constEnd(); ++pkIt )
1704 QDomElement pkAttributeElem = doc.createElement( QStringLiteral(
"PrimaryKeyAttribute" ) );
1705 QDomText pkAttName = doc.createTextNode( layerFields.
at( *pkIt ).
name() );
1706 pkAttributeElem.appendChild( pkAttName );
1707 pkElem.appendChild( pkAttributeElem );
1709 layerElem.appendChild( pkElem );
1716 layerElem.setAttribute( QStringLiteral(
"opacity" ), QString::number( vLayer->
opacity() ) );
1718 layerElem.appendChild( attributesElem );
1725 if ( provider && provider->
name() ==
"wms" )
1728 QVariant wmsBackgroundLayer = currentLayer->
customProperty( QStringLiteral(
"WMSBackgroundLayer" ), false );
1729 QDomElement wmsBackgroundLayerElem = doc.createElement(
"WMSBackgroundLayer" );
1730 QDomText wmsBackgroundLayerText = doc.createTextNode( wmsBackgroundLayer.toBool() ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) );
1731 wmsBackgroundLayerElem.appendChild( wmsBackgroundLayerText );
1732 layerElem.appendChild( wmsBackgroundLayerElem );
1735 QVariant wmsPublishDataSourceUrl = currentLayer->
customProperty( QStringLiteral(
"WMSPublishDataSourceUrl" ),
false );
1736 if ( wmsPublishDataSourceUrl.toBool() )
1738 bool tiled = qobject_cast<const QgsRasterDataProvider *>( provider )
1739 ? !qobject_cast<const QgsRasterDataProvider *>( provider )->nativeResolutions().isEmpty()
1742 QDomElement dataSourceElem = doc.createElement( tiled ? QStringLiteral(
"WMTSDataSource" ) : QStringLiteral(
"WMSDataSource" ) );
1743 QDomText dataSourceUri = doc.createTextNode( provider->
dataSourceUri() );
1744 dataSourceElem.appendChild( dataSourceUri );
1745 layerElem.appendChild( dataSourceElem );
1749 QVariant wmsPrintLayer = currentLayer->
customProperty( QStringLiteral(
"WMSPrintLayer" ) );
1750 if ( wmsPrintLayer.isValid() )
1752 QDomElement wmsPrintLayerElem = doc.createElement(
"WMSPrintLayer" );
1753 QDomText wmsPrintLayerText = doc.createTextNode( wmsPrintLayer.toString() );
1754 wmsPrintLayerElem.appendChild( wmsPrintLayerText );
1755 layerElem.appendChild( wmsPrintLayerElem );
1761 if ( rasterRenderer )
1763 layerElem.setAttribute( QStringLiteral(
"opacity" ), QString::number( rasterRenderer->
opacity() ) );
1779 void addKeywordListElement(
const QgsProject *project, QDomDocument &doc, QDomElement &parent )
1783 QDomElement keywordsElem = doc.createElement( QStringLiteral(
"KeywordList" ) );
1785 QDomElement keywordElem = doc.createElement( QStringLiteral(
"Keyword" ) );
1786 keywordElem.setAttribute( QStringLiteral(
"vocabulary" ), QStringLiteral(
"ISO" ) );
1787 QDomText keywordText = doc.createTextNode( QStringLiteral(
"infoMapAccessService" ) );
1788 keywordElem.appendChild( keywordText );
1789 keywordsElem.appendChild( keywordElem );
1790 parent.appendChild( keywordsElem );
1792 for (
const QString &keyword : std::as_const( keywords ) )
1794 if ( !keyword.isEmpty() )
1796 keywordElem = doc.createElement( QStringLiteral(
"Keyword" ) );
1797 keywordText = doc.createTextNode( keyword );
1798 keywordElem.appendChild( keywordText );
1801 keywordElem.setAttribute( QStringLiteral(
"vocabulary" ), QStringLiteral(
"SIA_Geo405" ) );
1803 keywordsElem.appendChild( keywordElem );
1806 parent.appendChild( keywordsElem );
1810 bool hasQueryableLayers(
const QStringList &layerIds,
const QMap<QString, QgsWmsLayerInfos> &wmsLayerInfos )
1812 for (
const QString &
id : std::as_const( layerIds ) )
1814 if ( !wmsLayerInfos.contains(
id ) )
1818 if ( wmsLayerInfos[
id].queryable )
1831 for (
const QString &
id : std::as_const( layerIds ) )
1833 if ( !wmsLayerInfos.contains(
id ) )
1838 QgsRectangle rect = wmsLayerInfos[id].wgs84BoundingRect;
1863 QMap<QString, QgsRectangle>
combineCrsExtents(
const QStringList &layerIds,
const QMap<QString, QgsWmsLayerInfos> &wmsLayerInfos )
1865 QMap<QString, QgsRectangle> combined;
1867 for (
const QString &
id : std::as_const( layerIds ) )
1869 if ( !wmsLayerInfos.contains(
id ) )
1875 const auto keys = layerInfos.
crsExtents.keys();
1876 for (
const QString &
crs : std::as_const( keys ) )
1889 if ( !combined.contains(
crs ) )
1891 combined[
crs] = rect;
1863 QMap<QString, QgsRectangle>
combineCrsExtents(
const QStringList &layerIds,
const QMap<QString, QgsWmsLayerInfos> &wmsLayerInfos ) {
…}
@ 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 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.
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 its value from a feature's field.
Handles 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.
Qgis::FieldConfigurationFlags configurationFlags
Container of fields for a vector layer.
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.
Layer tree node points to a map layer.
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.
Base class for nodes in a layer tree.
@ 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.
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())
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.
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.
Represents a vector layer which manages a vector based dataset.
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.
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(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.
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.
QList< int > QgsAttributeList
const QgsCoordinateReferenceSystem & crs
Setting to define QGIS Server WMS Dimension.