30   , mInterface( interface )
 
   37   qDeleteAll( mExternalLayers );
 
   38   mExternalLayers.clear();
 
   45   initRestrictedLayers();
 
   48   searchLayersToRender();
 
   49   removeUnwantedLayers();
 
   50   checkLayerReadPermissions();
 
   52   std::reverse( mLayersToRender.begin(), mLayersToRender.end() );
 
   69   return mFlags.testFlag( flag );
 
   92   if ( mSlds.contains( nickname ) )
 
   94     sld = mSlds[ nickname ];
 
  105   if ( mStyles.contains( nickname ) )
 
  107     style = mStyles[ nickname ];
 
  177   if ( !mParameters.
dpi().isEmpty() )
 
  188   std::function <QStringList( 
const QString &name )> findLeaves = [ & ]( 
const QString & name ) -> QStringList
 
  191     if ( mLayerGroups.contains( name ) )
 
  193       const auto &
layers  { mLayerGroups[ name ] };
 
  194       for ( 
const auto &l : 
layers )
 
  198         if ( mLayerGroups.contains( nick ) )
 
  200           _result.append( name );
 
  204           _result.append( findLeaves( nick ) );
 
  210       _result.append( name );
 
  215   for ( 
const auto &name : std::as_const( layerNames ) )
 
  217     result.append( findLeaves( name ) );
 
  224   return mLayersToRender;
 
  229   return mNicknameLayers.values();
 
  234   double denominator = -1;
 
  236   if ( mScaleDenominator >= 0 )
 
  238     denominator = mScaleDenominator;
 
  251   removeUnwantedLayers();
 
  273   else if ( name.isEmpty() )
 
  285   for ( 
auto layer : mLayersToRender )
 
  299   return layer( nickname ) != 
nullptr;
 
  304   return mLayerGroups.value( nickname );
 
  309   return mLayerGroups.contains( name );
 
  312 void QgsWmsRenderContext::initNicknameLayers()
 
  323   initLayerGroupsRecursive( root, rootName.isEmpty() ? mProject->
title() : rootName );
 
  326 void QgsWmsRenderContext::initLayerGroupsRecursive( 
const QgsLayerTreeGroup *group, 
const QString &groupName )
 
  328   if ( !groupName.isEmpty() )
 
  330     mLayerGroups[groupName] = QList<QgsMapLayer *>();
 
  331     const auto projectLayerTreeRoot { mProject->
layerTreeRoot() };
 
  332     const auto treeGroupLayers { group->
findLayers() };
 
  335     if ( ! projectLayerTreeRoot->hasCustomLayerOrder() )
 
  337       for ( 
const auto &tl : treeGroupLayers )
 
  339         mLayerGroups[groupName].push_back( tl->layer() );
 
  344       const auto projectLayerOrder { projectLayerTreeRoot->layerOrder() };
 
  346       QList<QgsMapLayer *> groupLayersList;
 
  347       for ( 
const auto &tl : treeGroupLayers )
 
  349         groupLayersList << tl->layer();
 
  351       for ( 
const auto &l : projectLayerOrder )
 
  353         if ( groupLayersList.contains( l ) )
 
  355           mLayerGroups[groupName].push_back( l );
 
  365       QString name = child->customProperty( QStringLiteral( 
"wmsShortName" ) ).toString();
 
  367       if ( name.isEmpty() )
 
  368         name = child->name();
 
  370       initLayerGroupsRecursive( 
static_cast<const QgsLayerTreeGroup *
>( child ), name );
 
  376 void QgsWmsRenderContext::initRestrictedLayers()
 
  378   mRestrictedLayers.clear();
 
  384   QStringList restrictedLayersNames;
 
  387   for ( 
const QString &l : std::as_const( restricted ) )
 
  392       const QList<QgsLayerTreeLayer *> groupLayers = group->
