QGIS API Documentation 3.37.0-Master (fdefdf9c27f)
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 {
503 {
505 param.mValue = lname;
507 param );
508 }
509 for ( QgsMapLayer *layer : mLayerGroups[lname] )
510 {
511 const QString name = layerNickname( *layer );
512 mSlds[name] = namedElem;
513 mLayersToRender.insert( 0, layer );
514 }
515 }
516 else
517 {
519 param.mValue = lname;
521 param );
522 }
523 }
524 }
525}
526
527void QgsWmsRenderContext::searchLayersToRenderStyle()
528{
529 for ( const QgsWmsParametersLayer &param : mParameters.layersParameters() )
530 {
531 const QString nickname = param.mNickname;
532 const QString style = param.mStyle;
533
534 if ( ! param.mExternalUri.isEmpty() && ( mFlags & AddExternalLayers ) )
535 {
536
537 std::unique_ptr<QgsMapLayer> layer = std::make_unique< QgsRasterLayer >( param.mExternalUri, param.mNickname, QStringLiteral( "wms" ) );
538
539 if ( layer->isValid() )
540 {
541 // to delete later
542 mExternalLayers.append( layer.release() );
543 mLayersToRender.append( mExternalLayers.last() );
544 }
545 }
546 else if ( mNicknameLayers.contains( nickname ) )
547 {
548 if ( !style.isEmpty() )
549 {
550 mStyles[nickname] = style;
551 }
552
553 mLayersToRender.append( mNicknameLayers.values( nickname ) );
554 }
555 else if ( mLayerGroups.contains( nickname ) )
556 {
558 {
560 param.mValue = nickname;
562 param );
563 }
564 // Reverse order of layers from a group
565 QList<QString> layersFromGroup;
566 for ( QgsMapLayer *layer : mLayerGroups[nickname] )
567 {
568 const QString nickname = layerNickname( *layer );
569 if ( !style.isEmpty() )
570 {
571 mStyles[ nickname ] = style;
572 }
573 layersFromGroup.push_front( nickname );
574 }
575
576 for ( const auto &name : layersFromGroup )
577 {
578 mLayersToRender.append( mNicknameLayers.values( name ) );
579 }
580 }
581 else
582 {
584 param.mValue = nickname;
586 param );
587 }
588 }
589}
590
591bool QgsWmsRenderContext::layerScaleVisibility( const QString &name ) const
592{
593 bool visible = false;
594
595 if ( ! mNicknameLayers.contains( name ) )
596 {
597 return visible;
598 }
599
600 const QList<QgsMapLayer *>layers = mNicknameLayers.values( name );
601 for ( QgsMapLayer *layer : layers )
602 {
603 bool scaleBasedVisibility = layer->hasScaleBasedVisibility();
604 bool useScaleConstraint = ( scaleDenominator() > 0 && scaleBasedVisibility );
605
606 if ( !useScaleConstraint || layer->isInScaleRange( scaleDenominator() ) )
607 {
608 visible = true;
609 }
610 }
611
612 return visible;
613}
614
615QMap<QString, QList<QgsMapLayer *> > QgsWmsRenderContext::layerGroups() const
616{
617 return mLayerGroups;
618}
619
621{
622 int width = mParameters.widthAsInt();
623
624 // May use SRCWIDTH to define image map size
625 if ( ( mFlags & UseSrcWidthHeight ) && mParameters.srcWidthAsInt() > 0 )
626 {
627 width = mParameters.srcWidthAsInt();
628 }
629
630 return width;
631}
632
634{
635 int height = mParameters.heightAsInt();
636
637 // May use SRCHEIGHT to define image map size
638 if ( ( mFlags & UseSrcWidthHeight ) && mParameters.srcHeightAsInt() > 0 )
639 {
640 height = mParameters.srcHeightAsInt();
641 }
642
643 return height;
644}
645
647{
649}
650
651bool QgsWmsRenderContext::isValidWidthHeight( int width, int height ) const
652{
653 if ( width <= 0 || height <= 0 )
654 return false;
655
656 //test if maxWidth / maxHeight are set in the project or as an env variable
657 //and WIDTH / HEIGHT parameter is in the range allowed range
658 //WIDTH
659 const int wmsMaxWidthProj = QgsServerProjectUtils::wmsMaxWidth( *mProject );
660 const int wmsMaxWidthEnv = settings().wmsMaxWidth();
661 int wmsMaxWidth;
662 if ( wmsMaxWidthEnv != -1 && wmsMaxWidthProj != -1 )
663 {
664 // both are set, so we take the more conservative one
665 wmsMaxWidth = std::min( wmsMaxWidthProj, wmsMaxWidthEnv );
666 }
667 else
668 {
669 // none or one are set, so we take the bigger one which is the one set or -1
670 wmsMaxWidth = std::max( wmsMaxWidthProj, wmsMaxWidthEnv );
671 }
672
673 if ( wmsMaxWidth != -1 && width > wmsMaxWidth )
674 {
675 return false;
676 }
677
678 //HEIGHT
679 const int wmsMaxHeightProj = QgsServerProjectUtils::wmsMaxHeight( *mProject );
680 const int wmsMaxHeightEnv = settings().wmsMaxHeight();
681 int wmsMaxHeight;
682 if ( wmsMaxHeightEnv != -1 && wmsMaxHeightProj != -1 )
683 {
684 // both are set, so we take the more conservative one
685 wmsMaxHeight = std::min( wmsMaxHeightProj, wmsMaxHeightEnv );
686 }
687 else
688 {
689 // none or one are set, so we take the bigger one which is the one set or -1
690 wmsMaxHeight = std::max( wmsMaxHeightProj, wmsMaxHeightEnv );
691 }
692
693 if ( wmsMaxHeight != -1 && height > wmsMaxHeight )
694 {
695 return false;
696 }
697
698 // Sanity check from internal QImage checks
699 // (see QImageData::calculateImageParameters() in qimage_p.h)
700 // this is to report a meaningful error message in case of
701 // image creation failure and to differentiate it from out
702 // of memory conditions.
703
704 // depth for now it cannot be anything other than 32, but I don't like
705 // to hardcode it: I hope we will support other depths in the future.
706 int depth = 32;
707 switch ( mParameters.format() )
708 {
709 case QgsWmsParameters::Format::JPG:
710 case QgsWmsParameters::Format::PNG:
711 default:
712 depth = 32;
713 }
714
715 if ( width > ( std::numeric_limits<int>::max() - 31 ) / depth )
716 return false;
717
718 const int bytes_per_line = ( ( width * depth + 31 ) >> 5 ) << 2; // bytes per scanline (must be multiple of 4)
719
720 if ( std::numeric_limits<int>::max() / bytes_per_line < height
721 || std::numeric_limits<int>::max() / sizeof( uchar * ) < static_cast<uint>( height ) )
722 {
723 return false;
724 }
725
726 return true;
727}
728
729double QgsWmsRenderContext::mapTileBuffer( const int mapWidth ) const
730{
731 double buffer;
732 if ( mFlags & UseTileBuffer )
733 {
734 const QgsRectangle extent = mParameters.bboxAsRectangle();
735 if ( !mParameters.bbox().isEmpty() && extent.isEmpty() )
736 {
738 mParameters[QgsWmsParameter::BBOX] );
739 }
740 buffer = tileBuffer() * ( extent.width() / mapWidth );
741 }
742 else
743 {
744 buffer = 0;
745 }
746 return buffer;
747}
748
749QSize QgsWmsRenderContext::mapSize( const bool aspectRatio ) const
750{
751 int width = mapWidth();
752 int height = mapHeight();
753
754 // Adapt width / height if the aspect ratio does not correspond with the BBOX.
755 // Required by WMS spec. 1.3.
756 if ( aspectRatio
757 && mParameters.versionAsNumber() >= QgsProjectVersion( 1, 3, 0 ) )
758 {
759 QgsRectangle extent = mParameters.bboxAsRectangle();
760 if ( !mParameters.bbox().isEmpty() && extent.isEmpty() )
761 {
763 mParameters[QgsWmsParameter::BBOX] );
764 }
765
766 QString crs = mParameters.crs();
767 if ( crs.compare( "CRS:84", Qt::CaseInsensitive ) == 0 )
768 {
769 crs = QString( "EPSG:4326" );
770 extent.invert();
771 }
772
775 {
776 extent.invert();
777 }
778
779 if ( !extent.isEmpty() && height > 0 && width > 0 )
780 {
781 const double mapRatio = extent.width() / extent.height();
782 const double imageRatio = static_cast<double>( width ) / static_cast<double>( height );
783 if ( !qgsDoubleNear( mapRatio, imageRatio, 0.0001 ) )
784 {
785 // inspired by MapServer, mapdraw.c L115
786 const double cellsize = ( extent.width() / static_cast<double>( width ) ) * 0.5 + ( extent.height() / static_cast<double>( height ) ) * 0.5;
787 width = extent.width() / cellsize;
788 height = extent.height() / cellsize;
789 }
790 }
791 }
792
793 if ( width <= 0 )
794 {
796 mParameters[QgsWmsParameter::WIDTH] );
797 }
798 else if ( height <= 0 )
799 {
801 mParameters[QgsWmsParameter::HEIGHT] );
802 }
803
804 return QSize( width, height );
805}
806
807void QgsWmsRenderContext::removeUnwantedLayers()
808{
809 QList<QgsMapLayer *> layers;
810
811 for ( QgsMapLayer *layer : mLayersToRender )
812 {
813 const QString nickname = layerNickname( *layer );
814
815 if ( ! isExternalLayer( nickname ) )
816 {
817 if ( !layerScaleVisibility( nickname ) )
818 continue;
819
820 if ( mRestrictedLayers.contains( nickname ) )
821 continue;
822
823 if ( mFlags & UseWfsLayersOnly )
824 {
826 {
827 continue;
828 }
829
830 const QStringList wfsLayers = QgsServerProjectUtils::wfsLayerIds( *mProject );
831 if ( ! wfsLayers.contains( layer->id() ) )
832 {
833 continue;
834 }
835 }
836 }
837
838 layers.append( layer );
839 }
840
841 mLayersToRender = layers;
842}
843
844bool QgsWmsRenderContext::isExternalLayer( const QString &name ) const
845{
846 for ( const auto &layer : mExternalLayers )
847 {
848 if ( layerNickname( *layer ).compare( name ) == 0 )
849 return true;
850 }
851
852 return false;
853}
854
855void QgsWmsRenderContext::checkLayerReadPermissions()
856{
857#ifdef HAVE_SERVER_PYTHON_PLUGINS
858 for ( const auto layer : mLayersToRender )
859 {
860 if ( !accessControl()->layerReadPermission( layer ) )
861 {
862 throw QgsSecurityException( QStringLiteral( "You are not allowed to access to the layer: %1" ).arg( layer->name() ) );
863 }
864 }
865#endif
866}
867
868#ifdef HAVE_SERVER_PYTHON_PLUGINS
869QgsAccessControl *QgsWmsRenderContext::accessControl() const
870{
871 return mInterface->accessControls();
872}
873#endif
874
876{
877 mSocketFeedback = feedback;
878}
879
881{
882 return mSocketFeedback;
883}
@ Vector
Vector layer.
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 the axis order is inverted for the CRS compared to the order east/north (longitude/la...
Base class for feedback objects to be used for cancellation of something running in a worker thread.
Definition: qgsfeedback.h:44
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:75
QString name
Definition: qgsmaplayer.h:78
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.
Qgis::LayerType type
Definition: qgsmaplayer.h:82
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:83
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:107
QString title() const
Returns the project's title.
Definition: qgsproject.cpp:506
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 width() const
Returns the width of the rectangle.
Definition: qgsrectangle.h:236
bool isEmpty() const
Returns true if the rectangle has no area.
Definition: qgsrectangle.h:492
double height() const
Returns the height of the rectangle.
Definition: qgsrectangle.h:243
void invert()
Swap x/y coordinates in the rectangle.
Definition: qgsrectangle.h:604
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...
QgsFeedback * socketFeedback() const
Returns the response feedback if any.
~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.
void setSocketFeedback(QgsFeedback *feedback)
Sets the response feedback.
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 bool wmsSkipNameForGroup(const QgsProject &project)
Returns if name attribute should be skipped for groups in WMS capabilities document.
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:5207
const QgsCoordinateReferenceSystem & outputCrs
const QgsCoordinateReferenceSystem & crs
const double OGC_PX_M