51     void appendLayerProjectSettings( QDomDocument &doc, QDomElement &layerElem, 
QgsMapLayer *currentLayer );
 
   53     void appendDrawingOrder( QDomDocument &doc, QDomElement &parentElem, 
QgsServerInterface *serverIface,
 
   56     void combineExtentAndCrsOfGroupChildren( QDomDocument &doc, QDomElement &groupElem, 
const QgsProject *project,
 
   57         bool considerMapExtent = 
false );
 
   59     bool crsSetFromLayerElement( 
const QDomElement &layerElement, QSet<QString> &crsSet );
 
   61     QgsRectangle layerBoundingBoxInProjectCrs( 
const QDomDocument &doc, 
const QDomElement &layerElem,
 
   64     void appendLayerBoundingBox( QDomDocument &doc, QDomElement &layerElem, 
const QgsRectangle &layerExtent,
 
   68     void appendLayerBoundingBoxes( QDomDocument &doc, QDomElement &layerElem, 
const QgsRectangle &lExtent,
 
   70                                    const QStringList &constrainedCrsList, 
const QgsProject *project,
 
   73     void appendCrsElementToLayer( QDomDocument &doc, QDomElement &layerElement, 
const QDomElement &precedingElement,
 
   74                                   const QString &crsText );
 
   76     void appendCrsElementsToLayer( QDomDocument &doc, QDomElement &layerElement,
 
   77                                    const QStringList &crsList, 
const QStringList &constrainedCrsList );
 
   79     void appendLayerStyles( QDomDocument &doc, QDomElement &layerElem, 
QgsMapLayer *currentLayer,
 
   82     void appendLayersFromTreeGroup( QDomDocument &doc,
 
   83                                     QDomElement &parentLayer,
 
   86                                     const QgsWmsRequest &request,
 
   88                                     bool projectSettings );
 
   90     void addKeywordListElement( 
const QgsProject *project, QDomDocument &doc, QDomElement &parent );
 
   97                              bool projectSettings )
 
   99 #ifdef HAVE_SERVER_PYTHON_PLUGINS 
  104     const QDomDocument *capabilitiesDocument = 
nullptr;
 
  109     QStringList cacheKeyList;
 
  110     cacheKeyList << ( projectSettings ? QStringLiteral( 
"projectSettings" ) : request.
wmsParameters().
version() );
 
  114 #ifdef HAVE_SERVER_PYTHON_PLUGINS 
  118     QString cacheKey = cacheKeyList.join( 
'-' );
 
  120 #ifdef HAVE_SERVER_PYTHON_PLUGINS 
  122     if ( cacheManager && cacheManager->
getCachedDocument( &doc, project, request, accessControl ) )
 
  124       capabilitiesDocument = &doc;
 
  127     if ( !capabilitiesDocument && cache ) 
 
  132     if ( !capabilitiesDocument ) 
 
  134       QgsMessageLog::logMessage( QStringLiteral( 
"WMS capabilities document not found in cache" ), QStringLiteral( 
"Server" ) );
 
  136       doc = 
getCapabilities( serverIface, project, request, projectSettings );
 
  138 #ifdef HAVE_SERVER_PYTHON_PLUGINS 
  142         capabilitiesDocument = &doc;
 
  147       if ( !capabilitiesDocument )
 
  152       if ( !capabilitiesDocument )
 
  154         capabilitiesDocument = &doc;
 
  166     response.
setHeader( QStringLiteral( 
"Content-Type" ), QStringLiteral( 
"text/xml; charset=utf-8" ) );
 
  167     response.
write( capabilitiesDocument->toByteArray() );
 
  172                                 bool projectSettings )
 
  175     QDomElement wmsCapabilitiesElement;
 
  181     QString hrefString = href.toString();
 
  182     hrefString.append( href.hasQuery() ? 
"&" : 
"?" );
 
  185     QDomProcessingInstruction xmlDeclaration = doc.createProcessingInstruction( QStringLiteral( 
"xml" ),
 
  186         QStringLiteral( 
"version=\"1.0\" encoding=\"utf-8\"" ) );
 
  189     std::function < void ( QDomElement &, 
const QString & ) > appendFormat = [&doc]( QDomElement & elem, 
const QString & format )
 
  191       QDomElement formatElem = doc.createElement( QStringLiteral( 
"Format" ) );
 
  192       formatElem.appendChild( doc.createTextNode( format ) );
 
  193       elem.appendChild( formatElem );
 
  198       doc = QDomDocument( QStringLiteral( 
"WMT_MS_Capabilities SYSTEM 'http://schemas.opengis.net/wms/1.1.1/WMS_MS_Capabilities.dtd'" ) );  
 
  199       doc.appendChild( xmlDeclaration );
 
  200       wmsCapabilitiesElement = doc.createElement( QStringLiteral( 
"WMT_MS_Capabilities" ) );
 
  204       doc.appendChild( xmlDeclaration );
 
  205       wmsCapabilitiesElement = doc.createElement( QStringLiteral( 
"WMS_Capabilities" ) );
 
  206       wmsCapabilitiesElement.setAttribute( QStringLiteral( 
"xmlns" ), QStringLiteral( 
"http://www.opengis.net/wms" ) );
 
  207       wmsCapabilitiesElement.setAttribute( QStringLiteral( 
"xmlns:sld" ), QStringLiteral( 
"http://www.opengis.net/sld" ) );
 
  208       wmsCapabilitiesElement.setAttribute( QStringLiteral( 
"xmlns:qgs" ), QStringLiteral( 
"http://www.qgis.org/wms" ) );
 
  209       wmsCapabilitiesElement.setAttribute( QStringLiteral( 
"xmlns:xsi" ), QStringLiteral( 
"http://www.w3.org/2001/XMLSchema-instance" ) );
 
  210       QString schemaLocation = QStringLiteral( 
"http://www.opengis.net/wms" );
 
  211       schemaLocation += QLatin1String( 
" http://schemas.opengis.net/wms/1.3.0/capabilities_1_3_0.xsd" );
 
  212       schemaLocation += QLatin1String( 
" http://www.opengis.net/sld" );
 
  213       schemaLocation += QLatin1String( 
" http://schemas.opengis.net/sld/1.1.0/sld_capabilities.xsd" );
 
  217         wmsCapabilitiesElement.setAttribute( QStringLiteral( 
"xmlns:inspire_common" ), QStringLiteral( 
"http://inspire.ec.europa.eu/schemas/common/1.0" ) );
 
  218         wmsCapabilitiesElement.setAttribute( QStringLiteral( 
"xmlns:inspire_vs" ), QStringLiteral( 
"http://inspire.ec.europa.eu/schemas/inspire_vs/1.0" ) );
 
  219         schemaLocation += QLatin1String( 
" http://inspire.ec.europa.eu/schemas/inspire_vs/1.0" );
 
  220         schemaLocation += QLatin1String( 
" http://inspire.ec.europa.eu/schemas/inspire_vs/1.0/inspire_vs.xsd" );
 
  223       schemaLocation += QLatin1String( 
" http://www.qgis.org/wms" );
 
  224       schemaLocation += 
" " + hrefString + 
"SERVICE=WMS&REQUEST=GetSchemaExtension";
 
  226       wmsCapabilitiesElement.setAttribute( QStringLiteral( 
"xsi:schemaLocation" ), schemaLocation );
 
  228     wmsCapabilitiesElement.setAttribute( QStringLiteral( 
"version" ), request.
wmsParameters().
version() );
 
  229     doc.appendChild( wmsCapabilitiesElement );
 
  235     QDomElement capabilityElement = 
getCapabilityElement( doc, project, request, projectSettings, serverIface );
 
  236     wmsCapabilitiesElement.appendChild( capabilityElement );
 
  238     if ( projectSettings )
 
  247     capabilityElement.appendChild(
 
  251     if ( projectSettings )
 
  253       appendDrawingOrder( doc, capabilityElement, serverIface, project );
 
  263     QDomElement serviceElem = doc.createElement( QStringLiteral( 
"Service" ) );
 
  266     QDomElement nameElem = doc.createElement( QStringLiteral( 
"Name" ) );
 
  267     QDomText nameText = doc.createTextNode( QStringLiteral( 
"WMS" ) );
 
  268     nameElem.appendChild( nameText );
 
  269     serviceElem.appendChild( nameElem );
 
  272     QDomElement titleElem = doc.createElement( QStringLiteral( 
"Title" ) );
 
  274     titleElem.appendChild( titleText );
 
  275     serviceElem.appendChild( titleElem );
 
  278     if ( !
abstract.isEmpty() )
 
  280       QDomElement abstractElem = doc.createElement( QStringLiteral( 
"Abstract" ) );
 
  281       QDomText abstractText = doc.createCDATASection( 
abstract );
 
  282       abstractElem.appendChild( abstractText );
 
  283       serviceElem.appendChild( abstractElem );
 
  286     addKeywordListElement( project, doc, serviceElem );
 
  289     if ( onlineResource.isEmpty() )
 
  291       onlineResource = 
serviceUrl( request, project, *serverSettings ).toString();
 
  293     QDomElement onlineResourceElem = doc.createElement( QStringLiteral( 
"OnlineResource" ) );
 
  294     onlineResourceElem.setAttribute( QStringLiteral( 
"xmlns:xlink" ), QStringLiteral( 
"http://www.w3.org/1999/xlink" ) );
 
  295     onlineResourceElem.setAttribute( QStringLiteral( 
"xlink:type" ), QStringLiteral( 
"simple" ) );
 
  296     onlineResourceElem.setAttribute( QStringLiteral( 
"xlink:href" ), onlineResource );
 
  297     serviceElem.appendChild( onlineResourceElem );
 
  304     if ( !contactPerson.isEmpty() ||
 
  305          !contactOrganization.isEmpty() ||
 
  306          !contactPosition.isEmpty() ||
 
  307          !contactMail.isEmpty() ||
 
  308          !contactPhone.isEmpty() )
 
  311       QDomElement contactInfoElem = doc.createElement( QStringLiteral( 
"ContactInformation" ) );
 
  314       if ( !contactPerson.isEmpty() ||
 
  315            !contactOrganization.isEmpty() )
 
  317         QDomElement contactPersonPrimaryElem = doc.createElement( QStringLiteral( 
"ContactPersonPrimary" ) );
 
  319         QDomText contactPersonText;
 
  320         if ( !contactPerson.isEmpty() )
 
  322           contactPersonText = doc.createTextNode( contactPerson );
 
  326           contactPersonText = doc.createTextNode( QStringLiteral( 
"unknown" ) );
 
  328         QDomElement contactPersonElem = doc.createElement( QStringLiteral( 
"ContactPerson" ) );
 
  329         contactPersonElem.appendChild( contactPersonText );
 
  330         contactPersonPrimaryElem.appendChild( contactPersonElem );
 
  332         QDomText contactOrganizationText;
 
  333         if ( !contactOrganization.isEmpty() )
 
  335           contactOrganizationText = doc.createTextNode( contactOrganization );
 
  339           contactOrganizationText = doc.createTextNode( QStringLiteral( 
"unknown" ) );
 
  341         QDomElement contactOrganizationElem = doc.createElement( QStringLiteral( 
"ContactOrganization" ) );
 
  342         contactOrganizationElem.appendChild( contactOrganizationText );
 
  343         contactPersonPrimaryElem.appendChild( contactOrganizationElem );
 
  345         contactInfoElem.appendChild( contactPersonPrimaryElem );
 
  348       if ( !contactPosition.isEmpty() )
 
  350         QDomElement contactPositionElem = doc.createElement( QStringLiteral( 
"ContactPosition" ) );
 
  351         QDomText contactPositionText = doc.createTextNode( contactPosition );
 
  352         contactPositionElem.appendChild( contactPositionText );
 
  353         contactInfoElem.appendChild( contactPositionElem );
 
  356       if ( !contactPhone.isEmpty() )
 
  358         QDomElement phoneElem = doc.createElement( QStringLiteral( 
"ContactVoiceTelephone" ) );
 
  359         QDomText phoneText = doc.createTextNode( contactPhone );
 
  360         phoneElem.appendChild( phoneText );
 
  361         contactInfoElem.appendChild( phoneElem );
 
  364       if ( !contactMail.isEmpty() )
 
  366         QDomElement mailElem = doc.createElement( QStringLiteral( 
"ContactElectronicMailAddress" ) );
 
  367         QDomText mailText = doc.createTextNode( contactMail );
 
  368         mailElem.appendChild( mailText );
 
  369         contactInfoElem.appendChild( mailElem );
 
  372       serviceElem.appendChild( contactInfoElem );
 
  375     QDomElement feesElem = doc.createElement( QStringLiteral( 
"Fees" ) );
 
  376     QDomText feesText = doc.createTextNode( QStringLiteral( 
"None" ) ); 
 
  378     if ( !fees.isEmpty() )
 
  380       feesText = doc.createTextNode( fees );
 
  382     feesElem.appendChild( feesText );
 
  383     serviceElem.appendChild( feesElem );
 
  385     QDomElement accessConstraintsElem = doc.createElement( QStringLiteral( 
"AccessConstraints" ) );
 
  386     QDomText accessConstraintsText = doc.createTextNode( QStringLiteral( 
"None" ) ); 
 
  388     if ( !accessConstraints.isEmpty() )
 
  390       accessConstraintsText = doc.createTextNode( accessConstraints );
 
  392     accessConstraintsElem.appendChild( accessConstraintsText );
 
  393     serviceElem.appendChild( accessConstraintsElem );
 
  400         QDomElement maxWidthElem = doc.createElement( QStringLiteral( 
"MaxWidth" ) );
 
  401         QDomText maxWidthText = doc.createTextNode( QString::number( maxWidth ) );
 
  402         maxWidthElem.appendChild( maxWidthText );
 
  403         serviceElem.appendChild( maxWidthElem );
 
  409         QDomElement maxHeightElem = doc.createElement( QStringLiteral( 
"MaxHeight" ) );
 
  410         QDomText maxHeightText = doc.createTextNode( QString::number( maxHeight ) );
 
  411         maxHeightElem.appendChild( maxHeightText );
 
  412         serviceElem.appendChild( maxHeightElem );
 
  429     QString hrefString = href.toString();
 
  430     hrefString.append( href.hasQuery() ? 
"&" : 
"?" );
 
  432     QDomElement capabilityElem = doc.createElement( QStringLiteral( 
"Capability" ) );
 
  435     QDomElement requestElem = doc.createElement( QStringLiteral( 
"Request" ) );
 
  436     capabilityElem.appendChild( requestElem );
 
  438     QDomElement dcpTypeElem = doc.createElement( QStringLiteral( 
"DCPType" ) );
 
  439     QDomElement httpElem = doc.createElement( QStringLiteral( 
"HTTP" ) );
 
  440     dcpTypeElem.appendChild( httpElem );
 
  443     std::function < void ( QDomElement &, 
const QString & ) > appendFormat = [&doc]( QDomElement & elem, 
const QString & format )
 
  445       QDomElement formatElem = doc.createElement( QStringLiteral( 
"Format" ) );
 
  446       formatElem.appendChild( doc.createTextNode( format ) );
 
  447       elem.appendChild( formatElem );
 
  453     elem = doc.createElement( QStringLiteral( 
"GetCapabilities" ) );
 
  454     appendFormat( elem, ( version == QLatin1String( 
"1.1.1" ) ? 
"application/vnd.ogc.wms_xml" : 
"text/xml" ) );
 
  455     elem.appendChild( dcpTypeElem );
 
  456     requestElem.appendChild( elem );
 
  459     QDomElement getElem = doc.createElement( QStringLiteral( 
"Get" ) );
 
  460     httpElem.appendChild( getElem );
 
  461     QDomElement olResourceElem = doc.createElement( QStringLiteral( 
"OnlineResource" ) );
 
  462     olResourceElem.setAttribute( QStringLiteral( 
"xmlns:xlink" ), QStringLiteral( 
"http://www.w3.org/1999/xlink" ) );
 
  463     olResourceElem.setAttribute( QStringLiteral( 
"xlink:type" ), QStringLiteral( 
"simple" ) );
 
  464     olResourceElem.setAttribute( QStringLiteral( 
"xlink:href" ), hrefString );
 
  465     getElem.appendChild( olResourceElem );
 
  468     elem = doc.createElement( QStringLiteral( 
"GetMap" ) );
 
  469     appendFormat( elem, QStringLiteral( 
"image/jpeg" ) );
 
  470     appendFormat( elem, QStringLiteral( 
"image/png" ) );
 
  471     appendFormat( elem, QStringLiteral( 
"image/png; mode=16bit" ) );
 
  472     appendFormat( elem, QStringLiteral( 
"image/png; mode=8bit" ) );
 
  473     appendFormat( elem, QStringLiteral( 
"image/png; mode=1bit" ) );
 
  474     appendFormat( elem, QStringLiteral( 
"application/dxf" ) );
 
  475     elem.appendChild( dcpTypeElem.cloneNode().toElement() ); 
 
  476     requestElem.appendChild( elem );
 
  479     elem = doc.createElement( QStringLiteral( 
"GetFeatureInfo" ) );
 
  480     appendFormat( elem, QStringLiteral( 
"text/plain" ) );
 
  481     appendFormat( elem, QStringLiteral( 
"text/html" ) );
 
  482     appendFormat( elem, QStringLiteral( 
"text/xml" ) );
 
  483     appendFormat( elem, QStringLiteral( 
"application/vnd.ogc.gml" ) );
 
  484     appendFormat( elem, QStringLiteral( 
"application/vnd.ogc.gml/3.1.1" ) );
 
  485     appendFormat( elem, QStringLiteral( 
"application/json" ) );
 
  486     appendFormat( elem, QStringLiteral( 
"application/geo+json" ) );
 
  487     elem.appendChild( dcpTypeElem.cloneNode().toElement() ); 
 
  488     requestElem.appendChild( elem );
 
  491     elem = doc.createElement( ( version == QLatin1String( 
"1.1.1" ) ? 
"GetLegendGraphic" : 
"sld:GetLegendGraphic" ) );
 
  492     appendFormat( elem, QStringLiteral( 
"image/jpeg" ) );
 
  493     appendFormat( elem, QStringLiteral( 
"image/png" ) );
 
  494     appendFormat( elem, QStringLiteral( 
"application/json" ) );
 
  495     elem.appendChild( dcpTypeElem.cloneNode().toElement() ); 
 
  496     requestElem.appendChild( elem );
 
  499     elem = doc.createElement( ( version == QLatin1String( 
"1.1.1" ) ? 
"DescribeLayer" : 
"sld:DescribeLayer" ) );
 
  500     appendFormat( elem, QStringLiteral( 
"text/xml" ) );
 
  501     elem.appendChild( dcpTypeElem.cloneNode().toElement() ); 
 
  502     requestElem.appendChild( elem );
 
  505     elem = doc.createElement( ( version == QLatin1String( 
"1.1.1" ) ? 
"GetStyles" : 
"qgs:GetStyles" ) );
 
  506     appendFormat( elem, QStringLiteral( 
"text/xml" ) );
 
  507     elem.appendChild( dcpTypeElem.cloneNode().toElement() ); 
 
  508     requestElem.appendChild( elem );
 
  514       elem = doc.createElement( QStringLiteral( 
"GetPrint" )  );
 
  515       appendFormat( elem, QStringLiteral( 
"svg" ) );
 
  516       appendFormat( elem, QStringLiteral( 
"png" ) );
 
  517       appendFormat( elem, QStringLiteral( 
"pdf" ) );
 
  518       elem.appendChild( dcpTypeElem.cloneNode().toElement() ); 
 
  519       requestElem.appendChild( elem );
 
  523     elem = doc.createElement( QStringLiteral( 
"Exception" ) );
 
  524     appendFormat( elem, ( version == QLatin1String( 
"1.1.1" ) ? 
"application/vnd.ogc.se_xml" : 
"XML" ) );
 
  525     capabilityElem.appendChild( elem );
 
  528     if ( version == QLatin1String( 
"1.3.0" ) )
 
  530       elem = doc.createElement( QStringLiteral( 
"sld:UserDefinedSymbolization" ) );
 
  531       elem.setAttribute( QStringLiteral( 
"SupportSLD" ), QStringLiteral( 
"1" ) );
 
  532       elem.setAttribute( QStringLiteral( 
"UserLayer" ), QStringLiteral( 
"0" ) );
 
  533       elem.setAttribute( QStringLiteral( 
"UserStyle" ), QStringLiteral( 
"1" ) );
 
  534       elem.setAttribute( QStringLiteral( 
"RemoteWFS" ), QStringLiteral( 
"0" ) );
 
  535       elem.setAttribute( QStringLiteral( 
"InlineFeature" ), QStringLiteral( 
"0" ) );
 
  536       elem.setAttribute( QStringLiteral( 
"RemoteWCS" ), QStringLiteral( 
"0" ) );
 
  537       capabilityElem.appendChild( elem );
 
  545     return capabilityElem;
 
  550     QDomElement inspireCapabilitiesElem;
 
  553       return inspireCapabilitiesElem;
 
  555     inspireCapabilitiesElem = doc.createElement( QStringLiteral( 
"inspire_vs:ExtendedCapabilities" ) );
 
  559     if ( !inspireMetadataUrl.isEmpty() )
 
  561       QDomElement inspireCommonMetadataUrlElem = doc.createElement( QStringLiteral( 
"inspire_common:MetadataUrl" ) );
 
  562       inspireCommonMetadataUrlElem.setAttribute( QStringLiteral( 
"xsi:type" ), QStringLiteral( 
"inspire_common:resourceLocatorType" ) );
 
  564       QDomElement inspireCommonMetadataUrlUrlElem = doc.createElement( QStringLiteral( 
"inspire_common:URL" ) );
 
  565       inspireCommonMetadataUrlUrlElem.appendChild( doc.createTextNode( inspireMetadataUrl ) );
 
  566       inspireCommonMetadataUrlElem.appendChild( inspireCommonMetadataUrlUrlElem );
 
  569       if ( !inspireMetadataUrlType.isNull() )
 
  571         QDomElement inspireCommonMetadataUrlMediaTypeElem = doc.createElement( QStringLiteral( 
"inspire_common:MediaType" ) );
 
  572         inspireCommonMetadataUrlMediaTypeElem.appendChild( doc.createTextNode( inspireMetadataUrlType ) );
 
  573         inspireCommonMetadataUrlElem.appendChild( inspireCommonMetadataUrlMediaTypeElem );
 
  576       inspireCapabilitiesElem.appendChild( inspireCommonMetadataUrlElem );
 
  580       QDomElement inspireCommonResourceTypeElem = doc.createElement( QStringLiteral( 
"inspire_common:ResourceType" ) );
 
  581       inspireCommonResourceTypeElem.appendChild( doc.createTextNode( QStringLiteral( 
"service" ) ) );
 
  582       inspireCapabilitiesElem.appendChild( inspireCommonResourceTypeElem );
 
  584       QDomElement inspireCommonSpatialDataServiceTypeElem = doc.createElement( QStringLiteral( 
"inspire_common:SpatialDataServiceType" ) );
 
  585       inspireCommonSpatialDataServiceTypeElem.appendChild( doc.createTextNode( QStringLiteral( 
"view" ) ) );
 
  586       inspireCapabilitiesElem.appendChild( inspireCommonSpatialDataServiceTypeElem );
 
  589       if ( !inspireTemporalReference.isNull() )
 
  591         QDomElement inspireCommonTemporalReferenceElem = doc.createElement( QStringLiteral( 
"inspire_common:TemporalReference" ) );
 
  592         QDomElement inspireCommonDateOfLastRevisionElem = doc.createElement( QStringLiteral( 
"inspire_common:DateOfLastRevision" ) );
 
  593         inspireCommonDateOfLastRevisionElem.appendChild( doc.createTextNode( inspireTemporalReference ) );
 
  594         inspireCommonTemporalReferenceElem.appendChild( inspireCommonDateOfLastRevisionElem );
 
  595         inspireCapabilitiesElem.appendChild( inspireCommonTemporalReferenceElem );
 
  598       QDomElement inspireCommonMetadataPointOfContactElem = doc.createElement( QStringLiteral( 
"inspire_common:MetadataPointOfContact" ) );
 
  601       QDomElement inspireCommonOrganisationNameElem = doc.createElement( QStringLiteral( 
"inspire_common:OrganisationName" ) );
 
  602       if ( !contactOrganization.isNull() )
 
  604         inspireCommonOrganisationNameElem.appendChild( doc.createTextNode( contactOrganization ) );
 
  606       inspireCommonMetadataPointOfContactElem.appendChild( inspireCommonOrganisationNameElem );
 
  609       QDomElement inspireCommonEmailAddressElem = doc.createElement( QStringLiteral( 
"inspire_common:EmailAddress" ) );
 
  610       if ( !contactMail.isNull() )
 
  612         inspireCommonEmailAddressElem.appendChild( doc.createTextNode( contactMail ) );
 
  614       inspireCommonMetadataPointOfContactElem.appendChild( inspireCommonEmailAddressElem );
 
  616       inspireCapabilitiesElem.appendChild( inspireCommonMetadataPointOfContactElem );
 
  619       if ( !inspireMetadataDate.isNull() )
 
  621         QDomElement inspireCommonMetadataDateElem = doc.createElement( QStringLiteral( 
"inspire_common:MetadataDate" ) );
 
  622         inspireCommonMetadataDateElem.appendChild( doc.createTextNode( inspireMetadataDate ) );
 
  623         inspireCapabilitiesElem.appendChild( inspireCommonMetadataDateElem );
 
  628     QDomElement inspireCommonSupportedLanguagesElem = doc.createElement( QStringLiteral( 
"inspire_common:SupportedLanguages" ) );
 
  629     inspireCommonSupportedLanguagesElem.setAttribute( QStringLiteral( 
"xsi:type" ), QStringLiteral( 
"inspire_common:supportedLanguagesType" ) );
 
  631     QDomElement inspireCommonLanguageElem = doc.createElement( QStringLiteral( 
"inspire_common:Language" ) );
 
  634     QDomElement inspireCommonDefaultLanguageElem = doc.createElement( QStringLiteral( 
"inspire_common:DefaultLanguage" ) );
 
  635     inspireCommonDefaultLanguageElem.appendChild( inspireCommonLanguageElem );
 
  636     inspireCommonSupportedLanguagesElem.appendChild( inspireCommonDefaultLanguageElem );
 
  640     QDomElement inspireCommonSupportedLanguageElem = doc.createElement( 
"inspire_common:SupportedLanguage" );
 
  641     inspireCommonSupportedLanguageElem.appendChild( inspireCommonLanguageElem.cloneNode().toElement() );
 
  642     inspireCommonSupportedLanguagesElem.appendChild( inspireCommonSupportedLanguageElem );
 
  645     inspireCapabilitiesElem.appendChild( inspireCommonSupportedLanguagesElem );
 
  647     QDomElement inspireCommonResponseLanguageElem = doc.createElement( QStringLiteral( 
"inspire_common:ResponseLanguage" ) );
 
  648     inspireCommonResponseLanguageElem.appendChild( inspireCommonLanguageElem.cloneNode().toElement() );
 
  649     inspireCapabilitiesElem.appendChild( inspireCommonResponseLanguageElem );
 
  651     return inspireCapabilitiesElem;
 
  657     if ( projectComposers.size() == 0 )
 
  658       return QDomElement();
 
  662     QDomElement composerTemplatesElem = doc.createElement( QStringLiteral( 
"ComposerTemplates" ) );
 
  663     QList<QgsPrintLayout *>::const_iterator cIt = projectComposers.constBegin();
 
  664     for ( ; cIt != projectComposers.constEnd(); ++cIt )
 
  667       if ( restrictedComposers.contains( layout->
name() ) )
 
  679       QDomElement composerTemplateElem = doc.createElement( QStringLiteral( 
"ComposerTemplate" ) );
 
  680       composerTemplateElem.setAttribute( QStringLiteral( 
"name" ), layout->
name() );
 
  683       composerTemplateElem.setAttribute( QStringLiteral( 
"width" ), width.
length() );
 
  684       composerTemplateElem.setAttribute( QStringLiteral( 
"height" ), height.
length() );
 
  688       if ( atlas && atlas->
enabled() )
 
  690         composerTemplateElem.setAttribute( QStringLiteral( 
"atlasEnabled" ), QStringLiteral( 
"1" ) );
 
  697             layerName = cLayer->
id();
 
  699           else if ( layerName.isEmpty() )
 
  701             layerName = cLayer->
name();
 
  703           composerTemplateElem.setAttribute( QStringLiteral( 
"atlasCoverageLayer" ), layerName );
 
  708       QList<QgsLayoutItemMap *> layoutMapList;
 
  710       QList<QgsLayoutItemMap *>::const_iterator cmIt = layoutMapList.constBegin();
 
  713       for ( ; cmIt != layoutMapList.constEnd(); ++cmIt )
 
  717         QDomElement composerMapElem = doc.createElement( QStringLiteral( 
"ComposerMap" ) );
 
  718         composerMapElem.setAttribute( QStringLiteral( 
"name" ), QStringLiteral( 
"map%1" ).arg( mapId ) );
 
  720         composerMapElem.setAttribute( QStringLiteral( 
"width" ), composerMap->rect().width() );
 
  721         composerMapElem.setAttribute( QStringLiteral( 
"height" ), composerMap->rect().height() );
 
  722         composerTemplateElem.appendChild( composerMapElem );
 
  726       QList<QgsLayoutItemLabel *> composerLabelList;
 
  728       QList<QgsLayoutItemLabel *>::const_iterator clIt = composerLabelList.constBegin();
 
  729       for ( ; clIt != composerLabelList.constEnd(); ++clIt )
 
  732         QString 
id = composerLabel->
id();
 
  736         QDomElement composerLabelElem = doc.createElement( QStringLiteral( 
"ComposerLabel" ) );
 
  737         composerLabelElem.setAttribute( QStringLiteral( 
"name" ), id );
 
  738         composerTemplateElem.appendChild( composerLabelElem );
 
  742       QList<QgsLayoutItemHtml *> composerHtmlList;
 
  744       QList<QgsLayoutItemHtml *>::const_iterator chIt = composerHtmlList.constBegin();
 
  745       for ( ; chIt != composerHtmlList.constEnd(); ++chIt )
 
  751         QString 
id = composerHtml->
frame( 0 )->
id();
 
  755         QDomElement composerHtmlElem = doc.createElement( QStringLiteral( 
"ComposerHtml" ) );
 
  756         composerHtmlElem.setAttribute( QStringLiteral( 
"name" ), id );
 
  757         composerTemplateElem.appendChild( composerHtmlElem );
 
  760       composerTemplatesElem.appendChild( composerTemplateElem );
 
  763     if ( composerTemplatesElem.childNodes().size() == 0 )
 
  764       return QDomElement();
 
  766     return composerTemplatesElem;
 
  773       return QDomElement();
 
  775     QDomElement wfsLayersElem = doc.createElement( QStringLiteral( 
"WFSLayers" ) );
 
  784       QDomElement wfsLayerElem = doc.createElement( QStringLiteral( 
"WFSLayer" ) );
 
  787         wfsLayerElem.setAttribute( QStringLiteral( 
"name" ), layer->
id() );
 
  791         wfsLayerElem.setAttribute( QStringLiteral( 
"name" ), layer->
name() );
 
  793       wfsLayersElem.appendChild( wfsLayerElem );
 
  796     return wfsLayersElem;
 
  805     QDomElement layerParentElem = doc.createElement( QStringLiteral( 
"Layer" ) );
 
  809     if ( rootLayerName.isEmpty() && !project->
title().isEmpty() )
 
  811       rootLayerName = project->
title();
 
  814     if ( !rootLayerName.isEmpty() )
 
  816       QDomElement layerParentNameElem = doc.createElement( QStringLiteral( 
"Name" ) );
 
  817       QDomText layerParentNameText = doc.createTextNode( rootLayerName );
 
  818       layerParentNameElem.appendChild( layerParentNameText );
 
  819       layerParentElem.appendChild( layerParentNameElem );
 
  823     QDomElement layerParentTitleElem = doc.createElement( QStringLiteral( 
"Title" ) );
 
  825     layerParentTitleElem.appendChild( layerParentTitleText );
 
  826     layerParentElem.appendChild( layerParentTitleElem );
 
  830     if ( !rootLayerAbstract.isEmpty() )
 
  832       QDomElement layerParentAbstElem = doc.createElement( QStringLiteral( 
"Abstract" ) );
 
  833       QDomText layerParentAbstText = doc.createCDATASection( rootLayerAbstract );
 
  834       layerParentAbstElem.appendChild( layerParentAbstText );
 
  835       layerParentElem.appendChild( layerParentAbstElem );
 
  839     addKeywordListElement( project, doc, layerParentElem );
 
  842     if ( projectSettings )
 
  844       QDomElement treeNameElem = doc.createElement( QStringLiteral( 
"TreeName" ) );
 
  845       QDomText treeNameText = doc.createTextNode( project->
title() );
 
  846       treeNameElem.appendChild( treeNameText );
 
  847       layerParentElem.appendChild( treeNameElem );
 
  852       layerParentElem.setAttribute( QStringLiteral( 
"queryable" ), QStringLiteral( 
"1" ) );
 
  856       layerParentElem.setAttribute( QStringLiteral( 
"queryable" ), QStringLiteral( 
"0" ) );
 
  859     appendLayersFromTreeGroup( doc, layerParentElem, serverIface, project, request, projectLayerTreeRoot, projectSettings );
 
  861     combineExtentAndCrsOfGroupChildren( doc, layerParentElem, project, 
true );
 
  863     return layerParentElem;
 
  869     void appendLayersFromTreeGroup( QDomDocument &doc,
 
  870                                     QDomElement &parentLayer,
 
  873                                     const QgsWmsRequest &request,
 
  875                                     bool projectSettings )
 
  877       const QString version = request.wmsParameters().version();
 
  883       QList< QgsLayerTreeNode * > layerTreeGroupChildren = layerTreeGroup->
children();
 
  884       for ( 
int i = 0; i < layerTreeGroupChildren.size(); ++i )
 
  887         QDomElement layerElem = doc.createElement( QStringLiteral( 
"Layer" ) );
 
  889         if ( projectSettings )
 
  891           layerElem.setAttribute( QStringLiteral( 
"visible" ), treeNode->
isVisible() );
 
  893           layerElem.setAttribute( QStringLiteral( 
"expanded" ), treeNode->
isExpanded() );
 
  900           QString name = treeGroupChild->
name();
 
  901           if ( restrictedLayers.contains( name ) ) 
 
  906           if ( projectSettings )
 
  908             layerElem.setAttribute( QStringLiteral( 
"mutuallyExclusive" ), treeGroupChild->
isMutuallyExclusive() );
 
  911           QString shortName = treeGroupChild->
customProperty( QStringLiteral( 
"wmsShortName" ) ).toString();
 
  912           QString title = treeGroupChild->
customProperty( QStringLiteral( 
"wmsTitle" ) ).toString();
 
  914           QDomElement nameElem = doc.createElement( QStringLiteral( 
"Name" ) );
 
  916           if ( !shortName.isEmpty() )
 
  917             nameText = doc.createTextNode( shortName );
 
  919             nameText = doc.createTextNode( name );
 
  920           nameElem.appendChild( nameText );
 
  921           layerElem.appendChild( nameElem );
 
  923           QDomElement titleElem = doc.createElement( QStringLiteral( 
"Title" ) );
 
  925           if ( !title.isEmpty() )
 
  926             titleText = doc.createTextNode( title );
 
  928             titleText = doc.createTextNode( name );
 
  929           titleElem.appendChild( titleText );
 
  930           layerElem.appendChild( titleElem );
 
  932           QString 
abstract = treeGroupChild->
customProperty( QStringLiteral( 
"wmsAbstract" ) ).toString();
 
  933           if ( !
abstract.isEmpty() )
 
  935             QDomElement abstractElem = doc.createElement( QStringLiteral( 
"Abstract" ) );
 
  936             QDomText abstractText = doc.createTextNode( 
abstract );
 
  937             abstractElem.appendChild( abstractText );
 
  938             layerElem.appendChild( abstractElem );
 
  942           if ( projectSettings )
 
  944             QDomElement treeNameElem = doc.createElement( QStringLiteral( 
"TreeName" ) );
 
  945             QDomText treeNameText = doc.createTextNode( name );
 
  946             treeNameElem.appendChild( treeNameText );
 
  947             layerElem.appendChild( treeNameElem );
 
  953             layerElem.setAttribute( QStringLiteral( 
"queryable" ), QStringLiteral( 
"1" ) );
 
  957             layerElem.setAttribute( QStringLiteral( 
"queryable" ), QStringLiteral( 
"0" ) );
 
  960           appendLayersFromTreeGroup( doc, layerElem, serverIface, project, request, treeGroupChild, projectSettings );
 
  962           combineExtentAndCrsOfGroupChildren( doc, layerElem, project );
 
  968           if ( !l || restrictedLayers.contains( l->
name() ) ) 
 
  973 #ifdef HAVE_SERVER_PYTHON_PLUGINS 
  980           QString wmsName = l->
name();
 
  993             layerElem.setAttribute( QStringLiteral( 
"queryable" ), QStringLiteral( 
"0" ) );
 
  997             layerElem.setAttribute( QStringLiteral( 
"queryable" ), QStringLiteral( 
"1" ) );
 
 1000           QDomElement nameElem = doc.createElement( QStringLiteral( 
"Name" ) );
 
 1001           QDomText nameText = doc.createTextNode( wmsName );
 
 1002           nameElem.appendChild( nameText );
 
 1003           layerElem.appendChild( nameElem );
 
 1005           QDomElement titleElem = doc.createElement( QStringLiteral( 
"Title" ) );
 
 1006           QString title = l->
title();
 
 1007           if ( title.isEmpty() )
 
 1011           QDomText titleText = doc.createTextNode( title );
 
 1012           titleElem.appendChild( titleText );
 
 1013           layerElem.appendChild( titleElem );
 
 1016           if ( !
abstract.isEmpty() )
 
 1018             QDomElement abstractElem = doc.createElement( QStringLiteral( 
"Abstract" ) );
 
 1019             QDomText abstractText = doc.createTextNode( 
abstract );
 
 1020             abstractElem.appendChild( abstractText );
 
 1021             layerElem.appendChild( abstractElem );
 
 1027             QStringList keywordStringList = l->
keywordList().split( 
',' );
 
 1029             QDomElement keywordListElem = doc.createElement( QStringLiteral( 
"KeywordList" ) );
 
 1030             for ( 
int i = 0; i < keywordStringList.size(); ++i )
 
 1032               QDomElement keywordElem = doc.createElement( QStringLiteral( 
"Keyword" ) );
 
 1033               QDomText keywordText = doc.createTextNode( keywordStringList.at( i ).trimmed() );
 
 1034               keywordElem.appendChild( keywordText );
 
 1037                 keywordElem.setAttribute( QStringLiteral( 
"vocabulary" ), QStringLiteral( 
"SIA_Geo405" ) );
 
 1039               keywordListElem.appendChild( keywordElem );
 
 1041             layerElem.appendChild( keywordListElem );
 
 1045           bool geometryLayer = 
true;
 
 1053                 geometryLayer = 
false;
 
 1059           if ( geometryLayer )
 
 1061             QStringList crsList;
 
 1064             appendCrsElementsToLayer( doc, layerElem, crsList, outputCrsList );
 
 1079               else if ( l->
crs() != project->
crs() )
 
 1085                   extent = ct.transform( extent );
 
 1089                   QgsMessageLog::logMessage( QStringLiteral( 
"Error transforming extent for layer %1: %2" ).arg( l->
name() ).arg( cse.
what() ), QStringLiteral( 
"Server" ), Qgis::MessageLevel::Warning );
 
 1100             appendLayerBoundingBoxes( doc, layerElem, extent, l->
crs(), crsList, outputCrsList, project, wgs84Extent );
 
 1104           appendLayerStyles( doc, layerElem, l, project, request, serverIface->
serverSettings() );
 
 1109             if ( version == QLatin1String( 
"1.1.1" ) )
 
 1112               double SCALE_TO_SCALEHINT = 
OGC_PX_M * M_SQRT2;
 
 1114               QDomElement scaleHintElem = doc.createElement( QStringLiteral( 
"ScaleHint" ) );
 
 1115               scaleHintElem.setAttribute( QStringLiteral( 
"min" ), QString::number( l->
maximumScale() * SCALE_TO_SCALEHINT ) );
 
 1116               scaleHintElem.setAttribute( QStringLiteral( 
"max" ), QString::number( l->
minimumScale() * SCALE_TO_SCALEHINT ) );
 
 1117               layerElem.appendChild( scaleHintElem );
 
 1121               QString minScaleString = QString::number( l->
maximumScale() );
 
 1122               QDomElement minScaleElem = doc.createElement( QStringLiteral( 
"MinScaleDenominator" ) );
 
 1123               QDomText minScaleText = doc.createTextNode( minScaleString );
 
 1124               minScaleElem.appendChild( minScaleText );
 
 1125               layerElem.appendChild( minScaleElem );
 
 1127               QString maxScaleString = QString::number( l->
minimumScale() );
 
 1128               QDomElement maxScaleElem = doc.createElement( QStringLiteral( 
"MaxScaleDenominator" ) );
 
 1129               QDomText maxScaleText = doc.createTextNode( maxScaleString );
 
 1130               maxScaleElem.appendChild( maxScaleText );
 
 1131               layerElem.appendChild( maxScaleElem );
 
 1136           QString dataUrl = l->
dataUrl();
 
 1137           if ( !dataUrl.isEmpty() )
 
 1139             QDomElement dataUrlElem = doc.createElement( QStringLiteral( 
"DataURL" ) );
 
 1140             QDomElement dataUrlFormatElem = doc.createElement( QStringLiteral( 
"Format" ) );
 
 1142             QDomText dataUrlFormatText = doc.createTextNode( dataUrlFormat );
 
 1143             dataUrlFormatElem.appendChild( dataUrlFormatText );
 
 1144             dataUrlElem.appendChild( dataUrlFormatElem );
 
 1145             QDomElement dataORElem = doc.createElement( QStringLiteral( 
"OnlineResource" ) );
 
 1146             dataORElem.setAttribute( QStringLiteral( 
"xmlns:xlink" ), QStringLiteral( 
"http://www.w3.org/1999/xlink" ) );
 
 1147             dataORElem.setAttribute( QStringLiteral( 
"xlink:type" ), QStringLiteral( 
"simple" ) );
 
 1148             dataORElem.setAttribute( QStringLiteral( 
"xlink:href" ), dataUrl );
 
 1149             dataUrlElem.appendChild( dataORElem );
 
 1150             layerElem.appendChild( dataUrlElem );
 
 1155           if ( !attribution.isEmpty() )
 
 1157             QDomElement attribElem = doc.createElement( QStringLiteral( 
"Attribution" ) );
 
 1158             QDomElement attribTitleElem = doc.createElement( QStringLiteral( 
"Title" ) );
 
 1159             QDomText attribText = doc.createTextNode( attribution );
 
 1160             attribTitleElem.appendChild( attribText );
 
 1161             attribElem.appendChild( attribTitleElem );
 
 1163             if ( !attributionUrl.isEmpty() )
 
 1165               QDomElement attribORElem = doc.createElement( QStringLiteral( 
"OnlineResource" ) );
 
 1166               attribORElem.setAttribute( QStringLiteral( 
"xmlns:xlink" ), QStringLiteral( 
"http://www.w3.org/1999/xlink" ) );
 
 1167               attribORElem.setAttribute( QStringLiteral( 
"xlink:type" ), QStringLiteral( 
"simple" ) );
 
 1168               attribORElem.setAttribute( QStringLiteral( 
"xlink:href" ), attributionUrl );
 
 1169               attribElem.appendChild( attribORElem );
 
 1171             layerElem.appendChild( attribElem );
 
 1176           if ( !metadataUrl.isEmpty() )
 
 1178             QDomElement metaUrlElem = doc.createElement( QStringLiteral( 
"MetadataURL" ) );
 
 1180             if ( version == QLatin1String( 
"1.1.1" ) )
 
 1182               metaUrlElem.setAttribute( QStringLiteral( 
"type" ), metadataUrlType );
 
 1184             else if ( metadataUrlType == QLatin1String( 
"FGDC" ) )
 
 1186               metaUrlElem.setAttribute( QStringLiteral( 
"type" ), QStringLiteral( 
"FGDC:1998" ) );
 
 1188             else if ( metadataUrlType == QLatin1String( 
"TC211" ) )
 
 1190               metaUrlElem.setAttribute( QStringLiteral( 
"type" ), QStringLiteral( 
"ISO19115:2003" ) );
 
 1194               metaUrlElem.setAttribute( QStringLiteral( 
"type" ), metadataUrlType );
 
 1197             if ( !metadataUrlFormat.isEmpty() )
 
 1199               QDomElement metaUrlFormatElem = doc.createElement( QStringLiteral( 
"Format" ) );
 
 1200               QDomText metaUrlFormatText = doc.createTextNode( metadataUrlFormat );
 
 1201               metaUrlFormatElem.appendChild( metaUrlFormatText );
 
 1202               metaUrlElem.appendChild( metaUrlFormatElem );
 
 1204             QDomElement metaUrlORElem = doc.createElement( QStringLiteral( 
"OnlineResource" ) );
 
 1205             metaUrlORElem.setAttribute( QStringLiteral( 
"xmlns:xlink" ), QStringLiteral( 
"http://www.w3.org/1999/xlink" ) );
 
 1206             metaUrlORElem.setAttribute( QStringLiteral( 
"xlink:type" ), QStringLiteral( 
"simple" ) );
 
 1207             metaUrlORElem.setAttribute( QStringLiteral( 
"xlink:href" ), metadataUrl );
 
 1208             metaUrlElem.appendChild( metaUrlORElem );
 
 1209             layerElem.appendChild( metaUrlElem );
 
 1221               if ( fieldIndex == -1 )
 
 1226               QSet<QVariant> uniqueValues = vl->
uniqueValues( fieldIndex );
 
 1229               if ( !dim.endFieldName.isEmpty() )
 
 1231                 int endFieldIndex = vl->
fields().
indexOf( dim.endFieldName );
 
 1233                 if ( endFieldIndex == -1 )
 
 1237                 uniqueValues.unite( vl->
uniqueValues( endFieldIndex ) );
 
 1240               QList<QVariant> values = qgis::setToList( uniqueValues );
 
 1241               std::sort( values.begin(), values.end() );
 
 1243               QDomElement dimElem = doc.createElement( QStringLiteral( 
"Dimension" ) );
 
 1244               dimElem.setAttribute( QStringLiteral( 
"name" ), dim.name );
 
 1245               if ( !dim.units.isEmpty() )
 
 1247                 dimElem.setAttribute( QStringLiteral( 
"units" ), dim.units );
 
 1249               if ( !dim.unitSymbol.isEmpty() )
 
 1251                 dimElem.setAttribute( QStringLiteral( 
"unitSymbol" ), dim.unitSymbol );
 
 1255                 dimElem.setAttribute( QStringLiteral( 
"default" ), values.first().toString() );
 
 1259                 dimElem.setAttribute( QStringLiteral( 
"default" ), values.last().toString() );
 
 1263                 dimElem.setAttribute( QStringLiteral( 
"default" ), dim.referenceValue.toString() );
 
 1265               dimElem.setAttribute( QStringLiteral( 
"multipleValues" ), QStringLiteral( 
"1" ) );
 
 1266               dimElem.setAttribute( QStringLiteral( 
"nearestValue" ), QStringLiteral( 
"0" ) );
 
 1268               QStringList strValues;
 
 1269               for ( 
const QVariant &v : values )
 
 1271                 strValues << v.toString();
 
 1273               QDomText dimValuesText = doc.createTextNode( strValues.join( QLatin1String( 
", " ) ) );
 
 1274               dimElem.appendChild( dimValuesText );
 
 1275               layerElem.appendChild( dimElem );
 
 1279           if ( projectSettings )
 
 1281             appendLayerProjectSettings( doc, layerElem, l );
 
 1285         parentLayer.appendChild( layerElem );
 
 1289     void appendLayerStyles( QDomDocument &doc, QDomElement &layerElem, 
QgsMapLayer *currentLayer,
 
 1293       QUrl href = 
serviceUrl( request, project, *settings );
 
 1296       QString hrefString = href.toString();
 
 1297       hrefString.append( href.hasQuery() ? 
"&" : 
"?" );
 
 1300         QDomElement styleElem = doc.createElement( QStringLiteral( 
"Style" ) );
 
 1301         QDomElement styleNameElem = doc.createElement( QStringLiteral( 
"Name" ) );
 
 1302         QDomText styleNameText = doc.createTextNode( styleName );
 
 1303         styleNameElem.appendChild( styleNameText );
 
 1304         QDomElement styleTitleElem = doc.createElement( QStringLiteral( 
"Title" ) );
 
 1305         QDomText styleTitleText = doc.createTextNode( styleName );
 
 1306         styleTitleElem.appendChild( styleTitleText );
 
 1307         styleElem.appendChild( styleNameElem );
 
 1308         styleElem.appendChild( styleTitleElem );
 
 1311         QDomElement getLayerLegendGraphicElem = doc.createElement( QStringLiteral( 
"LegendURL" ) );
 
 1313         QString customHrefString = currentLayer->
legendUrl();
 
 1315         QStringList getLayerLegendGraphicFormats;
 
 1316         if ( !customHrefString.isEmpty() )
 
 1322           getLayerLegendGraphicFormats << QStringLiteral( 
"image/png" ); 
 
 1325         for ( 
int i = 0; i < getLayerLegendGraphicFormats.size(); ++i )
 
 1327           QDomElement getLayerLegendGraphicFormatElem = doc.createElement( QStringLiteral( 
"Format" ) );
 
 1328           QString getLayerLegendGraphicFormat = getLayerLegendGraphicFormats[i];
 
 1329           QDomText getLayerLegendGraphicFormatText = doc.createTextNode( getLayerLegendGraphicFormat );
 
 1330           getLayerLegendGraphicFormatElem.appendChild( getLayerLegendGraphicFormatText );
 
 1331           getLayerLegendGraphicElem.appendChild( getLayerLegendGraphicFormatElem );
 
 1335         if ( customHrefString.isEmpty() )
 
 1337           QString layerName = currentLayer->
name();
 
 1339             layerName = currentLayer->
id();
 
 1340           else if ( !currentLayer->
shortName().isEmpty() )
 
 1342           QUrl mapUrl( hrefString );
 
 1343           QUrlQuery mapUrlQuery( mapUrl.query() );
 
 1344           mapUrlQuery.addQueryItem( QStringLiteral( 
"SERVICE" ), QStringLiteral( 
"WMS" ) );
 
 1345           mapUrlQuery.addQueryItem( QStringLiteral( 
"VERSION" ), request.wmsParameters().version() );
 
 1346           mapUrlQuery.addQueryItem( QStringLiteral( 
"REQUEST" ), QStringLiteral( 
"GetLegendGraphic" ) );
 
 1347           mapUrlQuery.addQueryItem( QStringLiteral( 
"LAYER" ), layerName );
 
 1348           mapUrlQuery.addQueryItem( QStringLiteral( 
"FORMAT" ), QStringLiteral( 
"image/png" ) );
 
 1349           mapUrlQuery.addQueryItem( QStringLiteral( 
"STYLE" ), styleNameText.data() );
 
 1350           if ( request.wmsParameters().version() == QLatin1String( 
"1.3.0" ) )
 
 1352             mapUrlQuery.addQueryItem( QStringLiteral( 
"SLD_VERSION" ), QStringLiteral( 
"1.1.0" ) );
 
 1354           mapUrl.setQuery( mapUrlQuery );
 
 1355           customHrefString = mapUrl.toString();
 
 1358         QDomElement getLayerLegendGraphicORElem = doc.createElement( QStringLiteral( 
"OnlineResource" ) );
 
 1359         getLayerLegendGraphicORElem.setAttribute( QStringLiteral( 
"xmlns:xlink" ), QStringLiteral( 
"http://www.w3.org/1999/xlink" ) );
 
 1360         getLayerLegendGraphicORElem.setAttribute( QStringLiteral( 
"xlink:type" ), QStringLiteral( 
"simple" ) );
 
 1361         getLayerLegendGraphicORElem.setAttribute( QStringLiteral( 
"xlink:href" ), customHrefString );
 
 1362         getLayerLegendGraphicElem.appendChild( getLayerLegendGraphicORElem );
 
 1363         styleElem.appendChild( getLayerLegendGraphicElem );
 
 1365         layerElem.appendChild( styleElem );
 
 1369     void appendCrsElementsToLayer( QDomDocument &doc, QDomElement &layerElement,
 
 1370                                    const QStringList &crsList, 
const QStringList &constrainedCrsList )
 
 1372       if ( layerElement.isNull() )
 
 1378       QDomElement titleElement = layerElement.firstChildElement( QStringLiteral( 
"Title" ) );
 
 1379       QDomElement abstractElement = layerElement.firstChildElement( QStringLiteral( 
"Abstract" ) );
 
 1380       QDomElement keywordListElement = layerElement.firstChildElement( QStringLiteral( 
"KeywordList" ) );
 
 1381       QDomElement CRSPrecedingElement = !keywordListElement.isNull() ? keywordListElement : !abstractElement.isNull() ? abstractElement : titleElement;
 
 1383       if ( CRSPrecedingElement.isNull() )
 
 1386         const QDomElement keyElement = layerElement.firstChildElement( QStringLiteral( 
"KeywordList" ) );
 
 1387         CRSPrecedingElement = keyElement;
 
 1391       if ( !constrainedCrsList.isEmpty() )
 
 1393         for ( 
int i = constrainedCrsList.size() - 1; i >= 0; --i )
 
 1395           appendCrsElementToLayer( doc, layerElement, CRSPrecedingElement, constrainedCrsList.at( i ) );
 
 1400         for ( 
const QString &
crs : crsList )
 
 1402           appendCrsElementToLayer( doc, layerElement, CRSPrecedingElement, 
crs );
 
 1407       appendCrsElementToLayer( doc, layerElement, CRSPrecedingElement, QString( 
"CRS:84" ) );
 
 1410     void appendCrsElementToLayer( QDomDocument &doc, QDomElement &layerElement, 
const QDomElement &precedingElement,
 
 1411                                   const QString &crsText )
 
 1413       if ( crsText.isEmpty() )
 
 1415       QString version = doc.documentElement().attribute( QStringLiteral( 
"version" ) );
 
 1416       QDomElement crsElement = doc.createElement( version == QLatin1String( 
"1.1.1" ) ? 
"SRS" : 
"CRS" );
 
 1417       QDomText crsTextNode = doc.createTextNode( crsText );
 
 1418       crsElement.appendChild( crsTextNode );
 
 1419       layerElement.insertAfter( crsElement, precedingElement );
 
 1422     void appendLayerBoundingBoxes( QDomDocument &doc, QDomElement &layerElem, 
const QgsRectangle &lExtent,
 
 1424                                    const QStringList &constrainedCrsList, 
const QgsProject *project,
 
 1427       if ( layerElem.isNull() )
 
 1436         layerExtent.
grow( 0.000001 );
 
 1440       if ( wgs84BoundingRect.
isNull() )
 
 1445         if ( !layerExtent.
isNull() )
 
 1450             wgs84BoundingRect = exGeoTransform.transformBoundingBox( layerExtent );
 
 1454             QgsMessageLog::logMessage( QStringLiteral( 
"Error transforming extent: %1" ).arg( cse.
what() ), QStringLiteral( 
"Server" ), Qgis::MessageLevel::Warning );
 
 1463         wgs84BoundingRect.
grow( 0.000001 );
 
 1467       QDomElement ExGeoBBoxElement;
 
 1468       const int wgs84precision = 6;
 
 1469       const QString version = doc.documentElement().attribute( QStringLiteral( 
"version" ) );
 
 1470       if ( version == QLatin1String( 
"1.1.1" ) ) 
 
 1472         ExGeoBBoxElement = doc.createElement( QStringLiteral( 
"LatLonBoundingBox" ) );
 
 1480         ExGeoBBoxElement = doc.createElement( QStringLiteral( 
"EX_GeographicBoundingBox" ) );
 
 1481         QDomElement wBoundLongitudeElement = doc.createElement( QStringLiteral( 
"westBoundLongitude" ) );
 
 1483         wBoundLongitudeElement.appendChild( wBoundLongitudeText );
 
 1484         ExGeoBBoxElement.appendChild( wBoundLongitudeElement );
 
 1485         QDomElement eBoundLongitudeElement = doc.createElement( QStringLiteral( 
"eastBoundLongitude" ) );
 
 1487         eBoundLongitudeElement.appendChild( eBoundLongitudeText );
 
 1488         ExGeoBBoxElement.appendChild( eBoundLongitudeElement );
 
 1489         QDomElement sBoundLatitudeElement = doc.createElement( QStringLiteral( 
"southBoundLatitude" ) );
 
 1491         sBoundLatitudeElement.appendChild( sBoundLatitudeText );
 
 1492         ExGeoBBoxElement.appendChild( sBoundLatitudeElement );
 
 1493         QDomElement nBoundLatitudeElement = doc.createElement( QStringLiteral( 
"northBoundLatitude" ) );
 
 1495         nBoundLatitudeElement.appendChild( nBoundLatitudeText );
 
 1496         ExGeoBBoxElement.appendChild( nBoundLatitudeElement );
 
 1499       if ( !wgs84BoundingRect.
isNull() ) 
 
 1501         QDomElement lastCRSElem = layerElem.lastChildElement( version == QLatin1String( 
"1.1.1" ) ? 
"SRS" : 
"CRS" );
 
 1502         if ( !lastCRSElem.isNull() )
 
 1504           layerElem.insertAfter( ExGeoBBoxElement, lastCRSElem );
 
 1508           layerElem.appendChild( ExGeoBBoxElement );
 
 1513       if ( !constrainedCrsList.isEmpty() )
 
 1515         for ( 
int i = constrainedCrsList.size() - 1; i >= 0; --i )
 
 1517           appendLayerBoundingBox( doc, layerElem, layerExtent, layerCRS, constrainedCrsList.at( i ), project );
 
 1522         for ( 
const QString &
crs : crsList )
 
 1524           appendLayerBoundingBox( doc, layerElem, layerExtent, layerCRS, 
crs, project );
 
 1530     void appendLayerBoundingBox( QDomDocument &doc, QDomElement &layerElem, 
const QgsRectangle &layerExtent,
 
 1534       if ( layerElem.isNull() )
 
 1539       if ( crsText.isEmpty() )
 
 1544       QString version = doc.documentElement().attribute( QStringLiteral( 
"version" ) );
 
 1550       if ( !layerExtent.
isNull() )
 
 1555           crsExtent = crsTransform.transformBoundingBox( layerExtent );
 
 1559           QgsMessageLog::logMessage( QStringLiteral( 
"Error transforming extent: %1" ).arg( cse.
what() ), QStringLiteral( 
"Server" ), Qgis::MessageLevel::Warning );
 
 1564       if ( crsExtent.
isNull() )
 
 1576       QDomElement bBoxElement = doc.createElement( QStringLiteral( 
"BoundingBox" ) );
 
 1579         bBoxElement.setAttribute( version == QLatin1String( 
"1.1.1" ) ? 
"SRS" : 
"CRS", 
crs.
authid() );
 
 1592       QDomElement lastBBoxElem = layerElem.lastChildElement( QStringLiteral( 
"BoundingBox" ) );
 
 1593       if ( !lastBBoxElem.isNull() )
 
 1595         layerElem.insertAfter( bBoxElement, lastBBoxElem );
 
 1599         lastBBoxElem = layerElem.lastChildElement( version == QLatin1String( 
"1.1.1" ) ? 
"LatLonBoundingBox" : 
"EX_GeographicBoundingBox" );
 
 1600         if ( !lastBBoxElem.isNull() )
 
 1602           layerElem.insertAfter( bBoxElement, lastBBoxElem );
 
 1606           layerElem.appendChild( bBoxElement );
 
 1611     QgsRectangle layerBoundingBoxInProjectCrs( 
const QDomDocument &doc, 
const QDomElement &layerElem,
 
 1615       if ( layerElem.isNull() )
 
 1621       QDomElement boundingBoxElem = layerElem.firstChildElement( QStringLiteral( 
"BoundingBox" ) );
 
 1622       if ( boundingBoxElem.isNull() )
 
 1627       double minx, miny, maxx, maxy;
 
 1629       minx = boundingBoxElem.attribute( QStringLiteral( 
"minx" ) ).toDouble( &conversionOk );
 
 1630       if ( !conversionOk )
 
 1634       miny = boundingBoxElem.attribute( QStringLiteral( 
"miny" ) ).toDouble( &conversionOk );
 
 1635       if ( !conversionOk )
 
 1639       maxx = boundingBoxElem.attribute( QStringLiteral( 
"maxx" ) ).toDouble( &conversionOk );
 
 1640       if ( !conversionOk )
 
 1644       maxy = boundingBoxElem.attribute( QStringLiteral( 
"maxy" ) ).toDouble( &conversionOk );
 
 1645       if ( !conversionOk )
 
 1651       QString version = doc.documentElement().attribute( QStringLiteral( 
"version" ) );
 
 1665       if ( version != QLatin1String( 
"1.1.1" ) && layerCrs.
hasAxisInverted() )
 
 1676         BBox = t.transformBoundingBox( BBox );
 
 1680         QgsMessageLog::logMessage( QStringLiteral( 
"Error transforming extent: %1" ).arg( cse.
what() ), QStringLiteral( 
"Server" ), Qgis::MessageLevel::Warning );
 
 1687     bool crsSetFromLayerElement( 
const QDomElement &layerElement, QSet<QString> &crsSet )
 
 1689       if ( layerElement.isNull() )
 
 1696       QDomNodeList crsNodeList;
 
 1697       crsNodeList = layerElement.elementsByTagName( QStringLiteral( 
"CRS" ) ); 
 
 1698       for ( 
int i = 0; i < crsNodeList.size(); ++i )
 
 1700         crsSet.insert( crsNodeList.at( i ).toElement().text() );
 
 1703       crsNodeList = layerElement.elementsByTagName( QStringLiteral( 
"SRS" ) ); 
 
 1704       for ( 
int i = 0; i < crsNodeList.size(); ++i )
 
 1706         crsSet.insert( crsNodeList.at( i ).toElement().text() );
 
 1712     void combineExtentAndCrsOfGroupChildren( QDomDocument &doc, QDomElement &groupElem, 
const QgsProject *project,
 
 1713         bool considerMapExtent )
 
 1716       QSet<QString> combinedCRSSet;
 
 1717       bool firstBBox = 
true;
 
 1718       bool firstCRSSet = 
true;
 
 1720       QDomNodeList layerChildren = groupElem.childNodes();
 
 1721       for ( 
int j = 0; j < layerChildren.size(); ++j )
 
 1723         QDomElement childElem = layerChildren.at( j ).toElement();
 
 1725         if ( childElem.tagName() != QLatin1String( 
"Layer" ) )
 
 1728         QgsRectangle bbox = layerBoundingBoxInProjectCrs( doc, childElem, project );
 
 1738             combinedBBox = bbox;
 
 1748         QSet<QString> crsSet;
 
 1749         if ( crsSetFromLayerElement( childElem, crsSet ) )
 
 1753             combinedCRSSet = crsSet;
 
 1754             firstCRSSet = 
false;
 
 1758             combinedCRSSet.intersect( crsSet );
 
 1764       appendCrsElementsToLayer( doc, groupElem, qgis::setToList( combinedCRSSet ), outputCrsList );
 
 1767       if ( considerMapExtent )
 
 1772           combinedBBox = mapRect;
 
 1775       appendLayerBoundingBoxes( doc, groupElem, combinedBBox, groupCRS, qgis::setToList( combinedCRSSet ), outputCrsList, project );
 
 1779     void appendDrawingOrder( QDomDocument &doc, QDomElement &parentElem, 
QgsServerInterface *serverIface,
 
 1782 #ifdef HAVE_SERVER_PYTHON_PLUGINS 
 1785       ( void )serverIface;
 
 1790       QStringList layerList;
 
 1793       QList< QgsMapLayer * > projectLayerOrder = projectLayerTreeRoot->
layerOrder();
 
 1794       for ( 
int i = 0; i < projectLayerOrder.size(); ++i )
 
 1798         if ( restrictedLayers.contains( l->
name() ) ) 
 
 1802 #ifdef HAVE_SERVER_PYTHON_PLUGINS 
 1808         QString wmsName = l->
name();
 
 1818         layerList <<  wmsName;
 
 1821       if ( !layerList.isEmpty() )
 
 1823         QStringList reversedList;
 
 1824         reversedList.reserve( layerList.size() );
 
 1825         for ( 
int i = layerList.size() - 1; i >= 0; --i )
 
 1826           reversedList << layerList[ i ];
 
 1828         QDomElement layerDrawingOrderElem = doc.createElement( QStringLiteral( 
"LayerDrawingOrder" ) );
 
 1829         QDomText drawingOrderText = doc.createTextNode( reversedList.join( 
',' ) );
 
 1830         layerDrawingOrderElem.appendChild( drawingOrderText );
 
 1831         parentElem.appendChild( layerDrawingOrderElem );
 
 1835     void appendLayerProjectSettings( QDomDocument &doc, QDomElement &layerElem, 
QgsMapLayer *currentLayer )
 
 1837       if ( !currentLayer )
 
 1843       QDomElement treeNameElem = doc.createElement( QStringLiteral( 
"TreeName" ) );
 
 1844       QDomText treeNameText = doc.createTextNode( currentLayer->
name() );
 
 1845       treeNameElem.appendChild( treeNameText );
 
 1846       layerElem.appendChild( treeNameElem );
 
 1848       switch ( currentLayer->
type() )
 
 1854           int displayFieldIdx = -1;
 
 1855           QString displayField = QStringLiteral( 
"maptip" );
 
 1857           if ( exp.isField() )
 
 1864           QDomElement attributesElem = doc.createElement( QStringLiteral( 
"Attributes" ) );
 
 1866           for ( 
int idx = 0; idx < layerFields.
count(); ++idx )
 
 1874             if ( idx == displayFieldIdx )
 
 1878             QDomElement attributeElem = doc.createElement( QStringLiteral( 
"Attribute" ) );
 
 1879             attributeElem.setAttribute( QStringLiteral( 
"name" ), 
field.
name() );
 
 1880             attributeElem.setAttribute( QStringLiteral( 
"type" ), QVariant::typeToName( 
field.
type() ) );
 
 1881             attributeElem.setAttribute( QStringLiteral( 
"typeName" ), 
field.
typeName() );
 
 1883             if ( !alias.isEmpty() )
 
 1885               attributeElem.setAttribute( QStringLiteral( 
"alias" ), alias );
 
 1889             attributeElem.setAttribute( QStringLiteral( 
"editType" ), vLayer->
editorWidgetSetup( idx ).
type() );
 
 1890             attributeElem.setAttribute( QStringLiteral( 
"comment" ), 
field.
comment() );
 
 1891             attributeElem.setAttribute( QStringLiteral( 
"length" ), 
field.
length() );
 
 1892             attributeElem.setAttribute( QStringLiteral( 
"precision" ), 
field.
precision() );
 
 1893             attributesElem.appendChild( attributeElem );
 
 1897           layerElem.setAttribute( QStringLiteral( 
"displayField" ), displayField );
 
 1901           if ( pkAttributes.size() > 0 )
 
 1903             QDomElement pkElem = doc.createElement( QStringLiteral( 
"PrimaryKey" ) );
 
 1904             QgsAttributeList::const_iterator pkIt = pkAttributes.constBegin();
 
 1905             for ( ; pkIt != pkAttributes.constEnd(); ++pkIt )
 
 1907               QDomElement pkAttributeElem = doc.createElement( QStringLiteral( 
"PrimaryKeyAttribute" ) );
 
 1908               QDomText pkAttName = doc.createTextNode( layerFields.
at( *pkIt ).
name() );
 
 1909               pkAttributeElem.appendChild( pkAttName );
 
 1910               pkElem.appendChild( pkAttributeElem );
 
 1912             layerElem.appendChild( pkElem );
 
 1919           layerElem.setAttribute( QStringLiteral( 
"opacity" ), QString::number( vLayer->
opacity() ) );
 
 1921           layerElem.appendChild( attributesElem );
 
 1928           if ( provider && provider->
name() == 
"wms" )
 
 1931             QVariant wmsBackgroundLayer = currentLayer->
customProperty( QStringLiteral( 
"WMSBackgroundLayer" ), false );
 
 1932             QDomElement wmsBackgroundLayerElem = doc.createElement( 
"WMSBackgroundLayer" );
 
 1933             QDomText wmsBackgroundLayerText = doc.createTextNode( wmsBackgroundLayer.toBool() ? QStringLiteral( 
"1" ) : QStringLiteral( 
"0" ) );
 
 1934             wmsBackgroundLayerElem.appendChild( wmsBackgroundLayerText );
 
 1935             layerElem.appendChild( wmsBackgroundLayerElem );
 
 1938             QVariant wmsPublishDataSourceUrl = currentLayer->
customProperty( QStringLiteral( 
"WMSPublishDataSourceUrl" ), 
false );
 
 1939             if ( wmsPublishDataSourceUrl.toBool() )
 
 1941               bool tiled = qobject_cast< const QgsRasterDataProvider * >( provider )
 
 1942                            ? !qobject_cast< const QgsRasterDataProvider * >( provider )->nativeResolutions().isEmpty()
 
 1945               QDomElement dataSourceElem = doc.createElement( tiled ? QStringLiteral( 
"WMTSDataSource" ) : QStringLiteral( 
"WMSDataSource" ) );
 
 1946               QDomText dataSourceUri = doc.createTextNode( provider->
dataSourceUri() );
 
 1947               dataSourceElem.appendChild( dataSourceUri );
 
 1948               layerElem.appendChild( dataSourceElem );
 
 1952           QVariant wmsPrintLayer = currentLayer->
customProperty( QStringLiteral( 
"WMSPrintLayer" ) );
 
 1953           if ( wmsPrintLayer.isValid() )
 
 1955             QDomElement wmsPrintLayerElem = doc.createElement( 
"WMSPrintLayer" );
 
 1956             QDomText wmsPrintLayerText = doc.createTextNode( wmsPrintLayer.toString() );
 
 1957             wmsPrintLayerElem.appendChild( wmsPrintLayerText );
 
 1958             layerElem.appendChild( wmsPrintLayerElem );
 
 1964           if ( rasterRenderer )
 
 1966             layerElem.setAttribute( QStringLiteral( 
"opacity" ), QString::number( rasterRenderer->
opacity() ) );
 
 1980     void addKeywordListElement( 
const QgsProject *project, QDomDocument &doc, QDomElement &parent )
 
 1984       QDomElement keywordsElem = doc.createElement( QStringLiteral( 
"KeywordList" ) );
 
 1986       QDomElement keywordElem = doc.createElement( QStringLiteral( 
"Keyword" ) );
 
 1987       keywordElem.setAttribute( QStringLiteral( 
"vocabulary" ), QStringLiteral( 
"ISO" ) );
 
 1988       QDomText keywordText = doc.createTextNode( QStringLiteral( 
"infoMapAccessService" ) );
 
 1989       keywordElem.appendChild( keywordText );
 
 1990       keywordsElem.appendChild( keywordElem );
 
 1991       parent.appendChild( keywordsElem );
 
 1993       for ( 
const QString &keyword : std::as_const( keywords ) )
 
 1995         if ( !keyword.isEmpty() )
 
 1997           keywordElem = doc.createElement( QStringLiteral( 
"Keyword" ) );
 
 1998           keywordText = doc.createTextNode( keyword );
 
 1999           keywordElem.appendChild( keywordText );
 
 2002             keywordElem.setAttribute( QStringLiteral( 
"vocabulary" ), QStringLiteral( 
"SIA_Geo405" ) );
 
 2004           keywordsElem.appendChild( keywordElem );
 
 2007       parent.appendChild( keywordsElem );
 
 2015       for ( 
int j = 0; j < childNode->
children().size(); ++j )
 
 2025       const auto l { treeLayer->
layer() };
 
 2032         QgsMessageLog::logMessage( QStringLiteral( 
"Broken/corrupted layer tree, layer '%1' does not exist: check your project!" ).arg( treeLayer->
name() ), QStringLiteral( 
"Server" ), Qgis::MessageLevel::Warning );
 
A helper class that centralizes restrictions given by all the access control filter plugins.
bool layerReadPermission(const QgsMapLayer *layer) const
Returns the layer read right.
bool fillCacheKey(QStringList &cacheKey) const
Fill the capabilities caching key.
A cache for capabilities xml documents (by configuration file path)
const QDomDocument * searchCapabilitiesDocument(const QString &configFilePath, const QString &key)
Returns cached capabilities document (or 0 if document for configuration file not in cache)
void insertCapabilitiesDocument(const QString &configFilePath, const QString &key, const QDomDocument *doc)
Inserts new capabilities document (creates a copy of the document, does not take ownership)
This class represents a coordinate reference system (CRS).
static QgsCoordinateReferenceSystem fromOgcWmsCrs(const QString &ogcCrs)
Creates a CRS from a given OGC WMS-format Coordinate Reference System string.
bool isValid() const
Returns whether this CRS is correctly initialized and usable.
QgsRectangle bounds() const
Returns the approximate bounds for the region the CRS is usable within.
QString authid() const
Returns the authority identifier for the CRS.
bool hasAxisInverted() const
Returns whether axis is inverted (e.g., for WMS 1.3) for the CRS.
Custom exception class for Coordinate Reference System related exceptions.
Abstract base class for spatial data provider implementations.
virtual QString name() const =0
Returns a provider name.
virtual QString dataSourceUri(bool expandAuthConfig=false) const
Gets the data source specification.
An expression node which takes it value from a feature's field.
Class for parsing and evaluation of expressions (formerly called "search strings").
Encapsulate a field in an attribute table or data source.
QString typeName() const
Gets the field type.
ConfigurationFlags configurationFlags
@ HideFromWms
Fields is available if layer is served as WMS from QGIS server.
Container of fields for a vector layer.
int indexOf(const QString &fieldName) const
Gets the field index from the field name.
int count() const
Returns number of items.
QgsField at(int i) const
Returns the field at particular index (must be in range 0..N-1).
int lookupField(const QString &fieldName) const
Looks up field's index from the field name.
Layer tree group node serves as a container for layers and further groups.
QString name() const override
Returns the group's name.
bool isMutuallyExclusive() const
Returns whether the group is mutually exclusive (only one child can be checked at a time)
Layer tree node points to a map layer.
QString name() const override
Returns the layer's name.
QgsMapLayer * layer() const
Returns the map layer associated with this node.
This class is a base class for nodes in a layer tree.
@ NodeGroup
Container of other groups and layers.
@ NodeLayer
Leaf node pointing to a layer.
bool isVisible() const
Returns whether a node is really visible (ie checked and all its ancestors checked as well)
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...
QList< QgsLayerTreeNode * > children()
Gets list of children of the node. Children are owned by the parent.
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 ...
QgsVectorLayer * coverageLayer() const
Returns the coverage layer used for the atlas features.
bool enabled() const
Returns whether the atlas generation is enabled.
A layout multiframe subclass for HTML content.
A layout item subclass for text labels.
Layout graphical items for displaying a map.
QgsLayoutSize sizeWithUnits() const
Returns the item's current size, including units.
QString id() const
Returns the item's ID name.
QList< QgsPrintLayout * > printLayouts() const
Returns a list of all print layouts contained in the manager.
This class provides a method of storing measurements for use in QGIS layouts using a variety of diffe...
double length() const
Returns the length of the measurement.
int frameCount() const
Returns the number of frames associated with this multiframe.
QgsLayoutFrame * frame(int index) const
Returns the child frame at a specified index from the multiframe.
int pageCount() const
Returns the number of pages in the collection.
QgsLayoutItemPage * page(int pageNumber)
Returns a specific page (by pageNumber) from the collection.
This class provides a method of storing sizes, consisting of a width and height, for use in QGIS layo...
double height() const
Returns the height of the size.
double width() const
Returns the width of the size.
QgsLayoutPageCollection * pageCollection()
Returns a pointer to the layout's page collection, which stores and manages page items in the layout.
void layoutItems(QList< T * > &itemList) const
Returns a list of layout items of a specific type.
void layoutObjects(QList< T * > &objectList) const
Returns a list of layout objects (items and multiframes) of a specific type.
QgsLayoutMeasurement convertFromLayoutUnits(double length, QgsUnitTypes::LayoutUnit unit) const
Converts a length measurement from the layout's native units to a specified target unit.
QStringList styles() const
Returns list of all defined style names.
Base class for all map layer types.
QString legendUrlFormat() const
Returns the format for a URL based layer legend.
QgsRectangle wgs84Extent(bool forceRecalculate=false) const
Returns the WGS84 extent (EPSG:4326) of the layer according to ReadFlag::FlagTrustLayerMetadata.
virtual QgsRectangle extent() const
Returns the extent of the layer.
Q_INVOKABLE QVariant customProperty(const QString &value, const QVariant &defaultValue=QVariant()) const
Read a custom property from layer.
QgsMapLayer::LayerFlags flags() const
Returns the flags for this layer.
QgsCoordinateReferenceSystem crs
QString attribution() const
Returns the attribution of the layer used by QGIS Server in GetCapabilities request.
QString id() const
Returns the layer's unique ID, which is used to access this layer from QgsProject.
QString abstract() const
Returns the abstract of the layer used by QGIS Server in GetCapabilities request.
QString dataUrlFormat() const
Returns the DataUrl format of the layer used by QGIS Server in GetCapabilities request.
QString shortName() const
Returns the short name of the layer used by QGIS Server to identify the layer.
QString title() const
Returns the title of the layer used by QGIS Server in GetCapabilities request.
QString dataUrl() const
Returns the DataUrl of the layer used by QGIS Server in GetCapabilities request.
bool hasScaleBasedVisibility() const
Returns whether scale based visibility is enabled for the layer.
QString metadataUrlFormat() const
Returns the metadata format of the layer used by QGIS Server in GetCapabilities request.
QString metadataUrl() const
Returns the metadata URL of the layer used by QGIS Server in GetCapabilities request.
@ Identifiable
If the layer is identifiable using the identify map tool and as a WMS layer.
QString attributionUrl() const
Returns the attribution URL of the layer used by QGIS Server in GetCapabilities request.
double minimumScale() const
Returns the minimum map scale (i.e.
QgsMapLayerStyleManager * styleManager() const
Gets access to the layer's style manager.
QString legendUrl() const
Returns the URL for the layer's legend.
virtual Q_INVOKABLE QgsDataProvider * dataProvider()
Returns the layer's data provider, it may be nullptr.
QString metadataUrlType() const
Returns the metadata type of the layer used by QGIS Server in GetCapabilities request.
double maximumScale() const
Returns the maximum map scale (i.e.
QString keywordList() const
Returns the keyword list of the layer used by QGIS Server in GetCapabilities request.
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::MessageLevel::Warning, bool notifyUser=true)
Adds a message to the log instance (and creates it if necessary).
Print layout, a QgsLayout subclass for static or atlas-based layouts.
QgsLayoutAtlas * atlas()
Returns the print layout's atlas.
Encapsulates a QGIS project, including sets of map layers and their styles, layouts,...
QString title() const
Returns the project's title.
Q_INVOKABLE QgsMapLayer * mapLayer(const QString &layerId) const
Retrieve a pointer to a registered layer by layer ID.
QgsCoordinateTransformContext transformContext
QgsLayerTree * layerTreeRoot() const
Returns pointer to the root (invisible) node of the project's layer tree.
const QgsLayoutManager * layoutManager() const
Returns the project's layout manager, which manages print layouts, atlases and reports within the pro...
QgsCoordinateReferenceSystem crs
Represents a raster layer.
QgsRasterRenderer * renderer() const
Returns the raster's renderer.
Raster renderer pipe that applies colors to a raster.
double opacity() const
Returns the opacity for the renderer, where opacity is a value between 0 (totally transparent) and 1....
A rectangle specified with double values.
double yMaximum() const SIP_HOLDGIL
Returns the y maximum value (top side of rectangle).
double xMaximum() const SIP_HOLDGIL
Returns the x maximum value (right side of rectangle).
double xMinimum() const SIP_HOLDGIL
Returns the x minimum value (left side of rectangle).
double yMinimum() const SIP_HOLDGIL
Returns the y minimum value (bottom side of rectangle).
void setYMinimum(double y) SIP_HOLDGIL
Set the minimum y value.
bool isNull() const
Test if the rectangle is null (all coordinates zero or after call to setMinimal()).
void setXMaximum(double x) SIP_HOLDGIL
Set the maximum x value.
void setXMinimum(double x) SIP_HOLDGIL
Set the minimum x value.
void grow(double delta)
Grows the rectangle in place by the specified amount.
void setYMaximum(double y) SIP_HOLDGIL
Set the maximum y value.
void combineExtentWith(const QgsRectangle &rect)
Expands the rectangle so that it covers both the original rectangle and the given rectangle.
bool isEmpty() const
Returns true if the rectangle is empty.
void invert()
Swap x/y coordinates in the rectangle.
A helper class that centralizes caches accesses given by all the server cache filter plugins.
bool setCachedDocument(const QDomDocument *doc, const QgsProject *project, const QgsServerRequest &request, QgsAccessControl *accessControl) const
Updates or inserts the document in cache like capabilities.
bool getCachedDocument(QDomDocument *doc, const QgsProject *project, const QgsServerRequest &request, QgsAccessControl *accessControl) const
Returns cached document (or 0 if document not in cache) like capabilities.
QgsServerInterface Class defining interfaces exposed by QGIS Server and made available to plugins.
virtual QgsAccessControl * accessControls() const =0
Gets the registered access control filters.
virtual QgsServerCacheManager * cacheManager() const =0
Gets the registered server cache filters.
virtual QString configFilePath()=0
Returns the configuration file path.
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< QgsVectorLayerServerProperties::WmsDimensionInfo > wmsDimensions() const
Returns the QGIS Server WMS Dimension list.
Represents a vector layer which manages a vector based data sets.
QString attributeDisplayName(int index) const
Convenience function that returns the attribute alias if defined or the field name else.
Q_INVOKABLE QgsWkbTypes::Type wkbType() const FINAL
Returns the WKBType or WKBUnknown in case of error.
QgsVectorLayerServerProperties * serverProperties() const
Returns QGIS Server Properties of the vector layer.
QgsFields fields() const FINAL
Returns the list of fields of this layer.
QString displayExpression
QgsEditorWidgetSetup editorWidgetSetup(int index) const
The editor widget setup defines which QgsFieldFormatter and editor widget will be used for the field ...
QgsAttributeList primaryKeyAttributes() const
Returns the list of attributes which make up the layer's primary keys.
QSet< QVariant > uniqueValues(int fieldIndex, int limit=-1) const FINAL
Calculates a list of unique values contained within an attribute in the layer.
static QString displayString(Type type) SIP_HOLDGIL
Returns a non-translated display string type for a WKB type, e.g., the geometry name used in WKT geom...
QString version() const override
Returns VERSION parameter as a string or an empty string if not defined.
Class defining request interface passed to WMS service.
const QgsWmsParameters & wmsParameters() const
Returns the parameters interpreted for the WMS service.
@ PointCloudLayer
Added in 3.18.
@ VectorTileLayer
Added in 3.14.
@ AnnotationLayer
Contains freeform, georeferenced annotations. Added in QGIS 3.16.
SERVER_EXPORT QString wmsRootName(const QgsProject &project)
Returns the WMS root layer name defined in a QGIS project.
SERVER_EXPORT bool wmsInfoFormatSia2045(const QgsProject &project)
Returns if the info format is SIA20145.
SERVER_EXPORT QString wmsInspireMetadataUrl(const QgsProject &project)
Returns the Inspire metadata URL.
SERVER_EXPORT double ceilWithPrecision(double number, int places)
Returns a double greater than number to the specified number of places.
SERVER_EXPORT QStringList wmsRestrictedComposers(const QgsProject &project)
Returns the restricted composer list.
SERVER_EXPORT QgsRectangle wmsExtent(const QgsProject &project)
Returns the WMS Extent restriction.
SERVER_EXPORT bool wmsUseLayerIds(const QgsProject &project)
Returns if layer ids are used as name in WMS.
SERVER_EXPORT QString owsServiceAccessConstraints(const QgsProject &project)
Returns the owsService access constraints defined in project.
SERVER_EXPORT QStringList wfsLayerIds(const QgsProject &project)
Returns the Layer ids list defined in a QGIS project as published in WFS.
SERVER_EXPORT QString owsServiceOnlineResource(const QgsProject &project)
Returns the owsService online resource defined in project.
SERVER_EXPORT QString owsServiceFees(const QgsProject &project)
Returns the owsService fees defined in project.
SERVER_EXPORT QStringList owsServiceKeywords(const QgsProject &project)
Returns the owsService keywords defined in project.
SERVER_EXPORT QString owsServiceContactPosition(const QgsProject &project)
Returns the owsService contact position defined in project.
SERVER_EXPORT QString serviceUrl(const QString &service, const QgsServerRequest &request, const QgsServerSettings &settings)
Returns the service url defined in the environment variable or with HTTP header.
SERVER_EXPORT QString wmsInspireTemporalReference(const QgsProject &project)
Returns the Inspire temporal reference.
SERVER_EXPORT QStringList wmsOutputCrsList(const QgsProject &project)
Returns the WMS output CRS list.
SERVER_EXPORT QString wmsInspireMetadataDate(const QgsProject &project)
Returns the Inspire metadata date.
SERVER_EXPORT QString owsServiceContactOrganization(const QgsProject &project)
Returns the owsService contact organization defined in project.
SERVER_EXPORT QStringList wmsRestrictedLayers(const QgsProject &project)
Returns the restricted layer name list.
SERVER_EXPORT QString wmsInspireLanguage(const QgsProject &project)
Returns the Inspire language.
SERVER_EXPORT QString wmsInspireMetadataUrlType(const QgsProject &project)
Returns the Inspire metadata URL type.
SERVER_EXPORT bool wmsInspireActivate(const QgsProject &project)
Returns if Inspire is activated.
SERVER_EXPORT int wmsMaxWidth(const QgsProject &project)
Returns the maximum width for WMS images defined in a QGIS project.
SERVER_EXPORT QString owsServiceTitle(const QgsProject &project)
Returns the owsService title defined in project.
SERVER_EXPORT QString owsServiceContactMail(const QgsProject &project)
Returns the owsService contact mail defined in project.
SERVER_EXPORT QString owsServiceAbstract(const QgsProject &project)
Returns the owsService abstract defined in project.
SERVER_EXPORT double floorWithPrecision(double number, int places)
Returns a double less than number to the specified number of places.
SERVER_EXPORT int wmsMaxHeight(const QgsProject &project)
Returns the maximum height for WMS images defined in a QGIS project.
SERVER_EXPORT QString owsServiceContactPhone(const QgsProject &project)
Returns the owsService contact phone defined in project.
SERVER_EXPORT QString owsServiceContactPerson(const QgsProject &project)
Returns the owsService contact person defined in project.
Median cut implementation.
QDomElement getWFSLayersElement(QDomDocument &doc, const QgsProject *project)
Create WFSLayers element for get capabilities document.
void writeGetCapabilities(QgsServerInterface *serverIface, const QgsProject *project, const QgsWmsRequest &request, QgsServerResponse &response, bool projectSettings)
Output GetCapabilities response.
QDomElement getLayersAndStylesCapabilitiesElement(QDomDocument &doc, QgsServerInterface *serverIface, const QgsProject *project, const QgsWmsRequest &request, bool projectSettings)
Create element for get capabilities document.
QDomElement getInspireCapabilitiesElement(QDomDocument &doc, const QgsProject *project)
Create InspireCapabilities element for get capabilities document.
QDomElement getComposerTemplatesElement(QDomDocument &doc, const QgsProject *project)
Create ComposerTemplates element for get capabilities document.
QDomElement getServiceElement(QDomDocument &doc, const QgsProject *project, const QgsWmsRequest &request, const QgsServerSettings *serverSettings)
Create Service element for get capabilities document.
QDomElement getCapabilityElement(QDomDocument &doc, const QgsProject *project, const QgsWmsRequest &request, bool projectSettings, QgsServerInterface *serverIface)
Create Capability element for get capabilities document.
bool hasQueryableChildren(const QgsLayerTreeNode *childNode, const QStringList &wmsRestrictedLayers)
QDomDocument getCapabilities(QgsServerInterface *serverIface, const QgsProject *project, const QgsWmsRequest &request, bool projectSettings)
Creates the WMS GetCapabilities XML document.
QUrl serviceUrl(const QgsServerRequest &request, const QgsProject *project, const QgsServerSettings &settings)
Returns WMS service URL.
QString qgsDoubleToString(double a, int precision=17)
Returns a string representation of a double.
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
CONSTLATIN1STRING geoEpsgCrsAuthId()
Geographic coord sys from EPSG authority.
QList< int > QgsAttributeList
const QgsCoordinateReferenceSystem & crs
Setting to define QGIS Server WMS Dimension.
@ MaxValue
Modify current selection to include only select features which match.
@ ReferenceValue
Remove from current selection.
@ MinValue
Add selection to current selection.