findLayers();
 
  395         restrictedLayersNames.append( treeLayer->name() );
 
  400       restrictedLayersNames.append( l );
 
  408     if ( restrictedLayersNames.contains( 
layer->
name() ) )
 
  415 void QgsWmsRenderContext::searchLayersToRender()
 
  417   mLayersToRender.clear();
 
  421   if ( ! mParameters.
sldBody().isEmpty() )
 
  423     searchLayersToRenderSld();
 
  427     searchLayersToRenderStyle();
 
  433     for ( 
const QString &layerName : queryLayerNames )
 
  435       const QList<QgsMapLayer *> 
layers = mNicknameLayers.values( layerName );
 
  437         if ( !mLayersToRender.contains( lyr ) )
 
  439           mLayersToRender.append( lyr );
 
  447     for ( 
const QString &layerName : queryLayerNames )
 
  449       const QList<QgsMapLayer *> 
layers = mNicknameLayers.values( layerName );
 
  451         if ( !mLayersToRender.contains( lyr ) )
 
  453           mLayersToRender.append( lyr );
 
  459 void QgsWmsRenderContext::searchLayersToRenderSld()
 
  469   ( void )doc.setContent( 
sld, 
true );
 
  470   QDomElement docEl = doc.documentElement();
 
  472   QDomElement root = doc.firstChildElement( 
"StyledLayerDescriptor" );
 
  473   QDomElement namedElem = root.firstChildElement( 
"NamedLayer" );
 
  475   if ( docEl.isNull() )
 
  480   QDomNodeList named = docEl.elementsByTagName( 
"NamedLayer" );
 
  481   for ( 
int i = 0; i < named.size(); ++i )
 
  483     QDomNodeList names = named.item( i ).toElement().elementsByTagName( 
"Name" );
 
  484     if ( !names.isEmpty() )
 
  486       QString lname = names.item( 0 ).toElement().text();
 
  487       if ( mNicknameLayers.contains( lname ) )
 
  489         mSlds[lname] = namedElem;
 
  490         mLayersToRender.append( mNicknameLayers.values( lname ) );
 
  492       else if ( mLayerGroups.contains( lname ) )
 
  497           mSlds[name] = namedElem;
 
  498           mLayersToRender.insert( 0, 
layer );
 
  504         param.mValue = lname;
 
  512 void QgsWmsRenderContext::searchLayersToRenderStyle()
 
  516     const QString nickname = param.mNickname;
 
  517     const QString 
style = param.mStyle;
 
  521       std::unique_ptr<QgsMapLayer> 
layer = std::make_unique< QgsRasterLayer >( param.mExternalUri, param.mNickname, QStringLiteral( 
"wms" ) );
 
  526         mExternalLayers.append( 
layer.release() );
 
  527         mLayersToRender.append( mExternalLayers.last() );
 
  530     else if ( mNicknameLayers.contains( nickname ) )
 
  532       if ( !
style.isEmpty() )
 
  534         mStyles[nickname] = 
style;
 
  537       mLayersToRender.append( mNicknameLayers.values( nickname ) );
 
  539     else if ( mLayerGroups.contains( nickname ) )
 
  546         if ( !
style.isEmpty() )
 
  548           mStyles[ nickname ] = 
style;
 
  555         mLayersToRender.append( mNicknameLayers.values( name ) );
 
  561       param.mValue = nickname;
 
  568 bool QgsWmsRenderContext::layerScaleVisibility( 
const QString &name )
 const 
  570   bool visible = 
false;
 
  572   if ( ! mNicknameLayers.contains( name ) )
 
  577   const QList<QgsMapLayer *>
