31#include <QRegularExpression>
34using namespace Qt::StringLiterals;
51 static const QSet<QString> sFilter { u
"REQUEST"_s, u
"VERSION"_s, u
"SERVICE"_s, u
"LAYERS"_s, u
"STYLES"_s, u
"SLD_VERSION"_s, u
"_DC"_s };
56 const QList<QPair<QString, QString>> queryItems = q.queryItems();
57 for (
const QPair<QString, QString> ¶m : queryItems )
59 if ( sFilter.contains( param.first.toUpper() ) )
60 q.removeAllQueryItems( param.first );
72 if ( format.compare(
"png"_L1, Qt::CaseInsensitive ) == 0 || format.compare(
"image/png"_L1, Qt::CaseInsensitive ) == 0 )
76 else if ( format.compare(
"jpg "_L1, Qt::CaseInsensitive ) == 0 || format.compare(
"image/jpeg"_L1, Qt::CaseInsensitive ) == 0 )
80 else if ( format.compare(
"webp"_L1, Qt::CaseInsensitive ) == 0 || format.compare(
"image/webp"_L1, Qt::CaseInsensitive ) == 0 )
87 const thread_local QRegularExpression modeExpr = QRegularExpression( u
"image/png\\s*;\\s*mode=([^;]+)"_s, QRegularExpression::CaseInsensitiveOption );
89 const QRegularExpressionMatch match = modeExpr.match( format );
90 const QString mode = match.captured( 1 );
91 if ( mode.compare(
"16bit"_L1, Qt::CaseInsensitive ) == 0 )
93 if ( mode.compare(
"8bit"_L1, Qt::CaseInsensitive ) == 0 )
95 if ( mode.compare(
"1bit"_L1, Qt::CaseInsensitive ) == 0 )
109 switch ( outputFormat )
113 contentType = u
"image/png"_s;
114 saveFormat = u
"PNG"_s;
118 QVector<QRgb> colorTable;
123 const QImage img256 = img.convertToFormat( QImage::Format_ARGB32 );
125 result = img256.convertToFormat( QImage::Format_Indexed8, colorTable, Qt::ColorOnly | Qt::ThresholdDither | Qt::ThresholdAlphaDither | Qt::NoOpaqueDetection );
127 contentType = u
"image/png"_s;
128 saveFormat = u
"PNG"_s;
131 result = img.convertToFormat( QImage::Format_ARGB4444_Premultiplied );
132 contentType = u
"image/png"_s;
133 saveFormat = u
"PNG"_s;
136 result = img.convertToFormat( QImage::Format_Mono, Qt::MonoOnly | Qt::ThresholdDither | Qt::ThresholdAlphaDither | Qt::NoOpaqueDetection );
137 contentType = u
"image/png"_s;
138 saveFormat = u
"PNG"_s;
142 contentType = u
"image/jpeg"_s;
143 saveFormat = u
"JPEG"_s;
147 contentType = u
"image/webp"_s;
148 saveFormat = u
"WEBP"_s;
152 saveFormat = u
"Unknown"_s;
157 result.setDotsPerMeterX( img.dotsPerMeterX() );
158 result.setDotsPerMeterY( img.dotsPerMeterY() );
162 response.
setHeader(
"Content-Type", contentType );
163 if ( saveFormat ==
"JPEG"_L1 || saveFormat ==
"WEBP"_L1 )
165 result.save( response.
io(), qPrintable( saveFormat ), imageQuality );
169 result.save( response.
io(), qPrintable( saveFormat ) );
175 parameter.
mValue = formatStr;
189 QHash<const QgsMapLayer *, QStringList> &acceptableLayersAndRequestNames,
191 const QStringList &requestedLayerNames,
193 QStringList requestedParentNames = QStringList(),
194 bool groupIsAnOpaqueChild =
false
199 if ( groupName.isEmpty() )
200 groupName = group->
name();
203 bool groupIsRequested = requestedLayerNames.contains( groupName );
206 if ( groupIsRequested && !groupIsAnOpaqueChild )
207 requestedParentNames << groupName;
235 else if ( name.isEmpty() )
237 name = layer->
name();
240 QStringList requestedNames = requestedParentNames;
242 if ( requestedLayerNames.contains( name ) && !isOpaqueChild )
244 requestedNames << name;
247 if ( !requestedNames.isEmpty() || requestedLayerNames.isEmpty() || projectIsRequested )
248 acceptableLayersAndRequestNames.insert( layer, requestedNames );
@ Opaque
Group can be requested, children cannot (appears like a single layer).
Layer tree group node serves as a container for layers and further groups.
QString name() const override
Returns the group's name.
QgsMapLayerServerProperties * serverProperties()
Returns QGIS Server Properties for the layer tree group.
Qgis::WmsGroupRequestMode wmsGroupRequestMode() const
Returns the request mode of the group.
Layer tree node points to a map layer.
Base class for nodes in a layer tree.
QList< QgsLayerTreeNode * > children()
Gets list of children of the node. Children are owned by the parent.
static bool isLayer(const QgsLayerTreeNode *node)
Check whether the node is a valid layer node.
static bool isGroup(QgsLayerTreeNode *node)
Check whether the node is a valid group node.
QString shortName() const
Returns the short name of the layer used by QGIS Server to identify the layer.
Base class for all map layer types.
QgsMapLayerServerProperties * serverProperties()
Returns QGIS Server Properties for the map layer.
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::MessageLevel::Warning, bool notifyUser=true, const char *file=__builtin_FILE(), const char *function=__builtin_FUNCTION(), int line=__builtin_LINE(), Qgis::StringFormat format=Qgis::StringFormat::PlainText)
Adds a message to the log instance (and creates it if necessary).
Encapsulates a QGIS project, including sets of map layers and their styles, layouts,...
static QgsProject * instance()
Returns the QgsProject singleton instance.
QgsLayerTree * layerTreeRoot() const
Returns pointer to the root (invisible) node of the project's layer tree.
static QString wmsRootName(const QgsProject &project)
Returns the WMS root layer name defined in a QGIS project.
static bool wmsUseLayerIds(const QgsProject &project)
Returns if layer ids are used as name in WMS.
static QString wmsServiceUrl(const QgsProject &project, const QgsServerRequest &request=QgsServerRequest(), const QgsServerSettings &settings=QgsServerSettings())
Returns the WMS service url.
Defines requests passed to QgsService classes.
QUrl originalUrl() const
Returns the request url as seen by the web server, by default this is equal to the url seen by QGIS s...
Defines the response interface passed to QgsService.
virtual void setHeader(const QString &key, const QString &value)=0
Set a single header value replacing any existing value(s) for the same key.
virtual QIODevice * io()=0
Returns the underlying QIODevice.
Provides a way to retrieve settings by prioritizing according to environment variables,...
Exception thrown in case of malformed request.
WMS parameter received from the client.
Median cut implementation.
void writeImage(QgsServerResponse &response, QImage &img, const QString &formatStr, int imageQuality)
Write image response.
void collectAcceptableLayersAndRequestNames(QHash< const QgsMapLayer *, QStringList > &acceptableLayersAndRequestNames, const QgsProject &project, const QStringList &requestedLayerNames)
Collects the acceptableLayersAndRequestNames, a hash of all the layers that can be rendered and for e...
void medianCut(QVector< QRgb > &colorTable, int nColors, const QImage &inputImage)
Median cut implementation used when reducing RGB colors to palletized colors.
QString implementationVersion()
Returns the highest version supported by this implementation.
void _collectAcceptableLayersAndRequestNames(QHash< const QgsMapLayer *, QStringList > &acceptableLayersAndRequestNames, const QgsProject &project, const QStringList &requestedLayerNames, const QgsLayerTreeGroup *group, QStringList requestedParentNames=QStringList(), bool groupIsAnOpaqueChild=false)
Collects the acceptableLayersAndRequestNames recursively, a hash of all the layers that can be render...
ImageOutputFormat
Supported image output format.
@ Unknown
Unknown/invalid format.
ImageOutputFormat parseImageFormat(const QString &format)
Parse image format parameter.
QUrl serviceUrl(const QgsServerRequest &request, const QgsProject *project, const QgsServerSettings &settings)
Returns WMS service URL.