QGIS API Documentation 3.28.0-Firenze (ed3ad0430f)
qgswmsrendercontext.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgswmsrendercontext.cpp
3 ---------------------
4 begin : March 22, 2019
5 copyright : (C) 2019 by Paul Blottiere
7 ***************************************************************************/
8
9/***************************************************************************
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 ***************************************************************************/
17
18#include "qgslayertree.h"
19
20#include "qgsrasterlayer.h"
21#include "qgswmsrendercontext.h"
24
25using namespace QgsWms;
26
27const double OGC_PX_M = 0.00028; // OGC reference pixel size in meter
28QgsWmsRenderContext::QgsWmsRenderContext( const QgsProject *project, QgsServerInterface *interface )
29 : mProject( project )
30 , mInterface( interface )
31 , mFlags()
32{
33}
34
36{
37 qDeleteAll( mExternalLayers );
38 mExternalLayers.clear();
39}
40
42{
43 mParameters = parameters;
44
45 initRestrictedLayers();
46 initNicknameLayers();
47
48 searchLayersToRender();
49 removeUnwantedLayers();
50 checkLayerReadPermissions();
51
52 std::reverse( mLayersToRender.begin(), mLayersToRender.end() );
53}
54
55void QgsWmsRenderContext::setFlag( const Flag flag, const bool on )
56{
57 if ( on )
58 {
59 mFlags |= flag;
60 }
61 else
62 {
63 mFlags &= ~flag;
64 }
65}
66
68{
69 return mFlags.testFlag( flag );
70}
71
73{
74 return mParameters;
75}
76
78{
79 return *mInterface->serverSettings();
80}
81
83{
84 return mProject;
85}
86
87QDomElement QgsWmsRenderContext::sld( const QgsMapLayer &layer ) const
88{
89 QDomElement sld;
90
91 const QString nickname = layerNickname( layer );
92 if ( mSlds.contains( nickname ) )
93 {
94 sld = mSlds[ nickname ];
95 }
96
97 return sld;
98}
99
100QString QgsWmsRenderContext::style( const QgsMapLayer &layer ) const
101{
102 QString style;
103
104 const QString nickname = layerNickname( layer );
105 if ( mStyles.contains( nickname ) )
106 {
107 style = mStyles[ nickname ];
108 }
109
110 return style;
111}
112
114{
116
117 const QList<QgsWmsParametersLayer> cLayerParams { mParameters.layersParameters() };
118
119 for ( const auto &params : std::as_const( cLayerParams ) )
120 {
121 if ( params.mNickname == layerNickname( layer ) )
122 {
123 parameters = params;
124 break;
125 }
126 }
127
128 return parameters;
129}
130
132{
134
135 if ( !mParameters.imageQuality().isEmpty() )
136 {
137 imageQuality = mParameters.imageQualityAsInt();
138 }
139
140 return imageQuality;
141}
142
144{
145 int tileBuffer = 0;
146
147 if ( mParameters.tiledAsBool() )
148 {
150 }
151
152 return tileBuffer;
153}
154
156{
158}
159
161{
163
164 if ( mParameters.wmsPrecisionAsInt() > -1 )
165 {
166 precision = mParameters.wmsPrecisionAsInt();
167 }
168
169 return precision;
170}
171
173{
174 // Apply DPI parameter if present. This is an extension of QGIS Server
175 // compared to WMS 1.3.
176 // Because of backwards compatibility, this parameter is optional
177 qreal dpm = 1 / OGC_PX_M;
178
179 if ( !mParameters.dpi().isEmpty() )
180 {
181 dpm = mParameters.dpiAsDouble() / 0.0254;
182 }
183
184 return dpm / 1000.0;
185}
186
187QStringList QgsWmsRenderContext::flattenedQueryLayers( const QStringList &layerNames ) const
188{
189 QStringList result;
190 std::function <QStringList( const QString &name )> findLeaves = [ & ]( const QString & name ) -> QStringList
191 {
192 QStringList _result;
193 if ( mLayerGroups.contains( name ) )
194 {
195 const auto &layers { mLayerGroups[ name ] };
196 for ( const auto &l : layers )
197 {
198 const auto nick { layerNickname( *l ) };
199 // This handles the case for root (fake) group
200 if ( mLayerGroups.contains( nick ) )
201 {
202 _result.append( name );
203 }
204 else
205 {
206 _result.append( findLeaves( nick ) );
207 }
208 }
209 }
210 else
211 {
212 _result.append( name );
213 }
214 return _result;
215 };
216
217 for ( const auto &name : std::as_const( layerNames ) )
218 {
219 result.append( findLeaves( name ) );
220 }
221 return result;
222}
223
224QList<QgsMapLayer *> QgsWmsRenderContext::layersToRender() const
225{
226 return mLayersToRender;
227}
228
229QList<QgsMapLayer *> QgsWmsRenderContext::layers() const
230{
231 return mNicknameLayers.values();
232}
233
235{
236 double denominator = -1;
237
238 if ( mScaleDenominator >= 0 )
239 {
240 denominator = mScaleDenominator;
241 }
242 else if ( mFlags & UseScaleDenominator && ! mParameters.scale().isEmpty() )
243 {
244 denominator = mParameters.scaleAsDouble();
245 }
246
247 return denominator;
248}
249
250void QgsWmsRenderContext::setScaleDenominator( double scaleDenominator )
251{
252 mScaleDenominator = scaleDenominator;
253 removeUnwantedLayers();
254}
255
257{
258 bool update = false;
259
260 if ( mFlags & UpdateExtent && ! mParameters.bbox().isEmpty() )
261 {
262 update = true;
263 }
264
265 return update;
266}
267
269{
270 QString name = layer.shortName();
271 // For external layers we cannot use the layer id because it's not known to the client, use layer name instead.
272 if ( QgsServerProjectUtils::wmsUseLayerIds( *mProject ) &&
273 std::find_if( mExternalLayers.cbegin(), mExternalLayers.cend(),
274 [ &layer ]( const QgsMapLayer * l )
275{
276 return l->id() == layer.id();
277 } ) == mExternalLayers.cend() )
278 {
279 name = layer.id();
280 }
281 else if ( name.isEmpty() )
282 {
283 name = layer.name();
284 }
285
286 return name;
287}
288
289QgsMapLayer *QgsWmsRenderContext::layer( const QString &nickname ) const
290{
291 QgsMapLayer *mlayer = nullptr;
292
293 for ( auto layer : mLayersToRender )
294 {
295 if ( layerNickname( *layer ).compare( nickname ) == 0 )
296 {
297 mlayer = layer;
298 break;
299 }
300 }
301
302 return mlayer;
303}
304
305bool QgsWmsRenderContext::isValidLayer( const QString &nickname ) const
306{
307 return layer( nickname ) != nullptr;
308}
309
310QList<QgsMapLayer *> QgsWmsRenderContext::layersFromGroup( const QString &nickname ) const
311{
312 return mLayerGroups.value( nickname );
313}
314
315bool QgsWmsRenderContext::isValidGroup( const QString &name ) const
316{
317 return mLayerGroups.contains( name );
318}
319
320void QgsWmsRenderContext::initNicknameLayers()
321{
322 for ( QgsMapLayer *ml : mProject->mapLayers() )
323 {
324 mNicknameLayers.insert( layerNickname( *ml ), ml );
325 }
326
327 // init groups
328 const QString rootName { QgsServerProjectUtils::wmsRootName( *mProject ) };
329 const QgsLayerTreeGroup *root = mProject->layerTreeRoot();
330
331 initLayerGroupsRecursive( root, rootName.isEmpty() ? mProject->title() : rootName );
332}
333
334void QgsWmsRenderContext::initLayerGroupsRecursive( const QgsLayerTreeGroup *group, const QString &groupName )
335{
336 if ( !groupName.isEmpty() )
337 {
338 mLayerGroups[groupName] = QList<QgsMapLayer *>();
339 const auto projectLayerTreeRoot { mProject->layerTreeRoot() };
340 const auto treeGroupLayers { group->findLayers() };
341 // Fast track if there is no custom layer order,
342 // otherwise reorder layers.
343 if ( ! projectLayerTreeRoot->hasCustomLayerOrder() )
344 {
345 for ( const auto &tl : treeGroupLayers )
346 {
347 mLayerGroups[groupName].push_back( tl->layer() );
348 }
349 }
350 else
351 {
352 const auto projectLayerOrder { projectLayerTreeRoot->layerOrder() };
353 // Flat list containing the layers from the tree nodes
354 QList<QgsMapLayer *> groupLayersList;
355 for ( const auto &tl : treeGroupLayers )
356 {
357 groupLayersList << tl->layer();
358 }
359 for ( const auto &l : projectLayerOrder )
360 {
361 if ( groupLayersList.contains( l ) )
362 {
363 mLayerGroups[groupName].push_back( l );
364 }
365 }
366 }
367 }
368
369 for ( const QgsLayerTreeNode *child : group->children() )
370 {
371 if ( child->nodeType() == QgsLayerTreeNode::NodeGroup )
372 {
373 QString name = child->customProperty( QStringLiteral( "wmsShortName" ) ).toString();
374
375 if ( name.isEmpty() )
376 name = child->name();
377
378 initLayerGroupsRecursive( static_cast<const QgsLayerTreeGroup *>( child ), name );
379
380 }
381 }
382}
383
384void QgsWmsRenderContext::initRestrictedLayers()
385{
386 mRestrictedLayers.clear();
387
388 // get name of restricted layers/groups in project
389 const QStringList restricted = QgsServerProjectUtils::wmsRestrictedLayers( *mProject );
390
391 // extract restricted layers from excluded groups
392 QStringList restrictedLayersNames;
393 QgsLayerTreeGroup *root = mProject->layerTreeRoot();
394
395 for ( const QString &l : std::as_const( restricted ) )
396 {
397 const QgsLayerTreeGroup *group = root->findGroup( l );
398 if ( group )
399 {
400 const QList<QgsLayerTreeLayer *> groupLayers = group->findLayers();
401 for ( QgsLayerTreeLayer *treeLayer : groupLayers )
402 {
403 restrictedLayersNames.append( treeLayer->name() );
404 }
405 }
406 else
407 {
408 restrictedLayersNames.append( l );
409 }
410 }
411
412 // build output with names, ids or short name according to the configuration
413 const QList<QgsLayerTreeLayer *> layers = root->findLayers();
415 {
416 if ( restrictedLayersNames.contains( layer->name() ) )
417 {
418 mRestrictedLayers.append( layerNickname( *layer->layer() ) );
419 }
420 }
421}
422
423void QgsWmsRenderContext::searchLayersToRender()
424{
425 mLayersToRender.clear();
426 mStyles.clear();
427 mSlds.clear();
428
429 if ( ! mParameters.sldBody().isEmpty() )
430 {
431 searchLayersToRenderSld();
432 }
433 else
434 {
435 searchLayersToRenderStyle();
436 }
437
438 if ( mFlags & AddQueryLayers )
439 {
440 const QStringList queryLayerNames = flattenedQueryLayers( mParameters.queryLayersNickname() );
441 for ( const QString &layerName : queryLayerNames )
442 {
443 const QList<QgsMapLayer *> layers = mNicknameLayers.values( layerName );
444 for ( QgsMapLayer *lyr : layers )
445 if ( !mLayersToRender.contains( lyr ) )
446 {
447 mLayersToRender.append( lyr );
448 }
449 }
450 }
451
452 if ( mFlags & AddAllLayers )
453 {
454 const QStringList queryLayerNames = flattenedQueryLayers( mParameters.allLayersNickname() );
455 for ( const QString &layerName : queryLayerNames )
456 {
457 const QList<QgsMapLayer *> layers = mNicknameLayers.values( layerName );
458 for ( QgsMapLayer *lyr : layers )
459 if ( !mLayersToRender.contains( lyr ) )
460 {
461 mLayersToRender.append( lyr );
462 }
463 }
464 }
465}
466
467void QgsWmsRenderContext::searchLayersToRenderSld()
468{
469 const QString sld = mParameters.sldBody();
470
471 if ( sld.isEmpty() )
472 {
473 return;
474 }
475
476 QDomDocument doc;
477 ( void )doc.setContent( sld, true );
478 QDomElement docEl = doc.documentElement();
479
480 QDomElement root = doc.firstChildElement( "StyledLayerDescriptor" );
481 QDomElement namedElem = root.firstChildElement( "NamedLayer" );
482
483 if ( docEl.isNull() )
484 {
485 return;
486 }
487
488 QDomNodeList named = docEl.elementsByTagName( "NamedLayer" );
489 for ( int i = 0; i < named.size(); ++i )
490 {
491 QDomNodeList names = named.item( i ).toElement().elementsByTagName( "Name" );
492 if ( !names.isEmpty() )
493 {
494 QString lname = names.item( 0 ).toElement().text();
495 if ( mNicknameLayers.contains( lname ) )
496 {
497 mSlds[lname] = namedElem;
498 mLayersToRender.append( mNicknameLayers.values( lname ) );
499 }
500 else if ( mLayerGroups.contains( lname ) )
501 {
502 for ( QgsMapLayer *layer : mLayerGroups[lname] )
503 {
504 const QString name = layerNickname( *layer );
505 mSlds[name] = namedElem;
506 mLayersToRender.insert( 0, layer );
507 }
508 }
509 else
510 {
512 param.mValue = lname;
514 param );
515 }
516 }
517 }
518}
519
520void QgsWmsRenderContext::searchLayersToRenderStyle()
521{
522 for ( const QgsWmsParametersLayer &param : mParameters.layersParameters() )
523 {
524 const QString nickname = param.mNickname;
525 const QString style = param.mStyle;
526
527 if ( ! param.mExternalUri.isEmpty() && ( mFlags & AddExternalLayers ) )
528 {
529
530 std::unique_ptr<QgsMapLayer> layer = std::make_unique< QgsRasterLayer >( param.mExternalUri, param.mNickname, QStringLiteral( "wms" ) );
531
532 if ( layer->isValid() )
533 {
534 // to delete later
535 mExternalLayers.append( layer.release() );
536 mLayersToRender.append( mExternalLayers.last() );
537 }
538 }
539 else if ( mNicknameLayers.contains( nickname ) )
540 {
541 if ( !style.isEmpty() )
542 {
543 mStyles[nickname] = style;
544 }
545
546 mLayersToRender.append( mNicknameLayers.values( nickname ) );
547 }
548 else if ( mLayerGroups.contains( nickname ) )
549 {
550 // Reverse order of layers from a group
551 QList<QString> layersFromGroup;
552 for ( QgsMapLayer *layer : mLayerGroups[nickname] )
553 {
554 const QString nickname = layerNickname( *layer );
555 if ( !style.isEmpty() )
556 {
557 mStyles[ nickname ] = style;
558 }
559 layersFromGroup.push_front( nickname );
560 }
561
562 for ( const auto &name : layersFromGroup )
563 {
564 mLayersToRender.append( mNicknameLayers.values( name ) );
565 }
566 }
567 else
568 {
570 param.mValue = nickname;
572 param );
573 }
574 }
575}
576
577bool QgsWmsRenderContext::layerScaleVisibility( const QString &name ) const
578{
579 bool visible = false;
580
581 if ( ! mNicknameLayers.contains( name ) )
582 {
583 return visible;
584 }
585
586 const QList<QgsMapLayer *>layers = mNicknameLayers.values( name );
587 for ( QgsMapLayer *layer : layers )
588 {
589 bool scaleBasedVisibility = layer->hasScaleBasedVisibility();
590 bool useScaleConstraint = ( scaleDenominator() > 0 && scaleBasedVisibility );
591
592 if ( !useScaleConstraint || layer->isInScaleRange( scaleDenominator() ) )
593 {
594 visible = true;
595 }
596 }
597
598 return visible;
599}
600
601QMap<QString, QList<QgsMapLayer *> > QgsWmsRenderContext::layerGroups() const
602{
603 return mLayerGroups;
604}
605
607{
608 int width = mParameters.widthAsInt();
609
610 // May use SRCWIDTH to define image map size
611 if ( ( mFlags & UseSrcWidthHeight ) && mParameters.srcWidthAsInt() > 0 )
612 {
613 width = mParameters.srcWidthAsInt();
614 }
615
616 return width;
617}
618
620{
621 int height = mParameters.heightAsInt();
622
623 // May use SRCHEIGHT to define image map size
624 if ( ( mFlags & UseSrcWidthHeight ) && mParameters.srcHeightAsInt() > 0 )
625 {
626 height = mParameters.srcHeightAsInt();
627 }
628
629 return height;
630}
631
633{
635}
636
637bool QgsWmsRenderContext::isValidWidthHeight( int width, int height ) const
638{
639 //test if maxWidth / maxHeight are set in the project or as an env variable
640 //and WIDTH / HEIGHT parameter is in the range allowed range
641 //WIDTH
642 const int wmsMaxWidthProj = QgsServerProjectUtils::wmsMaxWidth( *mProject );
643 const int wmsMaxWidthEnv = settings().wmsMaxWidth();
644 int wmsMaxWidth;
645 if ( wmsMaxWidthEnv != -1 && wmsMaxWidthProj != -1 )
646 {
647 // both are set, so we take the more conservative one
648 wmsMaxWidth = std::min( wmsMaxWidthProj, wmsMaxWidthEnv );
649 }
650 else
651 {
652 // none or one are set, so we take the bigger one which is the one set or -1
653 wmsMaxWidth = std::max( wmsMaxWidthProj, wmsMaxWidthEnv );
654 }
655
656 if ( wmsMaxWidth != -1 && width > wmsMaxWidth )
657 {
658 return false;
659 }
660
661 //HEIGHT
662 const int wmsMaxHeightProj = QgsServerProjectUtils::wmsMaxHeight( *mProject );
663 const int wmsMaxHeightEnv = settings().wmsMaxHeight();
664 int wmsMaxHeight;
665 if ( wmsMaxHeightEnv != -1 && wmsMaxHeightProj != -1 )
666 {
667 // both are set, so we take the more conservative one
668 wmsMaxHeight = std::min( wmsMaxHeightProj, wmsMaxHeightEnv );
669 }
670 else
671 {
672 // none or one are set, so we take the bigger one which is the one set or -1
673 wmsMaxHeight = std::max( wmsMaxHeightProj, wmsMaxHeightEnv );
674 }
675
676 if ( wmsMaxHeight != -1 && height > wmsMaxHeight )
677 {
678 return false;
679 }
680
681 // Sanity check from internal QImage checks (see qimage.cpp)
682 // this is to report a meaningful error message in case of
683 // image creation failure and to differentiate it from out
684 // of memory conditions.
685
686 // depth for now it cannot be anything other than 32, but I don't like
687 // to hardcode it: I hope we will support other depths in the future.
688 uint depth = 32;
689 switch ( mParameters.format() )
690 {
691 case QgsWmsParameters::Format::JPG:
692 case QgsWmsParameters::Format::PNG:
693 default:
694 depth = 32;
695 }
696
697 const int bytes_per_line = ( ( width * depth + 31 ) >> 5 ) << 2; // bytes per scanline (must be multiple of 4)
698
699 if ( std::numeric_limits<int>::max() / depth < static_cast<uint>( width )
700 || bytes_per_line <= 0
701 || height <= 0
702 || std::numeric_limits<int>::max() / static_cast<uint>( bytes_per_line ) < static_cast<uint>( height )
703 || std::numeric_limits<int>::max() / sizeof( uchar * ) < static_cast<uint>( height ) )
704 {
705 return false;
706 }
707
708 return true;
709}
710
711double QgsWmsRenderContext::mapTileBuffer( const int mapWidth ) const
712{
713 double buffer;
714 if ( mFlags & UseTileBuffer )
715 {
716 const QgsRectangle extent = mParameters.bboxAsRectangle();
717 if ( !mParameters.bbox().isEmpty() && extent.isEmpty() )
718 {
720 mParameters[QgsWmsParameter::BBOX] );
721 }
722 buffer = tileBuffer() * ( extent.width() / mapWidth );
723 }
724 else
725 {
726 buffer = 0;
727 }
728 return buffer;
729}
730
731QSize QgsWmsRenderContext::mapSize( const bool aspectRatio ) const
732{
733 int width = mapWidth();
734 int height = mapHeight();
735
736 // Adapt width / height if the aspect ratio does not correspond with the BBOX.
737 // Required by WMS spec. 1.3.
738 if ( aspectRatio
739 && mParameters.versionAsNumber() >= QgsProjectVersion( 1, 3, 0 ) )
740 {
741 QgsRectangle extent = mParameters.bboxAsRectangle();
742 if ( !mParameters.bbox().isEmpty() && extent.isEmpty() )
743 {
745 mParameters[QgsWmsParameter::BBOX] );
746 }
747
748 QString crs = mParameters.crs();
749 if ( crs.compare( "CRS:84", Qt::CaseInsensitive ) == 0 )
750 {
751 crs = QString( "EPSG:4326" );
752 extent.invert();
753 }
754
757 {
758 extent.invert();
759 }
760
761 if ( !extent.isEmpty() && height > 0 && width > 0 )
762 {
763 const double mapRatio = extent.width() / extent.height();
764 const double imageRatio = static_cast<double>( width ) / static_cast<double>( height );
765 if ( !qgsDoubleNear( mapRatio, imageRatio, 0.0001 ) )
766 {
767 // inspired by MapServer, mapdraw.c L115
768 const double cellsize = ( extent.width() / static_cast<double>( width ) ) * 0.5 + ( extent.height() / static_cast<double>( height ) ) * 0.5;
769 width = extent.width() / cellsize;
770 height = extent.height() / cellsize;
771 }
772 }
773 }
774
775 if ( width <= 0 )
776 {
778 mParameters[QgsWmsParameter::WIDTH] );
779 }
780 else if ( height <= 0 )
781 {
783 mParameters[QgsWmsParameter::HEIGHT] );
784 }
785
786 return QSize( width, height );
787}
788
789void QgsWmsRenderContext::removeUnwantedLayers()
790{
791 QList<QgsMapLayer *> layers;
792
793 for ( QgsMapLayer *layer : mLayersToRender )
794 {
795 const QString nickname = layerNickname( *layer );
796
797 if ( ! isExternalLayer( nickname ) )
798 {
799 if ( !layerScaleVisibility( nickname ) )
800 continue;
801
802 if ( mRestrictedLayers.contains( nickname ) )
803 continue;
804
805 if ( mFlags & UseWfsLayersOnly )
806 {
808 {
809 continue;
810 }
811
812 const QStringList wfsLayers = QgsServerProjectUtils::wfsLayerIds( *mProject );
813 if ( ! wfsLayers.contains( layer->id() ) )
814 {
815 continue;
816 }
817 }
818 }
819
820 layers.append( layer );
821 }
822
823 mLayersToRender = layers;
824}
825
826bool QgsWmsRenderContext::isExternalLayer( const QString &name ) const
827{
828 for ( const auto &layer : mExternalLayers )
829 {
830 if ( layerNickname( *layer ).compare( name ) == 0 )
831 return true;
832 }
833
834 return false;
835}
836
837void QgsWmsRenderContext::checkLayerReadPermissions()
838{
839#ifdef HAVE_SERVER_PYTHON_PLUGINS
840 for ( const auto layer : mLayersToRender )
841 {
842 if ( !accessControl()->layerReadPermission( layer ) )
843 {
844 throw QgsSecurityException( QStringLiteral( "You are not allowed to access to the layer: %1" ).arg( layer->name() ) );
845 }
846 }
847#endif
848}
849
850#ifdef HAVE_SERVER_PYTHON_PLUGINS
851QgsAccessControl *QgsWmsRenderContext::accessControl() const
852{
853 return mInterface->accessControls();
854}
855#endif
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.
Definition: qgsmaplayer.h:73
QString name
Definition: qgsmaplayer.h:76
bool isInScaleRange(double scale) const
Tests whether the layer should be visible at the specified scale.
QgsMapLayerType type
Definition: qgsmaplayer.h:80
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.
bool isValid
Definition: qgsmaplayer.h:81
A class to describe the version of a project.
Encapsulates a QGIS project, including sets of map layers and their styles, layouts,...
Definition: qgsproject.h:104
QString title() const
Returns the project's title.
Definition: qgsproject.cpp:500
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.
Definition: qgsrectangle.h:42
double height() const SIP_HOLDGIL
Returns the height of the rectangle.
Definition: qgsrectangle.h:230
double width() const SIP_HOLDGIL
Returns the width of the rectangle.
Definition: qgsrectangle.h:223
bool isEmpty() const
Returns true if the rectangle is empty.
Definition: qgsrectangle.h:469
void invert()
Swap x/y coordinates in the rectangle.
Definition: qgsrectangle.h:575
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.
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.
QList< QgsMapLayer * > layers() const
Returns a list of all layers read from the project.
void setParameters(const QgsWmsParameters &parameters)
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.
@ VectorLayer
Vector layer.
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)
Definition: qgis.h:2527
const QgsCoordinateReferenceSystem & outputCrs
const QgsCoordinateReferenceSystem & crs
const double OGC_PX_M