layers = mNicknameLayers.values( name );
 
  581     bool useScaleConstraint = ( 
scaleDenominator() > 0 && scaleBasedVisibility );
 
  631   if ( wmsMaxWidthEnv != -1 && wmsMaxWidthProj != -1 )
 
  634     wmsMaxWidth = std::min( wmsMaxWidthProj, wmsMaxWidthEnv );
 
  639     wmsMaxWidth = std::max( wmsMaxWidthProj, wmsMaxWidthEnv );
 
  651   if ( wmsMaxHeightEnv != -1 && wmsMaxHeightProj != -1 )
 
  654     wmsMaxHeight = std::min( wmsMaxHeightProj, wmsMaxHeightEnv );
 
  659     wmsMaxHeight = std::max( wmsMaxHeightProj, wmsMaxHeightEnv );
 
  675   switch ( mParameters.
format() )
 
  677     case QgsWmsParameters::Format::JPG:
 
  683   const int bytes_per_line = ( ( 
mapWidth() * depth + 31 ) >> 5 ) << 2; 
 
  685   if ( std::numeric_limits<int>::max() / depth < static_cast<uint>( 
mapWidth() )
 
  686        || bytes_per_line <= 0
 
  688        || std::numeric_limits<int>::max() / 
static_cast<uint
>( bytes_per_line ) < 
static_cast<uint
>( 
mapHeight() )
 
  689        || std::numeric_limits<int>::max() / 
sizeof( uchar * ) < 
static_cast<uint
>( 
mapHeight() ) )
 
  703     if ( !mParameters.
bbox().isEmpty() && extent.
isEmpty() )
 
  728     if ( !mParameters.
bbox().isEmpty() && extent.
isEmpty() )
 
  734     QString 
crs = mParameters.
crs();
 
  735     if ( 
crs.compare( 
"CRS:84", Qt::CaseInsensitive ) == 0 )
 
  737       crs = QString( 
"EPSG:4326" );
 
  747     if ( !extent.
isEmpty() && height > 0 && width > 0 )
 
  749       const double mapRatio = extent.
width() / extent.
height();
 
  750       const double imageRatio = 
static_cast<double>( width ) / 
static_cast<double>( height );
 
  754         const double cellsize = ( extent.
width() / 
static_cast<double>( width ) ) * 0.5 + ( extent.
height() / 
static_cast<double>( height ) ) * 0.5;
 
  755         width = extent.
width() / cellsize;
 
  756         height = extent.
height() / cellsize;
 
  766   else if ( height <= 0 )
 
  772   return QSize( width, height );
 
  775 void QgsWmsRenderContext::removeUnwantedLayers()
 
  777   QList<QgsMapLayer *> 
layers;
 
  785       if ( !layerScaleVisibility( nickname ) )
 
  788       if ( mRestrictedLayers.contains( nickname ) )
 
  799         if ( ! wfsLayers.contains( 
layer->
id() ) )
 
  814   for ( 
const auto &
layer : mExternalLayers )
 
  816     if ( 
layer->
name().compare( name ) == 0 )
 
  823 void QgsWmsRenderContext::checkLayerReadPermissions()
 
  825 #ifdef HAVE_SERVER_PYTHON_PLUGINS 
  826   for ( 
const auto layer : mLayersToRender )
 
  828     if ( !accessControl()->layerReadPermission( 
layer ) )
 
  836 #ifdef HAVE_SERVER_PYTHON_PLUGINS 
