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