47 void appendLayerProjectSettings( QDomDocument &doc, QDomElement &layerElem,
QgsMapLayer *currentLayer );
49 void appendDrawingOrder( QDomDocument &doc, QDomElement &parentElem,
QgsServerInterface *serverIface,
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,
57 const QString &crsText );
59 void appendCrsElementsToLayer( QDomDocument &doc, QDomElement &layerElement,
60 const QStringList &crsList,
const QStringList &constrainedCrsList );
62 void appendLayerStyles( QDomDocument &doc, QDomElement &layerElem,
const QgsWmsLayerInfos &layerInfos,
65 void appendLayersFromTreeGroup( QDomDocument &doc,
66 QDomElement &parentLayer,
69 const QgsWmsRequest &request,
71 const QMap< QString, QgsWmsLayerInfos > &wmsLayerInfos,
72 bool projectSettings );
74 void addKeywordListElement(
const QgsProject *project, QDomDocument &doc, QDomElement &parent );
81 bool projectSettings )
83#ifdef HAVE_SERVER_PYTHON_PLUGINS
88 const QDomDocument *capabilitiesDocument =
nullptr;
93 QStringList cacheKeyList;
94 cacheKeyList << ( projectSettings ? QStringLiteral(
"projectSettings" ) : request.
wmsParameters().
version() );
98#ifdef HAVE_SERVER_PYTHON_PLUGINS
102 QString cacheKey = cacheKeyList.join(
'-' );
104#ifdef HAVE_SERVER_PYTHON_PLUGINS
106 if ( cacheManager && cacheManager->
getCachedDocument( &doc, project, request, accessControl ) )
108 capabilitiesDocument = &doc;
111 if ( !capabilitiesDocument && cache )
116 if ( !capabilitiesDocument )
118 QgsMessageLog::logMessage( QStringLiteral(
"WMS capabilities document not found in cache" ), QStringLiteral(
"Server" ) );
120 doc =
getCapabilities( serverIface, project, request, projectSettings );
122#ifdef HAVE_SERVER_PYTHON_PLUGINS
126 capabilitiesDocument = &doc;
131 if ( !capabilitiesDocument )
136 if ( !capabilitiesDocument )
138 capabilitiesDocument = &doc;
150 response.
setHeader( QStringLiteral(
"Content-Type" ), QStringLiteral(
"text/xml; charset=utf-8" ) );
151 response.
write( capabilitiesDocument->toByteArray() );
156 bool projectSettings )
159 QDomElement wmsCapabilitiesElement;
165 QString hrefString = href.toString();
166 hrefString.append( href.hasQuery() ?
"&" :
"?" );
169 QDomProcessingInstruction xmlDeclaration = doc.createProcessingInstruction( QStringLiteral(
"xml" ),
170 QStringLiteral(
"version=\"1.0\" encoding=\"utf-8\"" ) );
173 std::function < void ( QDomElement &,
const QString & ) > appendFormat = [&doc]( QDomElement & elem,
const QString & format )
175 QDomElement formatElem = doc.createElement( QStringLiteral(
"Format" ) );
176 formatElem.appendChild( doc.createTextNode( format ) );
177 elem.appendChild( formatElem );
182 doc = QDomDocument( QStringLiteral(
"WMT_MS_Capabilities SYSTEM 'http://schemas.opengis.net/wms/1.1.1/WMS_MS_Capabilities.dtd'" ) );
183 doc.appendChild( xmlDeclaration );
184 wmsCapabilitiesElement = doc.createElement( QStringLiteral(
"WMT_MS_Capabilities" ) );
188 doc.appendChild( xmlDeclaration );
189 wmsCapabilitiesElement = doc.createElement( QStringLiteral(
"WMS_Capabilities" ) );
190 wmsCapabilitiesElement.setAttribute( QStringLiteral(
"xmlns" ), QStringLiteral(
"http://www.opengis.net/wms" ) );
191 wmsCapabilitiesElement.setAttribute( QStringLiteral(
"xmlns:sld" ), QStringLiteral(
"http://www.opengis.net/sld" ) );
192 wmsCapabilitiesElement.setAttribute( QStringLiteral(
"xmlns:qgs" ), QStringLiteral(
"http://www.qgis.org/wms" ) );
193 wmsCapabilitiesElement.setAttribute( QStringLiteral(
"xmlns:xsi" ), QStringLiteral(
"http://www.w3.org/2001/XMLSchema-instance" ) );
194 QString schemaLocation = QStringLiteral(
"http://www.opengis.net/wms" );
195 schemaLocation += QLatin1String(
" http://schemas.opengis.net/wms/1.3.0/capabilities_1_3_0.xsd" );
196 schemaLocation += QLatin1String(
" http://www.opengis.net/sld" );
197 schemaLocation += QLatin1String(
" http://schemas.opengis.net/sld/1.1.0/sld_capabilities.xsd" );
201 wmsCapabilitiesElement.setAttribute( QStringLiteral(
"xmlns:inspire_common" ), QStringLiteral(
"http://inspire.ec.europa.eu/schemas/common/1.0" ) );
202 wmsCapabilitiesElement.setAttribute( QStringLiteral(
"xmlns:inspire_vs" ), QStringLiteral(
"http://inspire.ec.europa.eu/schemas/inspire_vs/1.0" ) );
203 schemaLocation += QLatin1String(
" http://inspire.ec.europa.eu/schemas/inspire_vs/1.0" );
204 schemaLocation += QLatin1String(
" http://inspire.ec.europa.eu/schemas/inspire_vs/1.0/inspire_vs.xsd" );
207 schemaLocation += QLatin1String(
" http://www.qgis.org/wms" );
208 schemaLocation +=
" " + hrefString +
"SERVICE=WMS&REQUEST=GetSchemaExtension";
210 wmsCapabilitiesElement.setAttribute( QStringLiteral(
"xsi:schemaLocation" ), schemaLocation );
212 wmsCapabilitiesElement.setAttribute( QStringLiteral(
"version" ), request.
wmsParameters().
version() );
213 doc.appendChild( wmsCapabilitiesElement );
219 QDomElement capabilityElement =
getCapabilityElement( doc, project, request, projectSettings, serverIface );
220 wmsCapabilitiesElement.appendChild( capabilityElement );
222 if ( projectSettings )
231 capabilityElement.appendChild(
235 if ( projectSettings )
237 appendDrawingOrder( doc, capabilityElement, serverIface, project );
247 QDomElement serviceElem = doc.createElement( QStringLiteral(
"Service" ) );
250 QDomElement nameElem = doc.createElement( QStringLiteral(
"Name" ) );
251 QDomText nameText = doc.createTextNode( QStringLiteral(
"WMS" ) );
252 nameElem.appendChild( nameText );
253 serviceElem.appendChild( nameElem );
256 QDomElement titleElem = doc.createElement( QStringLiteral(
"Title" ) );
258 titleElem.appendChild( titleText );
259 serviceElem.appendChild( titleElem );
262 if ( !abstract.isEmpty() )
264 QDomElement abstractElem = doc.createElement( QStringLiteral(
"Abstract" ) );
265 QDomText abstractText = doc.createCDATASection( abstract );
266 abstractElem.appendChild( abstractText );
267 serviceElem.appendChild( abstractElem );
270 addKeywordListElement( project, doc, serviceElem );
273 if ( onlineResource.isEmpty() )
275 onlineResource =
serviceUrl( request, project, *serverSettings ).toString();
277 QDomElement onlineResourceElem = doc.createElement( QStringLiteral(
"OnlineResource" ) );
278 onlineResourceElem.setAttribute( QStringLiteral(
"xmlns:xlink" ), QStringLiteral(
"http://www.w3.org/1999/xlink" ) );
279 onlineResourceElem.setAttribute( QStringLiteral(
"xlink:type" ), QStringLiteral(
"simple" ) );
280 onlineResourceElem.setAttribute( QStringLiteral(
"xlink:href" ), onlineResource );
281 serviceElem.appendChild( onlineResourceElem );
288 if ( !contactPerson.isEmpty() ||
289 !contactOrganization.isEmpty() ||
290 !contactPosition.isEmpty() ||
291 !contactMail.isEmpty() ||
292 !contactPhone.isEmpty() )
295 QDomElement contactInfoElem = doc.createElement( QStringLiteral(
"ContactInformation" ) );
298 if ( !contactPerson.isEmpty() ||
299 !contactOrganization.isEmpty() )
301 QDomElement contactPersonPrimaryElem = doc.createElement( QStringLiteral(
"ContactPersonPrimary" ) );
303 QDomText contactPersonText;
304 if ( !contactPerson.isEmpty() )
306 contactPersonText = doc.createTextNode( contactPerson );
310 contactPersonText = doc.createTextNode( QStringLiteral(
"unknown" ) );
312 QDomElement contactPersonElem = doc.createElement( QStringLiteral(
"ContactPerson" ) );
313 contactPersonElem.appendChild( contactPersonText );
314 contactPersonPrimaryElem.appendChild( contactPersonElem );
316 QDomText contactOrganizationText;
317 if ( !contactOrganization.isEmpty() )
319 contactOrganizationText = doc.createTextNode( contactOrganization );
323 contactOrganizationText = doc.createTextNode( QStringLiteral(
"unknown" ) );
325 QDomElement contactOrganizationElem = doc.createElement( QStringLiteral(
"ContactOrganization" ) );
326 contactOrganizationElem.appendChild( contactOrganizationText );
327 contactPersonPrimaryElem.appendChild( contactOrganizationElem );
329 contactInfoElem.appendChild( contactPersonPrimaryElem );
332 if ( !contactPosition.isEmpty() )
334 QDomElement contactPositionElem = doc.createElement( QStringLiteral(
"ContactPosition" ) );
335 QDomText contactPositionText = doc.createTextNode( contactPosition );
336 contactPositionElem.appendChild( contactPositionText );
337 contactInfoElem.appendChild( contactPositionElem );
340 if ( !contactPhone.isEmpty() )
342 QDomElement phoneElem = doc.createElement( QStringLiteral(
"ContactVoiceTelephone" ) );
343 QDomText phoneText = doc.createTextNode( contactPhone );
344 phoneElem.appendChild( phoneText );
345 contactInfoElem.appendChild( phoneElem );
348 if ( !contactMail.isEmpty() )
350 QDomElement mailElem = doc.createElement( QStringLiteral(
"ContactElectronicMailAddress" ) );
351 QDomText mailText = doc.createTextNode( contactMail );
352 mailElem.appendChild( mailText );
353 contactInfoElem.appendChild( mailElem );
356 serviceElem.appendChild( contactInfoElem );
359 QDomElement feesElem = doc.createElement( QStringLiteral(
"Fees" ) );
360 QDomText feesText = doc.createTextNode( QStringLiteral(
"None" ) );
362 if ( !fees.isEmpty() )
364 feesText = doc.createTextNode( fees );
366 feesElem.appendChild( feesText );
367 serviceElem.appendChild( feesElem );
369 QDomElement accessConstraintsElem = doc.createElement( QStringLiteral(
"AccessConstraints" ) );
370 QDomText accessConstraintsText = doc.createTextNode( QStringLiteral(
"None" ) );
372 if ( !accessConstraints.isEmpty() )
374 accessConstraintsText = doc.createTextNode( accessConstraints );
376 accessConstraintsElem.appendChild( accessConstraintsText );
377 serviceElem.appendChild( accessConstraintsElem );
384 QDomElement maxWidthElem = doc.createElement( QStringLiteral(
"MaxWidth" ) );
385 QDomText maxWidthText = doc.createTextNode( QString::number( maxWidth ) );
386 maxWidthElem.appendChild( maxWidthText );
387 serviceElem.appendChild( maxWidthElem );
393 QDomElement maxHeightElem = doc.createElement( QStringLiteral(
"MaxHeight" ) );
394 QDomText maxHeightText = doc.createTextNode( QString::number( maxHeight ) );
395 maxHeightElem.appendChild( maxHeightText );
396 serviceElem.appendChild( maxHeightElem );
413 QString hrefString = href.toString();
414 hrefString.append( href.hasQuery() ?
"&" :
"?" );
416 QDomElement capabilityElem = doc.createElement( QStringLiteral(
"Capability" ) );
419 QDomElement requestElem = doc.createElement( QStringLiteral(
"Request" ) );
420 capabilityElem.appendChild( requestElem );
422 QDomElement dcpTypeElem = doc.createElement( QStringLiteral(
"DCPType" ) );
423 QDomElement httpElem = doc.createElement( QStringLiteral(
"HTTP" ) );
424 dcpTypeElem.appendChild( httpElem );
427 std::function < void ( QDomElement &,
const QString & ) > appendFormat = [&doc]( QDomElement & elem,
const QString & format )
429 QDomElement formatElem = doc.createElement( QStringLiteral(
"Format" ) );
430 formatElem.appendChild( doc.createTextNode( format ) );
431 elem.appendChild( formatElem );
437 elem = doc.createElement( QStringLiteral(
"GetCapabilities" ) );
438 appendFormat( elem, ( version == QLatin1String(
"1.1.1" ) ?
"application/vnd.ogc.wms_xml" :
"text/xml" ) );
439 elem.appendChild( dcpTypeElem );
440 requestElem.appendChild( elem );
443 QDomElement getElem = doc.createElement( QStringLiteral(
"Get" ) );
444 httpElem.appendChild( getElem );
445 QDomElement olResourceElem = doc.createElement( QStringLiteral(
"OnlineResource" ) );
446 olResourceElem.setAttribute( QStringLiteral(
"xmlns:xlink" ), QStringLiteral(
"http://www.w3.org/1999/xlink" ) );
447 olResourceElem.setAttribute( QStringLiteral(
"xlink:type" ), QStringLiteral(
"simple" ) );
448 olResourceElem.setAttribute( QStringLiteral(
"xlink:href" ), hrefString );
449 getElem.appendChild( olResourceElem );
452 elem = doc.createElement( QStringLiteral(
"GetMap" ) );
453 appendFormat( elem, QStringLiteral(
"image/jpeg" ) );
454 appendFormat( elem, QStringLiteral(
"image/png" ) );
455 appendFormat( elem, QStringLiteral(
"image/png; mode=16bit" ) );
456 appendFormat( elem, QStringLiteral(
"image/png; mode=8bit" ) );
457 appendFormat( elem, QStringLiteral(
"image/png; mode=1bit" ) );
458 appendFormat( elem, QStringLiteral(
"application/dxf" ) );
459 appendFormat( elem, QStringLiteral(
"application/pdf" ) );
460 elem.appendChild( dcpTypeElem.cloneNode().toElement() );
461 requestElem.appendChild( elem );
464 elem = doc.createElement( QStringLiteral(
"GetFeatureInfo" ) );
465 appendFormat( elem, QStringLiteral(
"text/plain" ) );
466 appendFormat( elem, QStringLiteral(
"text/html" ) );
467 appendFormat( elem, QStringLiteral(
"text/xml" ) );
468 appendFormat( elem, QStringLiteral(
"application/vnd.ogc.gml" ) );
469 appendFormat( elem, QStringLiteral(
"application/vnd.ogc.gml/3.1.1" ) );
470 appendFormat( elem, QStringLiteral(
"application/json" ) );
471 appendFormat( elem, QStringLiteral(
"application/geo+json" ) );
472 elem.appendChild( dcpTypeElem.cloneNode().toElement() );
473 requestElem.appendChild( elem );
476 elem = doc.createElement( ( version == QLatin1String(
"1.1.1" ) ?
"GetLegendGraphic" :
"sld:GetLegendGraphic" ) );
477 appendFormat( elem, QStringLiteral(
"image/jpeg" ) );
478 appendFormat( elem, QStringLiteral(
"image/png" ) );
479 appendFormat( elem, QStringLiteral(
"application/json" ) );
480 elem.appendChild( dcpTypeElem.cloneNode().toElement() );
481 requestElem.appendChild( elem );
484 elem = doc.createElement( ( version == QLatin1String(
"1.1.1" ) ?
"DescribeLayer" :
"sld:DescribeLayer" ) );
485 appendFormat( elem, QStringLiteral(
"text/xml" ) );
486 elem.appendChild( dcpTypeElem.cloneNode().toElement() );
487 requestElem.appendChild( elem );
490 elem = doc.createElement( ( version == QLatin1String(
"1.1.1" ) ?
"GetStyles" :
"qgs:GetStyles" ) );
491 appendFormat( elem, QStringLiteral(
"text/xml" ) );
492 elem.appendChild( dcpTypeElem.cloneNode().toElement() );
493 requestElem.appendChild( elem );
499 elem = doc.createElement( QStringLiteral(
"GetPrint" ) );
500 appendFormat( elem, QStringLiteral(
"svg" ) );
501 appendFormat( elem, QStringLiteral(
"png" ) );
502 appendFormat( elem, QStringLiteral(
"pdf" ) );
503 elem.appendChild( dcpTypeElem.cloneNode().toElement() );
504 requestElem.appendChild( elem );
508 elem = doc.createElement( QStringLiteral(
"Exception" ) );
509 appendFormat( elem, ( version == QLatin1String(
"1.1.1" ) ?
"application/vnd.ogc.se_xml" :
"XML" ) );
510 capabilityElem.appendChild( elem );
513 if ( version == QLatin1String(
"1.3.0" ) )
515 elem = doc.createElement( QStringLiteral(
"sld:UserDefinedSymbolization" ) );
516 elem.setAttribute( QStringLiteral(
"SupportSLD" ), QStringLiteral(
"1" ) );
517 elem.setAttribute( QStringLiteral(
"UserLayer" ), QStringLiteral(
"0" ) );
518 elem.setAttribute( QStringLiteral(
"UserStyle" ), QStringLiteral(
"1" ) );
519 elem.setAttribute( QStringLiteral(
"RemoteWFS" ), QStringLiteral(
"0" ) );
520 elem.setAttribute( QStringLiteral(
"InlineFeature" ), QStringLiteral(
"0" ) );
521 elem.setAttribute( QStringLiteral(
"RemoteWCS" ), QStringLiteral(
"0" ) );
522 capabilityElem.appendChild( elem );
530 return capabilityElem;
535 QDomElement inspireCapabilitiesElem;
538 return inspireCapabilitiesElem;
540 inspireCapabilitiesElem = doc.createElement( QStringLiteral(
"inspire_vs:ExtendedCapabilities" ) );
544 if ( !inspireMetadataUrl.isEmpty() )
546 QDomElement inspireCommonMetadataUrlElem = doc.createElement( QStringLiteral(
"inspire_common:MetadataUrl" ) );
547 inspireCommonMetadataUrlElem.setAttribute( QStringLiteral(
"xsi:type" ), QStringLiteral(
"inspire_common:resourceLocatorType" ) );
549 QDomElement inspireCommonMetadataUrlUrlElem = doc.createElement( QStringLiteral(
"inspire_common:URL" ) );
550 inspireCommonMetadataUrlUrlElem.appendChild( doc.createTextNode( inspireMetadataUrl ) );
551 inspireCommonMetadataUrlElem.appendChild( inspireCommonMetadataUrlUrlElem );
554 if ( !inspireMetadataUrlType.isNull() )
556 QDomElement inspireCommonMetadataUrlMediaTypeElem = doc.createElement( QStringLiteral(
"inspire_common:MediaType" ) );
557 inspireCommonMetadataUrlMediaTypeElem.appendChild( doc.createTextNode( inspireMetadataUrlType ) );
558 inspireCommonMetadataUrlElem.appendChild( inspireCommonMetadataUrlMediaTypeElem );
561 inspireCapabilitiesElem.appendChild( inspireCommonMetadataUrlElem );
565 QDomElement inspireCommonResourceTypeElem = doc.createElement( QStringLiteral(
"inspire_common:ResourceType" ) );
566 inspireCommonResourceTypeElem.appendChild( doc.createTextNode( QStringLiteral(
"service" ) ) );
567 inspireCapabilitiesElem.appendChild( inspireCommonResourceTypeElem );
569 QDomElement inspireCommonSpatialDataServiceTypeElem = doc.createElement( QStringLiteral(
"inspire_common:SpatialDataServiceType" ) );
570 inspireCommonSpatialDataServiceTypeElem.appendChild( doc.createTextNode( QStringLiteral(
"view" ) ) );
571 inspireCapabilitiesElem.appendChild( inspireCommonSpatialDataServiceTypeElem );
574 if ( !inspireTemporalReference.isNull() )
576 QDomElement inspireCommonTemporalReferenceElem = doc.createElement( QStringLiteral(
"inspire_common:TemporalReference" ) );
577 QDomElement inspireCommonDateOfLastRevisionElem = doc.createElement( QStringLiteral(
"inspire_common:DateOfLastRevision" ) );
578 inspireCommonDateOfLastRevisionElem.appendChild( doc.createTextNode( inspireTemporalReference ) );
579 inspireCommonTemporalReferenceElem.appendChild( inspireCommonDateOfLastRevisionElem );
580 inspireCapabilitiesElem.appendChild( inspireCommonTemporalReferenceElem );
583 QDomElement inspireCommonMetadataPointOfContactElem = doc.createElement( QStringLiteral(
"inspire_common:MetadataPointOfContact" ) );
586 QDomElement inspireCommonOrganisationNameElem = doc.createElement( QStringLiteral(
"inspire_common:OrganisationName" ) );
587 if ( !contactOrganization.isNull() )
589 inspireCommonOrganisationNameElem.appendChild( doc.createTextNode( contactOrganization ) );
591 inspireCommonMetadataPointOfContactElem.appendChild( inspireCommonOrganisationNameElem );
594 QDomElement inspireCommonEmailAddressElem = doc.createElement( QStringLiteral(
"inspire_common:EmailAddress" ) );
595 if ( !contactMail.isNull() )
597 inspireCommonEmailAddressElem.appendChild( doc.createTextNode( contactMail ) );
599 inspireCommonMetadataPointOfContactElem.appendChild( inspireCommonEmailAddressElem );
601 inspireCapabilitiesElem.appendChild( inspireCommonMetadataPointOfContactElem );
604 if ( !inspireMetadataDate.isNull() )
606 QDomElement inspireCommonMetadataDateElem = doc.createElement( QStringLiteral(
"inspire_common:MetadataDate" ) );
607 inspireCommonMetadataDateElem.appendChild( doc.createTextNode( inspireMetadataDate ) );
608 inspireCapabilitiesElem.appendChild( inspireCommonMetadataDateElem );
613 QDomElement inspireCommonSupportedLanguagesElem = doc.createElement( QStringLiteral(
"inspire_common:SupportedLanguages" ) );
614 inspireCommonSupportedLanguagesElem.setAttribute( QStringLiteral(
"xsi:type" ), QStringLiteral(
"inspire_common:supportedLanguagesType" ) );
616 QDomElement inspireCommonLanguageElem = doc.createElement( QStringLiteral(
"inspire_common:Language" ) );
619 QDomElement inspireCommonDefaultLanguageElem = doc.createElement( QStringLiteral(
"inspire_common:DefaultLanguage" ) );
620 inspireCommonDefaultLanguageElem.appendChild( inspireCommonLanguageElem );
621 inspireCommonSupportedLanguagesElem.appendChild( inspireCommonDefaultLanguageElem );
625 QDomElement inspireCommonSupportedLanguageElem = doc.createElement(
"inspire_common:SupportedLanguage" );
626 inspireCommonSupportedLanguageElem.appendChild( inspireCommonLanguageElem.cloneNode().toElement() );
627 inspireCommonSupportedLanguagesElem.appendChild( inspireCommonSupportedLanguageElem );
630 inspireCapabilitiesElem.appendChild( inspireCommonSupportedLanguagesElem );
632 QDomElement inspireCommonResponseLanguageElem = doc.createElement( QStringLiteral(
"inspire_common:ResponseLanguage" ) );
633 inspireCommonResponseLanguageElem.appendChild( inspireCommonLanguageElem.cloneNode().toElement() );
634 inspireCapabilitiesElem.appendChild( inspireCommonResponseLanguageElem );
636 return inspireCapabilitiesElem;
642 if ( projectComposers.size() == 0 )
643 return QDomElement();
647 QDomElement composerTemplatesElem = doc.createElement( QStringLiteral(
"ComposerTemplates" ) );
648 QList<QgsPrintLayout *>::const_iterator cIt = projectComposers.constBegin();
649 for ( ; cIt != projectComposers.constEnd(); ++cIt )
652 if ( restrictedComposers.contains( layout->
name() ) )
664 QDomElement composerTemplateElem = doc.createElement( QStringLiteral(
"ComposerTemplate" ) );
665 composerTemplateElem.setAttribute( QStringLiteral(
"name" ), layout->
name() );
668 composerTemplateElem.setAttribute( QStringLiteral(
"width" ), width.
length() );
669 composerTemplateElem.setAttribute( QStringLiteral(
"height" ), height.
length() );
673 if ( atlas && atlas->
enabled() )
675 composerTemplateElem.setAttribute( QStringLiteral(
"atlasEnabled" ), QStringLiteral(
"1" ) );
682 layerName = cLayer->
id();
684 else if ( layerName.isEmpty() )
686 layerName = cLayer->
name();
688 composerTemplateElem.setAttribute( QStringLiteral(
"atlasCoverageLayer" ), layerName );
693 QList<QgsLayoutItemMap *> layoutMapList;
695 QList<QgsLayoutItemMap *>::const_iterator cmIt = layoutMapList.constBegin();
698 for ( ; cmIt != layoutMapList.constEnd(); ++cmIt )
702 QDomElement composerMapElem = doc.createElement( QStringLiteral(
"ComposerMap" ) );
703 composerMapElem.setAttribute( QStringLiteral(
"name" ), QStringLiteral(
"map%1" ).arg( mapId ) );
704 composerMapElem.setAttribute( QStringLiteral(
"itemName" ), composerMap->
displayName() );
706 composerMapElem.setAttribute( QStringLiteral(
"width" ), composerMap->rect().width() );
707 composerMapElem.setAttribute( QStringLiteral(
"height" ), composerMap->rect().height() );
708 composerTemplateElem.appendChild( composerMapElem );
712 QList<QgsLayoutItemLabel *> composerLabelList;
714 QList<QgsLayoutItemLabel *>::const_iterator clIt = composerLabelList.constBegin();
715 for ( ; clIt != composerLabelList.constEnd(); ++clIt )
718 QString
id = composerLabel->
id();
722 QDomElement composerLabelElem = doc.createElement( QStringLiteral(
"ComposerLabel" ) );
723 composerLabelElem.setAttribute( QStringLiteral(
"name" ), id );
724 composerTemplateElem.appendChild( composerLabelElem );
728 QList<QgsLayoutItemHtml *> composerHtmlList;
730 QList<QgsLayoutItemHtml *>::const_iterator chIt = composerHtmlList.constBegin();
731 for ( ; chIt != composerHtmlList.constEnd(); ++chIt )
737 QString
id = composerHtml->
frame( 0 )->
id();
741 QDomElement composerHtmlElem = doc.createElement( QStringLiteral(
"ComposerHtml" ) );
742 composerHtmlElem.setAttribute( QStringLiteral(
"name" ), id );
743 composerTemplateElem.appendChild( composerHtmlElem );
746 composerTemplatesElem.appendChild( composerTemplateElem );
749 if ( composerTemplatesElem.childNodes().size() == 0 )
750 return QDomElement();
752 return composerTemplatesElem;
758 if ( wfsLayerIds.size() == 0 )
759 return QDomElement();
761 QDomElement wfsLayersElem = doc.createElement( QStringLiteral(
"WFSLayers" ) );
762 for (
int i = 0; i < wfsLayerIds.size(); ++i )
770 QDomElement wfsLayerElem = doc.createElement( QStringLiteral(
"WFSLayer" ) );
773 wfsLayerElem.setAttribute( QStringLiteral(
"name" ), layer->
id() );
777 wfsLayerElem.setAttribute( QStringLiteral(
"name" ), layer->
name() );
779 wfsLayersElem.appendChild( wfsLayerElem );
782 return wfsLayersElem;
786 QDomElement &parentLayer,
791 const QMap< QString, QgsWmsLayerInfos > &wmsLayerInfos,
792 bool projectSettings )
796 parentLayer.setAttribute(
797 QStringLiteral(
"queryable" ),
798 hasQueryableLayers( layerIds, wmsLayerInfos ) ? QStringLiteral(
"1" ) : QStringLiteral(
"0" )
802 QMap<QString, QgsRectangle> crsExtents =
combineCrsExtents( layerIds, wmsLayerInfos );
804 appendCrsElementsToLayer( doc, parentLayer, crsExtents.keys(), QStringList() );
805 appendLayerWgs84BoundingRect( doc, parentLayer, wgs84BoundingRect );
806 appendLayerCrsExtents( doc, parentLayer, crsExtents );
808 appendLayersFromTreeGroup( doc, parentLayer, serverIface, project, request, layerTreeGroup, wmsLayerInfos, projectSettings );
817 QDomElement layerParentElem = doc.createElement( QStringLiteral(
"Layer" ) );
821 if ( rootLayerName.isEmpty() && !project->
title().isEmpty() )
823 rootLayerName = project->
title();
826 if ( !rootLayerName.isEmpty() )
828 QDomElement layerParentNameElem = doc.createElement( QStringLiteral(
"Name" ) );
829 QDomText layerParentNameText = doc.createTextNode( rootLayerName );
830 layerParentNameElem.appendChild( layerParentNameText );
831 layerParentElem.appendChild( layerParentNameElem );
835 QDomElement layerParentTitleElem = doc.createElement( QStringLiteral(
"Title" ) );
837 layerParentTitleElem.appendChild( layerParentTitleText );
838 layerParentElem.appendChild( layerParentTitleElem );
842 if ( !rootLayerAbstract.isEmpty() )
844 QDomElement layerParentAbstElem = doc.createElement( QStringLiteral(
"Abstract" ) );
845 QDomText layerParentAbstText = doc.createCDATASection( rootLayerAbstract );
846 layerParentAbstElem.appendChild( layerParentAbstText );
847 layerParentElem.appendChild( layerParentAbstElem );
851 addKeywordListElement( project, doc, layerParentElem );
854 if ( projectSettings )
856 QDomElement treeNameElem = doc.createElement( QStringLiteral(
"TreeName" ) );
857 QDomText treeNameText = doc.createTextNode( project->
title() );
858 treeNameElem.appendChild( treeNameText );
859 layerParentElem.appendChild( treeNameElem );
865 auto outputCrsList = QList<QgsCoordinateReferenceSystem>();
871 outputCrsList.append(
crs );
895 QStringLiteral(
"Error transforming extent: %1" ).arg( cse.
what() ),
896 QStringLiteral(
"Server" ),
902 QMap< QString, QgsRectangle > wmsCrsExtents;
914 layerParentElem.setAttribute(
915 QStringLiteral(
"queryable" ),
919 appendCrsElementsToLayer( doc, layerParentElem, wmsCrsExtents.keys(), QStringList() );
920 appendLayerWgs84BoundingRect( doc, layerParentElem, wmsWgs84BoundingRect );
921 appendLayerCrsExtents( doc, layerParentElem, wmsCrsExtents );
923 appendLayersFromTreeGroup( doc, layerParentElem, serverIface, project, request, projectLayerTreeRoot, wmsLayerInfos, projectSettings );
927 handleLayersFromTreeGroup( doc, layerParentElem, serverIface, project, request, projectLayerTreeRoot, wmsLayerInfos, projectSettings );
930 return layerParentElem;
936 void appendLayersFromTreeGroup( QDomDocument &doc,
937 QDomElement &parentLayer,
940 const QgsWmsRequest &request,
942 const QMap< QString, QgsWmsLayerInfos > &wmsLayerInfos,
943 bool projectSettings )
945 const QString version = request.wmsParameters().version();
951 QList< QgsLayerTreeNode * > layerTreeGroupChildren = layerTreeGroup->
children();
952 for (
int i = 0; i < layerTreeGroupChildren.size(); ++i )
955 QDomElement layerElem = doc.createElement( QStringLiteral(
"Layer" ) );
957 if ( projectSettings )
959 layerElem.setAttribute( QStringLiteral(
"visible" ), treeNode->
isVisible() );
961 layerElem.setAttribute( QStringLiteral(
"expanded" ), treeNode->
isExpanded() );
968 QString name = treeGroupChild->
name();
969 if ( restrictedLayers.contains( name ) )
974 if ( projectSettings )
976 layerElem.setAttribute( QStringLiteral(
"mutuallyExclusive" ), treeGroupChild->
isMutuallyExclusive() );
979 QString shortName = treeGroupChild->
customProperty( QStringLiteral(
"wmsShortName" ) ).toString();
980 QString title = treeGroupChild->
customProperty( QStringLiteral(
"wmsTitle" ) ).toString();
982 if ( !skipNameForGroup )
984 QDomElement nameElem = doc.createElement( QStringLiteral(
"Name" ) );
986 if ( !shortName.isEmpty() )
987 nameText = doc.createTextNode( shortName );
989 nameText = doc.createTextNode( name );
990 nameElem.appendChild( nameText );
991 layerElem.appendChild( nameElem );
994 QDomElement titleElem = doc.createElement( QStringLiteral(
"Title" ) );
996 if ( !title.isEmpty() )
997 titleText = doc.createTextNode( title );
999 titleText = doc.createTextNode( name );
1000 titleElem.appendChild( titleText );
1001 layerElem.appendChild( titleElem );
1003 QString abstract = treeGroupChild->
customProperty( QStringLiteral(
"wmsAbstract" ) ).toString();
1004 if ( !abstract.isEmpty() )
1006 QDomElement abstractElem = doc.createElement( QStringLiteral(
"Abstract" ) );
1007 QDomText abstractText = doc.createTextNode( abstract );
1008 abstractElem.appendChild( abstractText );
1009 layerElem.appendChild( abstractElem );
1013 if ( projectSettings )
1015 QDomElement treeNameElem = doc.createElement( QStringLiteral(
"TreeName" ) );
1016 QDomText treeNameText = doc.createTextNode( name );
1017 treeNameElem.appendChild( treeNameText );
1018 layerElem.appendChild( treeNameElem );
1021 handleLayersFromTreeGroup( doc, layerElem, serverIface, project, request, treeGroupChild, wmsLayerInfos, projectSettings );
1024 if ( layerElem.elementsByTagName( QStringLiteral(
"Layer" ) ).length() == 0 )
1033 if ( !wmsLayerInfos.contains( treeLayer->
layerId() ) )
1040 layerElem.setAttribute(
1041 QStringLiteral(
"queryable" ),
1042 layerInfos.
queryable ? QStringLiteral(
"1" ) : QStringLiteral(
"0" )
1045 QDomElement nameElem = doc.createElement( QStringLiteral(
"Name" ) );
1046 QDomText nameText = doc.createTextNode( layerInfos.
name );
1047 nameElem.appendChild( nameText );
1048 layerElem.appendChild( nameElem );
1050 QDomElement titleElem = doc.createElement( QStringLiteral(
"Title" ) );
1051 QDomText titleText = doc.createTextNode( layerInfos.
title );
1052 titleElem.appendChild( titleText );
1053 layerElem.appendChild( titleElem );
1055 if ( ! layerInfos.
abstract.isEmpty() )
1057 QDomElement abstractElem = doc.createElement( QStringLiteral(
"Abstract" ) );
1058 QDomText abstractText = doc.createTextNode( layerInfos.
abstract );
1059 abstractElem.appendChild( abstractText );
1060 layerElem.appendChild( abstractElem );
1064 if ( ! layerInfos.
keywords.isEmpty() )
1066 QDomElement keywordListElem = doc.createElement( QStringLiteral(
"KeywordList" ) );
1067 for (
const QString &keyword : std::as_const( layerInfos.keywords ) )
1069 QDomElement keywordElem = doc.createElement( QStringLiteral(
"Keyword" ) );
1070 QDomText keywordText = doc.createTextNode( keyword.trimmed() );
1071 keywordElem.appendChild( keywordText );
1074 keywordElem.setAttribute( QStringLiteral(
"vocabulary" ), QStringLiteral(
"SIA_Geo405" ) );
1076 keywordListElem.appendChild( keywordElem );
1078 layerElem.appendChild( keywordListElem );
1084 appendCrsElementsToLayer( doc, layerElem, layerInfos.
crsExtents.keys(), QStringList() );
1088 appendLayerCrsExtents( doc, layerElem, layerInfos.
crsExtents );
1092 appendLayerStyles( doc, layerElem, layerInfos, project, request, serverIface->
serverSettings() );
1097 if ( version == QLatin1String(
"1.1.1" ) )
1100 double SCALE_TO_SCALEHINT =
OGC_PX_M * M_SQRT2;
1102 QDomElement scaleHintElem = doc.createElement( QStringLiteral(
"ScaleHint" ) );
1103 scaleHintElem.setAttribute( QStringLiteral(
"min" ), QString::number( layerInfos.
maxScale * SCALE_TO_SCALEHINT ) );
1104 scaleHintElem.setAttribute( QStringLiteral(
"max" ), QString::number( layerInfos.
minScale * SCALE_TO_SCALEHINT ) );
1105 layerElem.appendChild( scaleHintElem );
1109 QDomElement minScaleElem = doc.createElement( QStringLiteral(
"MinScaleDenominator" ) );
1110 QDomText minScaleText = doc.createTextNode( QString::number( layerInfos.
maxScale ) );
1111 minScaleElem.appendChild( minScaleText );
1112 layerElem.appendChild( minScaleElem );
1114 QDomElement maxScaleElem = doc.createElement( QStringLiteral(
"MaxScaleDenominator" ) );
1115 QDomText maxScaleText = doc.createTextNode( QString::number( layerInfos.
minScale ) );
1116 maxScaleElem.appendChild( maxScaleText );
1117 layerElem.appendChild( maxScaleElem );
1122 if ( !layerInfos.
dataUrl.isEmpty() )
1124 QDomElement dataUrlElem = doc.createElement( QStringLiteral(
"DataURL" ) );
1125 QDomElement dataUrlFormatElem = doc.createElement( QStringLiteral(
"Format" ) );
1127 QDomText dataUrlFormatText = doc.createTextNode( dataUrlFormat );
1128 dataUrlFormatElem.appendChild( dataUrlFormatText );
1129 dataUrlElem.appendChild( dataUrlFormatElem );
1130 QDomElement dataORElem = doc.createElement( QStringLiteral(
"OnlineResource" ) );
1131 dataORElem.setAttribute( QStringLiteral(
"xmlns:xlink" ), QStringLiteral(
"http://www.w3.org/1999/xlink" ) );
1132 dataORElem.setAttribute( QStringLiteral(
"xlink:type" ), QStringLiteral(
"simple" ) );
1133 dataORElem.setAttribute( QStringLiteral(
"xlink:href" ), layerInfos.
dataUrl );
1134 dataUrlElem.appendChild( dataORElem );
1135 layerElem.appendChild( dataUrlElem );
1141 QDomElement attribElem = doc.createElement( QStringLiteral(
"Attribution" ) );
1142 QDomElement attribTitleElem = doc.createElement( QStringLiteral(
"Title" ) );
1143 QDomText attribText = doc.createTextNode( layerInfos.
attribution );
1144 attribTitleElem.appendChild( attribText );
1145 attribElem.appendChild( attribTitleElem );
1148 QDomElement attribORElem = doc.createElement( QStringLiteral(
"OnlineResource" ) );
1149 attribORElem.setAttribute( QStringLiteral(
"xmlns:xlink" ), QStringLiteral(
"http://www.w3.org/1999/xlink" ) );
1150 attribORElem.setAttribute( QStringLiteral(
"xlink:type" ), QStringLiteral(
"simple" ) );
1151 attribORElem.setAttribute( QStringLiteral(
"xlink:href" ), layerInfos.
attributionUrl );
1152 attribElem.appendChild( attribORElem );
1154 layerElem.appendChild( attribElem );
1160 QDomElement metaUrlElem = doc.createElement( QStringLiteral(
"MetadataURL" ) );
1161 const QString metadataUrlType = metadataUrl.type;
1162 if ( version == QLatin1String(
"1.1.1" ) )
1164 metaUrlElem.setAttribute( QStringLiteral(
"type" ), metadataUrlType );
1166 else if ( metadataUrlType == QLatin1String(
"FGDC" ) )
1168 metaUrlElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"FGDC:1998" ) );
1170 else if ( metadataUrlType == QLatin1String(
"TC211" ) )
1172 metaUrlElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"ISO19115:2003" ) );
1176 metaUrlElem.setAttribute( QStringLiteral(
"type" ), metadataUrlType );
1178 const QString metadataUrlFormat = metadataUrl.format;
1179 if ( !metadataUrlFormat.isEmpty() )
1181 QDomElement metaUrlFormatElem = doc.createElement( QStringLiteral(
"Format" ) );
1182 QDomText metaUrlFormatText = doc.createTextNode( metadataUrlFormat );
1183 metaUrlFormatElem.appendChild( metaUrlFormatText );
1184 metaUrlElem.appendChild( metaUrlFormatElem );
1186 QDomElement metaUrlORElem = doc.createElement( QStringLiteral(
"OnlineResource" ) );
1187 metaUrlORElem.setAttribute( QStringLiteral(
"xmlns:xlink" ), QStringLiteral(
"http://www.w3.org/1999/xlink" ) );
1188 metaUrlORElem.setAttribute( QStringLiteral(
"xlink:type" ), QStringLiteral(
"simple" ) );
1189 metaUrlORElem.setAttribute( QStringLiteral(
"xlink:href" ), metadataUrl.url );
1190 metaUrlElem.appendChild( metaUrlORElem );
1191 layerElem.appendChild( metaUrlElem );
1194 bool timeDimensionAdded {
false };
1201 const QList<QgsMapLayerServerProperties::WmsDimensionInfo> wmsDims = serverProperties->
wmsDimensions();
1207 if ( fieldIndex == -1 )
1212 QSet<QVariant> uniqueValues = vl->
uniqueValues( fieldIndex );
1215 if ( !dim.endFieldName.isEmpty() )
1217 int endFieldIndex = vl->
fields().
indexOf( dim.endFieldName );
1219 if ( endFieldIndex == -1 )
1223 uniqueValues.unite( vl->
uniqueValues( endFieldIndex ) );
1226 QList<QVariant> values = qgis::setToList( uniqueValues );
1227 std::sort( values.begin(), values.end() );
1229 QDomElement dimElem = doc.createElement( QStringLiteral(
"Dimension" ) );
1230 dimElem.setAttribute( QStringLiteral(
"name" ), dim.name );
1232 if ( dim.name.toUpper() == QLatin1String(
"TIME" ) )
1234 timeDimensionAdded =
true;
1237 if ( !dim.units.isEmpty() )
1239 dimElem.setAttribute( QStringLiteral(
"units" ), dim.units );
1241 if ( !dim.unitSymbol.isEmpty() )
1243 dimElem.setAttribute( QStringLiteral(
"unitSymbol" ), dim.unitSymbol );
1245 if ( !values.isEmpty() && dim.defaultDisplayType == QgsMapLayerServerProperties::WmsDimensionInfo::MinValue )
1247 dimElem.setAttribute( QStringLiteral(
"default" ), values.first().toString() );
1249 else if ( !values.isEmpty() && dim.defaultDisplayType == QgsMapLayerServerProperties::WmsDimensionInfo::MaxValue )
1251 dimElem.setAttribute( QStringLiteral(
"default" ), values.last().toString() );
1253 else if ( dim.defaultDisplayType == QgsMapLayerServerProperties::WmsDimensionInfo::ReferenceValue )
1255 dimElem.setAttribute( QStringLiteral(
"default" ), dim.referenceValue.toString() );
1257 dimElem.setAttribute( QStringLiteral(
"multipleValues" ), QStringLiteral(
"1" ) );
1258 dimElem.setAttribute( QStringLiteral(
"nearestValue" ), QStringLiteral(
"0" ) );
1259 if ( projectSettings )
1261 dimElem.setAttribute( QStringLiteral(
"fieldName" ), dim.fieldName );
1262 dimElem.setAttribute( QStringLiteral(
"endFieldName" ), dim.endFieldName );
1265 QStringList strValues;
1266 for (
const QVariant &v : values )
1268 strValues << v.toString();
1270 QDomText dimValuesText = doc.createTextNode( strValues.join( QLatin1String(
", " ) ) );
1271 dimElem.appendChild( dimValuesText );
1272 layerElem.appendChild( dimElem );
1277 if ( ! timeDimensionAdded
1282 QDomElement dimElem = doc.createElement( QStringLiteral(
"Dimension" ) );
1283 dimElem.setAttribute( QStringLiteral(
"name" ), QStringLiteral(
"TIME" ) );
1284 dimElem.setAttribute( QStringLiteral(
"units" ), QStringLiteral(
"ISO8601" ) );
1294 bool isDateList {
true };
1295 bool isInstantList {
true };
1297 QList<QDateTime> values;
1298 for (
const auto &r : std::as_const( allRanges ) )
1300 if ( r.isInstant() )
1302 if ( r.begin().time() != QTime( 0, 0, 0, 0 ) )
1306 values.append( r.begin() );
1310 isInstantList =
false;
1317 if ( isInstantList )
1320 QStringList strValues;
1321 for (
const auto &v : values )
1325 strValues << v.date().toString( Qt::DateFormat::ISODate );
1329 strValues << v.toString( Qt::DateFormat::ISODate );
1332 QDomText dimValuesText = doc.createTextNode( strValues.join( QChar(
',' ) ) );
1333 dimElem.appendChild( dimValuesText );
1336 layerElem.appendChild( dimElem );
1338 QDomElement timeExtentElem = doc.createElement( QStringLiteral(
"Extent" ) );
1339 timeExtentElem.setAttribute( QStringLiteral(
"name" ), QStringLiteral(
"TIME" ) );
1345 extent = QStringLiteral(
"%1/%2" ).arg( timeExtent.begin().date().toString( Qt::DateFormat::ISODate ), timeExtent.end().date().toString( Qt::DateFormat::ISODate ) );
1349 extent = QStringLiteral(
"%1/%2" ).arg( timeExtent.begin().toString( Qt::DateFormat::ISODate ), timeExtent.end().toString( Qt::DateFormat::ISODate ) );
1351 QDomText extentValueText = doc.createTextNode( extent );
1352 timeExtentElem.appendChild( extentValueText );
1353 layerElem.appendChild( timeExtentElem );
1357 if ( projectSettings )
1359 appendLayerProjectSettings( doc, layerElem, l );
1363 parentLayer.appendChild( layerElem );
1367 void appendLayerStyles( QDomDocument &doc, QDomElement &layerElem,
const QgsWmsLayerInfos &layerInfos,
1371 QUrl href =
serviceUrl( request, project, *settings );
1374 QString hrefString = href.toString();
1375 hrefString.append( href.hasQuery() ?
"&" :
"?" );
1376 for (
const QString &styleName : std::as_const( layerInfos.styles ) )
1378 QDomElement styleElem = doc.createElement( QStringLiteral(
"Style" ) );
1379 QDomElement styleNameElem = doc.createElement( QStringLiteral(
"Name" ) );
1380 QDomText styleNameText = doc.createTextNode( styleName );
1381 styleNameElem.appendChild( styleNameText );
1382 QDomElement styleTitleElem = doc.createElement( QStringLiteral(
"Title" ) );
1383 QDomText styleTitleText = doc.createTextNode( styleName );
1384 styleTitleElem.appendChild( styleTitleText );
1385 styleElem.appendChild( styleNameElem );
1386 styleElem.appendChild( styleTitleElem );
1389 QDomElement getLayerLegendGraphicElem = doc.createElement( QStringLiteral(
"LegendURL" ) );
1391 QString customHrefString = layerInfos.
legendUrl;
1393 QStringList getLayerLegendGraphicFormats;
1394 if ( !customHrefString.isEmpty() )
1400 getLayerLegendGraphicFormats << QStringLiteral(
"image/png" );
1403 for (
const QString &getLayerLegendGraphicFormat : std::as_const( getLayerLegendGraphicFormats ) )
1405 QDomElement getLayerLegendGraphicFormatElem = doc.createElement( QStringLiteral(
"Format" ) );
1406 QDomText getLayerLegendGraphicFormatText = doc.createTextNode( getLayerLegendGraphicFormat );
1407 getLayerLegendGraphicFormatElem.appendChild( getLayerLegendGraphicFormatText );
1408 getLayerLegendGraphicElem.appendChild( getLayerLegendGraphicFormatElem );
1412 if ( customHrefString.isEmpty() )
1414 QUrl mapUrl( hrefString );
1415 QUrlQuery mapUrlQuery( mapUrl.query() );
1416 mapUrlQuery.addQueryItem( QStringLiteral(
"SERVICE" ), QStringLiteral(
"WMS" ) );
1417 mapUrlQuery.addQueryItem( QStringLiteral(
"VERSION" ), request.wmsParameters().version() );
1418 mapUrlQuery.addQueryItem( QStringLiteral(
"REQUEST" ), QStringLiteral(
"GetLegendGraphic" ) );
1419 mapUrlQuery.addQueryItem( QStringLiteral(
"LAYER" ), layerInfos.
name );
1420 mapUrlQuery.addQueryItem( QStringLiteral(
"FORMAT" ), QStringLiteral(
"image/png" ) );
1421 mapUrlQuery.addQueryItem( QStringLiteral(
"STYLE" ), styleName );
1422 if ( request.wmsParameters().version() == QLatin1String(
"1.3.0" ) )
1424 mapUrlQuery.addQueryItem( QStringLiteral(
"SLD_VERSION" ), QStringLiteral(
"1.1.0" ) );
1426 mapUrl.setQuery( mapUrlQuery );
1427 customHrefString = mapUrl.toString();
1430 QDomElement getLayerLegendGraphicORElem = doc.createElement( QStringLiteral(
"OnlineResource" ) );
1431 getLayerLegendGraphicORElem.setAttribute( QStringLiteral(
"xmlns:xlink" ), QStringLiteral(
"http://www.w3.org/1999/xlink" ) );
1432 getLayerLegendGraphicORElem.setAttribute( QStringLiteral(
"xlink:type" ), QStringLiteral(
"simple" ) );
1433 getLayerLegendGraphicORElem.setAttribute( QStringLiteral(
"xlink:href" ), customHrefString );
1434 getLayerLegendGraphicElem.appendChild( getLayerLegendGraphicORElem );
1435 styleElem.appendChild( getLayerLegendGraphicElem );
1437 layerElem.appendChild( styleElem );
1441 void appendCrsElementsToLayer( QDomDocument &doc, QDomElement &layerElement,
1442 const QStringList &crsList,
const QStringList &constrainedCrsList )
1444 if ( layerElement.isNull() )
1449 const QString version = doc.documentElement().attribute( QStringLiteral(
"version" ) );
1452 QDomElement titleElement = layerElement.firstChildElement( QStringLiteral(
"Title" ) );
1453 QDomElement abstractElement = layerElement.firstChildElement( QStringLiteral(
"Abstract" ) );
1454 QDomElement keywordListElement = layerElement.firstChildElement( QStringLiteral(
"KeywordList" ) );
1455 QDomElement CRSPrecedingElement = !keywordListElement.isNull() ? keywordListElement : !abstractElement.isNull() ? abstractElement : titleElement;
1457 if ( CRSPrecedingElement.isNull() )
1460 const QDomElement keyElement = layerElement.firstChildElement( QStringLiteral(
"KeywordList" ) );
1461 CRSPrecedingElement = keyElement;
1465 if ( !constrainedCrsList.isEmpty() )
1467 for (
int i = constrainedCrsList.size() - 1; i >= 0; --i )
1469 appendCrsElementToLayer( doc, layerElement, CRSPrecedingElement, constrainedCrsList.at( i ) );
1474 for (
const QString &
crs : crsList )
1476 appendCrsElementToLayer( doc, layerElement, CRSPrecedingElement,
crs );
1482 if ( version == QLatin1String(
"1.3.0" ) )
1484 appendCrsElementToLayer( doc, layerElement, CRSPrecedingElement, QString(
"CRS:84" ) );
1488 void appendCrsElementToLayer( QDomDocument &doc, QDomElement &layerElement,
const QDomElement &precedingElement,
1489 const QString &crsText )
1491 if ( crsText.isEmpty() )
1493 const QString version = doc.documentElement().attribute( QStringLiteral(
"version" ) );
1494 QDomElement crsElement = doc.createElement( version == QLatin1String(
"1.1.1" ) ?
"SRS" :
"CRS" );
1495 QDomText crsTextNode = doc.createTextNode( crsText );
1496 crsElement.appendChild( crsTextNode );
1497 layerElement.insertAfter( crsElement, precedingElement );
1500 void appendLayerWgs84BoundingRect( QDomDocument &doc, QDomElement &layerElem,
const QgsRectangle &wgs84BoundingRect )
1503 if ( wgs84BoundingRect.
isNull() )
1509 QDomElement ExGeoBBoxElement;
1510 const int wgs84precision = 6;
1511 const QString version = doc.documentElement().attribute( QStringLiteral(
"version" ) );
1512 if ( version == QLatin1String(
"1.1.1" ) )
1514 ExGeoBBoxElement = doc.createElement( QStringLiteral(
"LatLonBoundingBox" ) );
1522 ExGeoBBoxElement = doc.createElement( QStringLiteral(
"EX_GeographicBoundingBox" ) );
1523 QDomElement wBoundLongitudeElement = doc.createElement( QStringLiteral(
"westBoundLongitude" ) );
1525 wBoundLongitudeElement.appendChild( wBoundLongitudeText );
1526 ExGeoBBoxElement.appendChild( wBoundLongitudeElement );
1527 QDomElement eBoundLongitudeElement = doc.createElement( QStringLiteral(
"eastBoundLongitude" ) );
1529 eBoundLongitudeElement.appendChild( eBoundLongitudeText );
1530 ExGeoBBoxElement.appendChild( eBoundLongitudeElement );
1531 QDomElement sBoundLatitudeElement = doc.createElement( QStringLiteral(
"southBoundLatitude" ) );
1533 sBoundLatitudeElement.appendChild( sBoundLatitudeText );
1534 ExGeoBBoxElement.appendChild( sBoundLatitudeElement );
1535 QDomElement nBoundLatitudeElement = doc.createElement( QStringLiteral(
"northBoundLatitude" ) );
1537 nBoundLatitudeElement.appendChild( nBoundLatitudeText );
1538 ExGeoBBoxElement.appendChild( nBoundLatitudeElement );
1541 const QDomElement lastCRSElem = layerElem.lastChildElement( version == QLatin1String(
"1.1.1" ) ?
"SRS" :
"CRS" );
1542 if ( !lastCRSElem.isNull() )
1544 layerElem.insertAfter( ExGeoBBoxElement, lastCRSElem );
1548 layerElem.appendChild( ExGeoBBoxElement );
1552 void appendLayerCrsExtents( QDomDocument &doc, QDomElement &layerElem,
const QMap<QString, QgsRectangle> &crsExtents )
1554 const QString version = doc.documentElement().attribute( QStringLiteral(
"version" ) );
1556 const auto &keys = crsExtents.keys();
1557 for (
const QString &crsText : std::as_const( keys ) )
1562 if ( crsExtent.isNull() )
1574 QDomElement bBoxElement = doc.createElement( QStringLiteral(
"BoundingBox" ) );
1577 bBoxElement.setAttribute( version == QLatin1String(
"1.1.1" ) ?
"SRS" :
"CRS",
crs.authid() );
1590 QDomElement lastBBoxElem = layerElem.lastChildElement( QStringLiteral(
"BoundingBox" ) );
1591 if ( !lastBBoxElem.isNull() )
1593 layerElem.insertAfter( bBoxElement, lastBBoxElem );
1597 lastBBoxElem = layerElem.lastChildElement( version == QLatin1String(
"1.1.1" ) ?
"LatLonBoundingBox" :
"EX_GeographicBoundingBox" );
1598 if ( !lastBBoxElem.isNull() )
1600 layerElem.insertAfter( bBoxElement, lastBBoxElem );
1604 layerElem.appendChild( bBoxElement );
1610 void appendDrawingOrder( QDomDocument &doc, QDomElement &parentElem,
QgsServerInterface *serverIface,
1613#ifdef HAVE_SERVER_PYTHON_PLUGINS
1616 ( void )serverIface;
1621 QStringList layerList;
1624 QList< QgsMapLayer * > projectLayerOrder = projectLayerTreeRoot->
layerOrder();
1625 for (
int i = 0; i < projectLayerOrder.size(); ++i )
1629 if ( restrictedLayers.contains( l->
name() ) )
1633#ifdef HAVE_SERVER_PYTHON_PLUGINS
1639 QString wmsName = l->
name();
1649 layerList << wmsName;
1652 if ( !layerList.isEmpty() )
1654 QStringList reversedList;
1655 reversedList.reserve( layerList.size() );
1656 for (
int i = layerList.size() - 1; i >= 0; --i )
1657 reversedList << layerList[ i ];
1659 QDomElement layerDrawingOrderElem = doc.createElement( QStringLiteral(
"LayerDrawingOrder" ) );
1660 QDomText drawingOrderText = doc.createTextNode( reversedList.join(
',' ) );
1661 layerDrawingOrderElem.appendChild( drawingOrderText );
1662 parentElem.appendChild( layerDrawingOrderElem );
1666 void appendLayerProjectSettings( QDomDocument &doc, QDomElement &layerElem,
QgsMapLayer *currentLayer )
1668 if ( !currentLayer )
1674 QDomElement treeNameElem = doc.createElement( QStringLiteral(
"TreeName" ) );
1675 QDomText treeNameText = doc.createTextNode( currentLayer->
name() );
1676 treeNameElem.appendChild( treeNameText );
1677 layerElem.appendChild( treeNameElem );
1679 switch ( currentLayer->
type() )
1685 int displayFieldIdx = -1;
1686 QString displayField = QStringLiteral(
"maptip" );
1688 if ( exp.isField() )
1695 QDomElement attributesElem = doc.createElement( QStringLiteral(
"Attributes" ) );
1697 for (
int idx = 0; idx < layerFields.
count(); ++idx )
1705 if ( idx == displayFieldIdx )
1709 QDomElement attributeElem = doc.createElement( QStringLiteral(
"Attribute" ) );
1710 attributeElem.setAttribute( QStringLiteral(
"name" ), field.
name() );
1711 attributeElem.setAttribute( QStringLiteral(
"type" ), QVariant::typeToName( field.
type() ) );
1712 attributeElem.setAttribute( QStringLiteral(
"typeName" ), field.
typeName() );
1713 QString alias = field.
alias();
1714 if ( !alias.isEmpty() )
1716 attributeElem.setAttribute( QStringLiteral(
"alias" ), alias );
1720 attributeElem.setAttribute( QStringLiteral(
"editType" ), vLayer->
editorWidgetSetup( idx ).
type() );
1721 attributeElem.setAttribute( QStringLiteral(
"comment" ), field.
comment() );
1722 attributeElem.setAttribute( QStringLiteral(
"length" ), field.
length() );
1723 attributeElem.setAttribute( QStringLiteral(
"precision" ), field.
precision() );
1724 attributesElem.appendChild( attributeElem );
1728 layerElem.setAttribute( QStringLiteral(
"displayField" ), displayField );
1732 if ( pkAttributes.size() > 0 )
1734 QDomElement pkElem = doc.createElement( QStringLiteral(
"PrimaryKey" ) );
1735 QgsAttributeList::const_iterator pkIt = pkAttributes.constBegin();
1736 for ( ; pkIt != pkAttributes.constEnd(); ++pkIt )
1738 QDomElement pkAttributeElem = doc.createElement( QStringLiteral(
"PrimaryKeyAttribute" ) );
1739 QDomText pkAttName = doc.createTextNode( layerFields.
at( *pkIt ).
name() );
1740 pkAttributeElem.appendChild( pkAttName );
1741 pkElem.appendChild( pkAttributeElem );
1743 layerElem.appendChild( pkElem );
1750 layerElem.setAttribute( QStringLiteral(
"opacity" ), QString::number( vLayer->
opacity() ) );
1752 layerElem.appendChild( attributesElem );
1759 if ( provider && provider->
name() ==
"wms" )
1762 QVariant wmsBackgroundLayer = currentLayer->
customProperty( QStringLiteral(
"WMSBackgroundLayer" ), false );
1763 QDomElement wmsBackgroundLayerElem = doc.createElement(
"WMSBackgroundLayer" );
1764 QDomText wmsBackgroundLayerText = doc.createTextNode( wmsBackgroundLayer.toBool() ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) );
1765 wmsBackgroundLayerElem.appendChild( wmsBackgroundLayerText );
1766 layerElem.appendChild( wmsBackgroundLayerElem );
1769 QVariant wmsPublishDataSourceUrl = currentLayer->
customProperty( QStringLiteral(
"WMSPublishDataSourceUrl" ),
false );
1770 if ( wmsPublishDataSourceUrl.toBool() )
1772 bool tiled = qobject_cast< const QgsRasterDataProvider * >( provider )
1773 ? !qobject_cast< const QgsRasterDataProvider * >( provider )->nativeResolutions().isEmpty()
1776 QDomElement dataSourceElem = doc.createElement( tiled ? QStringLiteral(
"WMTSDataSource" ) : QStringLiteral(
"WMSDataSource" ) );
1777 QDomText dataSourceUri = doc.createTextNode( provider->
dataSourceUri() );
1778 dataSourceElem.appendChild( dataSourceUri );
1779 layerElem.appendChild( dataSourceElem );
1783 QVariant wmsPrintLayer = currentLayer->
customProperty( QStringLiteral(
"WMSPrintLayer" ) );
1784 if ( wmsPrintLayer.isValid() )
1786 QDomElement wmsPrintLayerElem = doc.createElement(
"WMSPrintLayer" );
1787 QDomText wmsPrintLayerText = doc.createTextNode( wmsPrintLayer.toString() );
1788 wmsPrintLayerElem.appendChild( wmsPrintLayerText );
1789 layerElem.appendChild( wmsPrintLayerElem );
1795 if ( rasterRenderer )
1797 layerElem.setAttribute( QStringLiteral(
"opacity" ), QString::number( rasterRenderer->
opacity() ) );
1813 void addKeywordListElement(
const QgsProject *project, QDomDocument &doc, QDomElement &parent )
1817 QDomElement keywordsElem = doc.createElement( QStringLiteral(
"KeywordList" ) );
1819 QDomElement keywordElem = doc.createElement( QStringLiteral(
"Keyword" ) );
1820 keywordElem.setAttribute( QStringLiteral(
"vocabulary" ), QStringLiteral(
"ISO" ) );
1821 QDomText keywordText = doc.createTextNode( QStringLiteral(
"infoMapAccessService" ) );
1822 keywordElem.appendChild( keywordText );
1823 keywordsElem.appendChild( keywordElem );
1824 parent.appendChild( keywordsElem );
1826 for (
const QString &keyword : std::as_const( keywords ) )
1828 if ( !keyword.isEmpty() )
1830 keywordElem = doc.createElement( QStringLiteral(
"Keyword" ) );
1831 keywordText = doc.createTextNode( keyword );
1832 keywordElem.appendChild( keywordText );
1835 keywordElem.setAttribute( QStringLiteral(
"vocabulary" ), QStringLiteral(
"SIA_Geo405" ) );
1837 keywordsElem.appendChild( keywordElem );
1840 parent.appendChild( keywordsElem );
1844 bool hasQueryableLayers(
const QStringList &layerIds,
const QMap< QString, QgsWmsLayerInfos > &wmsLayerInfos )
1846 for (
const QString &
id : std::as_const( layerIds ) )
1848 if ( !wmsLayerInfos.contains(
id ) )
1852 if ( wmsLayerInfos[
id].queryable )
1865 for (
const QString &
id : std::as_const( layerIds ) )
1867 if ( !wmsLayerInfos.contains(
id ) )
1872 QgsRectangle rect = wmsLayerInfos[ id ].wgs84BoundingRect;
1897 QMap<QString, QgsRectangle>
combineCrsExtents(
const QStringList &layerIds,
const QMap< QString, QgsWmsLayerInfos > &wmsLayerInfos )
1899 QMap<QString, QgsRectangle> combined;
1901 for (
const QString &
id : std::as_const( layerIds ) )
1903 if ( !wmsLayerInfos.contains(
id ) )
1909 const auto keys = layerInfos.
crsExtents.keys();
1910 for (
const QString &
crs : std::as_const( keys ) )
1923 if ( !combined.contains(
crs ) )
1925 combined[
crs ] = rect;
@ Millimeters
Millimeters.
@ Warning
Warning message.
@ Group
Composite group layer. Added in QGIS 3.24.
@ Plugin
Plugin based layer.
@ TiledScene
Tiled scene layer. Added in QGIS 3.34.
@ Annotation
Contains freeform, georeferenced annotations. Added in QGIS 3.16.
@ VectorTile
Vector tile layer. Added in QGIS 3.14.
@ Mesh
Mesh layer. Added in QGIS 3.2.
@ PointCloud
Point cloud layer. Added in QGIS 3.18.
@ 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)
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.
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 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.
Qgis::FieldConfigurationFlags configurationFlags
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.
QStringList findLayerIds() const
Find layer IDs used in all layer nodes.
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 layerId() const
Returns the ID for the map layer associated with this node.
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.
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, 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.
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.
QString id() const
Returns the layer's unique ID, which is used to access this layer from QgsProject.
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.
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)
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 xMinimum() const
Returns the x minimum value (left side of rectangle).
double yMinimum() const
Returns the y minimum value (bottom side of rectangle).
double xMaximum() const
Returns the x maximum value (right side of rectangle).
bool isNull() const
Test if the rectangle is null (holding no spatial information).
double yMaximum() const
Returns the y maximum value (top side of rectangle).
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 has no area.
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.
QgsFields fields() const FINAL
Returns the list of fields of this layer.
Q_INVOKABLE Qgis::WkbType wkbType() const FINAL
Returns the WKBType or WKBUnknown in case of error.
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(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 title
WMS layer title.
QStringList keywords
WMS layer keywords.
QString legendUrl
WMS layer legend URL.
QString abstract
WMS layer abstract.
static QgsRectangle transformExtent(const QgsRectangle &extent, const QgsCoordinateReferenceSystem &source, const QgsCoordinateReferenceSystem &destination, const QgsCoordinateTransformContext &context, const bool &ballparkTransformsAreAppropriate=false)
Returns a transformed extent.
QString attribution
WMS layer attribution.
QString dataUrl
WMS layer dataUrl.
double maxScale
WMS layer maximum scale (if negative, no maximum scale is defined)
QMap< QString, QgsRectangle > crsExtents
WMS layer CRS extents (can be empty)
QString attributionUrl
WMS layer attribution URL.
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.
Class defining request interface passed to WMS service.
const QgsWmsParameters & wmsParameters() const
Returns the parameters interpreted for the WMS service.
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 bool wmsSkipNameForGroup(const QgsProject &project)
Returns if name attribute should be skipped for groups in WMS capabilities document.
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.
void handleLayersFromTreeGroup(QDomDocument &doc, QDomElement &parentLayer, QgsServerInterface *serverIface, const QgsProject *project, const QgsWmsRequest &request, const QgsLayerTreeGroup *layerTreeGroup, const QMap< QString, QgsWmsLayerInfos > &wmsLayerInfos, bool projectSettings)
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.
CONSTLATIN1STRING geoEpsgCrsAuthId()
Geographic coord sys from EPSG authority.
QList< int > QgsAttributeList
const QgsCoordinateReferenceSystem & crs
Setting to define QGIS Server WMS Dimension.