A helper class that centralizes restrictions given by all the access control filter plugins.
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 hasAxisInverted() const
Returns whether axis is inverted (e.g., for WMS 1.3) for the CRS.
Layer tree group node serves as a container for layers and further groups.
QgsLayerTreeGroup * findGroup(const QString &name)
Find group node with specified name.
QList< QgsLayerTreeLayer * > findLayers() const
Find all layer nodes.
Layer tree node points to a map layer.
This class is a base class for nodes in a layer tree.
@ NodeGroup
Container of other groups and layers.
QList< QgsLayerTreeNode * > children()
Gets list of children of the node. Children are owned by the parent.
Base class for all map layer types.
bool isInScaleRange(double scale) const
Tests whether the layer should be visible at the specified scale.
QString id() const
Returns the layer's unique ID, which is used to access this layer from QgsProject.
QString shortName() const
Returns the short name of the layer used by QGIS Server to identify the layer.
bool hasScaleBasedVisibility() const
Returns whether scale based visibility is enabled for the layer.
A class to describe the version of a project.
Encapsulates a QGIS project, including sets of map layers and their styles, layouts,...
QString title() const
Returns the project's title.
QgsLayerTree * layerTreeRoot() const
Returns pointer to the root (invisible) node of the project's layer tree.
QMap< QString, QgsMapLayer * > mapLayers(const bool validOnly=false) const
Returns a map of all registered layers by layer ID.
A rectangle specified with double values.
double height() const SIP_HOLDGIL
Returns the height of the rectangle.
double width() const SIP_HOLDGIL
Returns the width of the rectangle.
bool isEmpty() const
Returns true if the rectangle is empty.
void invert()
Swap x/y coordinates in the rectangle.
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 QgsServerSettings * serverSettings()=0
Returns the server settings.
Provides a way to retrieve settings by prioritizing according to environment variables,...
int wmsMaxWidth() const
Returns the server-wide max width of a WMS GetMap request.
int wmsMaxHeight() const
Returns the server-wide max height of a WMS GetMap request.
Exception thrown in case of malformed request.
Exception thrown when data access violates access controls.
@ QGIS_InvalidParameterValue
WMS parameter received from the client.
Provides an interface to retrieve and manipulate WMS parameters received from the client.
int wmsPrecisionAsInt() const
Returns WMS_PRECISION parameter as an int or its default value if not defined.
QStringList allLayersNickname() const
Returns nickname of layers found in LAYER and LAYERS parameters.
QgsProjectVersion versionAsNumber() const
Returns VERSION parameter if defined or its default value.
QString scale() const
Returns SCALE parameter or an empty string if none is defined.
double scaleAsDouble() const
Returns SCALE as a double.
QgsRectangle bboxAsRectangle() const
Returns BBOX as a rectangle if defined and valid.
double dpiAsDouble() const
Returns DPI parameter as an int or its default value if not defined.
QList< QgsWmsParametersLayer > layersParameters() const
Returns parameters for each layer found in LAYER/LAYERS.
QString bbox() const
Returns BBOX if defined or an empty string.
int heightAsInt() const
Returns HEIGHT parameter as an int or its default value if not defined.
Format format() const
Returns format.
int widthAsInt() const
Returns WIDTH parameter as an int or its default value if not defined.
QString sldBody() const
Returns SLD_body if defined or an empty string.
int imageQualityAsInt() const
Returns IMAGE_QUALITY parameter as an integer.
int srcHeightAsInt() const
Returns SRCHEIGHT parameter as an int or its default value if not defined.
QString imageQuality() const
Returns IMAGE_QUALITY parameter or an empty string if not defined.
QString crs() const
Returns CRS or an empty string if none is defined.
bool tiledAsBool() const
Returns TILED parameter as a boolean.
QString dpi() const
Returns DPI parameter or an empty string if not defined.
QStringList queryLayersNickname() const
Returns nickname of layers found in QUERY_LAYERS parameter.
int srcWidthAsInt() const
Returns SRCWIDTH parameter as an int or its default value if not defined.
QSize mapSize(bool aspectRatio=true) const
Returns the size (in pixels) of the map to render, according to width and height WMS parameters as we...
bool isExternalLayer(const QString &name) const
Returns true if the layer is an external layer, false otherwise.
bool isValidGroup(const QString &name) const
Returns true if name is a group.
QStringList flattenedQueryLayers(const QStringList &layerNames) const
Returns a list of query layer names where group names are replaced by the names of their layer compon...
~QgsWmsRenderContext()
Destructor for QgsWmsRenderContext.
QgsWmsRenderContext(const QgsProject *project, QgsServerInterface *interface)
Constructor for QgsWmsRenderContext.
QList< QgsMapLayer * > layers() const
Returns a list of all layers read from the project.
void setParameters(const QgsWmsParameters ¶meters)
Sets WMS parameters.
QList< QgsMapLayer * > layersToRender() const
Returns a list of all layers to actually render according to the current configuration.
int mapWidth() const
Returns WIDTH or SRCWIDTH according to UseSrcWidthHeight flag.
QgsMapLayer * layer(const QString &nickname) const
Returns the layer corresponding to the nickname, or a nullptr if not found or if the layer do not nee...
int tileBuffer() const
Returns the tile buffer value to use for rendering according to the current configuration.
bool updateExtent() const
Returns true if the extent has to be updated before the rendering, false otherwise.
const QgsServerSettings & settings() const
Returns settings of the server.
void setFlag(Flag flag, bool on=true)
Sets or unsets a rendering flag according to the on value.
bool isValidWidthHeight() const
Returns true if width and height are valid according to the maximum values defined within the project...
QList< QgsMapLayer * > layersFromGroup(const QString &nickname) const
Returns the group's layers list corresponding to the nickname, or an empty list if not found.
QgsWmsParameters parameters() const
Returns WMS parameters.
void setScaleDenominator(double scaleDenominator)
Sets a custom scale denominator.
QString style(const QgsMapLayer &layer) const
Returns a style's name for a specific layer.
QMap< QString, QList< QgsMapLayer * > > layerGroups() const
Returns a map having layer group names as keys and a list of layers as values.
double mapTileBuffer(int mapWidth) const
Returns the tile buffer in geographical units for the given map width in pixels.
QString layerNickname(const QgsMapLayer &layer) const
Returns the nickname (short name, id or name) of the layer according to the current configuration.
double scaleDenominator() const
Returns the scale denominator to use for rendering according to the current configuration.
qreal dotsPerMm() const
Returns default dots per mm according to the current configuration.
bool testFlag(Flag flag) const
Returns the status of a rendering flag.
QDomElement sld(const QgsMapLayer &layer) const
Returns a SLD document for a specific layer.
bool isValidLayer(const QString &nickname) const
Returns true if the layer has to be rendered, false otherwise.
const QgsProject * project() const
Returns the project.
int precision() const
Returns the precision to use according to the current configuration.
int imageQuality() const
Returns the image quality to use for rendering according to the current configuration.
int mapHeight() const
Returns HEIGHT or SRCHEIGHT according to UseSrcWidthHeight flag.
bool renderMapTiles() const
Returns true if WMS requests should use the QgsMapSettings::RenderMapTile flag, so that no visible ar...
Flag
Available rendering options.
@ AddAllLayers
For GetPrint: add layers from LAYER(S) parameter.
SERVER_EXPORT int wmsTileBuffer(const QgsProject &project)
Returns the tile buffer in pixels for WMS images defined in a QGIS project.
SERVER_EXPORT QString wmsRootName(const QgsProject &project)
Returns the WMS root layer name defined in a QGIS project.
SERVER_EXPORT int wmsFeatureInfoPrecision(const QgsProject &project)
Returns the geometry precision for GetFeatureInfo request.
SERVER_EXPORT bool wmsUseLayerIds(const QgsProject &project)
Returns if layer ids are used as name in WMS.
SERVER_EXPORT QStringList wfsLayerIds(const QgsProject &project)
Returns the Layer ids list defined in a QGIS project as published in WFS.
SERVER_EXPORT bool wmsRenderMapTiles(const QgsProject &project)
Returns true if WMS requests should use the QgsMapSettings::RenderMapTile flag, so that no visible ar...
SERVER_EXPORT QStringList wmsRestrictedLayers(const QgsProject &project)
Returns the restricted layer name list.
SERVER_EXPORT int wmsImageQuality(const QgsProject &project)
Returns the quality for WMS images defined in a QGIS project.
SERVER_EXPORT int wmsMaxWidth(const QgsProject &project)
Returns the maximum width for WMS images defined in a QGIS project.
SERVER_EXPORT int wmsMaxHeight(const QgsProject &project)
Returns the maximum height for WMS images defined in a QGIS project.
Median cut implementation.
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
const QgsCoordinateReferenceSystem & outputCrs
const QgsCoordinateReferenceSystem & crs