QGIS API Documentation 3.41.0-Master (cea29feecf2)
Loading...
Searching...
No Matches
qgsmaptip.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsmaptips.cpp - Query a layer and show a maptip on the canvas
3 ---------------------
4 begin : October 2007
5 copyright : (C) 2007 by Gary Sherman
6 email : sherman @ mrcc dot com
7 ***************************************************************************
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 ***************************************************************************/
15// QGIS includes
16#include "qgsfeatureiterator.h"
17#include "qgsmapcanvas.h"
18#include "qgsmaptool.h"
19#include "qgsvectorlayer.h"
20#include "qgsrasterlayer.h"
21#include "qgsexpression.h"
22#include "qgslogger.h"
23#include "qgssettings.h"
24#include "qgswebview.h"
25#include "qgswebframe.h"
26#include "qgsapplication.h"
27#include "qgsrenderer.h"
30#include "qgsrendercontext.h"
31#include "qgsmapcanvasutils.h"
32
33// Qt includes
34#include <QPoint>
35#include <QToolTip>
36#include <QSettings>
37#include <QLabel>
38#include <QDesktopServices>
39#if WITH_QTWEBKIT
40#include <QWebElement>
41#endif
42#include <QHBoxLayout>
43
44#include "qgsmaptip.h"
45#include "moc_qgsmaptip.cpp"
46
47
48const QString QgsMapTip::sMapTipTemplate = "<html>\n"
49 " <head>\n"
50 " <style>\n"
51 " body {\n"
52 " margin: 0;\n"
53 " font: %1pt \"%2\";\n"
54 " color: %3;\n"
55 " width: %4px;\n"
56 " }\n"
57 " #QgsWebViewContainer {\n"
58 " background-color: %5;\n"
59 " border: 1px solid %6;\n"
60 " display: inline-block;\n"
61 " margin: 0\n"
62 " }\n"
63 " #QgsWebViewContainerInner {\n"
64 " margin: 5px\n"
65 " }\n"
66 " </style>\n"
67 " </head>\n"
68 " <body>\n"
69 " <div id='QgsWebViewContainer'>\n"
70 " <div id='QgsWebViewContainerInner'>\n"
71 " %7\n"
72 " </div>\n"
73 " </div>\n"
74 " </body>\n"
75 "</html>\n";
76
77
79{
80 // Init the visible flag
81 mMapTipVisible = false;
82
83 mDelayedClearTimer.setSingleShot( true );
84 connect( &mDelayedClearTimer, &QTimer::timeout, this, [=]() { this->clear(); } );
85}
86
87void QgsMapTip::showMapTip( QgsMapLayer *pLayer, QgsPointXY &mapPosition, const QPoint &pixelPosition, QgsMapCanvas *pMapCanvas )
88{
89 // Do the search using the active layer and the preferred label field for the
90 // layer. The label field must be defined in the layer configuration
91 // file/database. The code required to do this is similar to identify, except
92 // we only want the first qualifying feature and we will only display the
93 // field defined as the label field in the layer configuration file/database
94
95 // Do not render map tips if the layer is not visible
96 if ( !pMapCanvas->layers( true ).contains( pLayer ) )
97 {
98 return;
99 }
100
101 // Do not render a new map tip when the mouse hovers an existing one
102 if ( mWebView && mWebView->underMouse() )
103 {
104 return;
105 }
106
107 // Show the maptip on the canvas
108 QString tipText, lastTipText, tipHtml;
109
110 if ( !mWebView )
111 {
112 mWebView = new QgsWebView( pMapCanvas );
113 // Make the webwiew transparent
114
115 // Setting the background color to 'transparent' does not play nice
116 // with webkit scrollbars, that are rendered as black rectangles (#54683)
117 QColor transparentColor = mWebView->palette().color( QPalette::Window );
118 transparentColor.setAlpha( 0 );
119 mWebView->setStyleSheet( QString( "background:%1;" ).arg( transparentColor.name( QColor::HexArgb ) ) );
120
121
122#if WITH_QTWEBKIT
123 mWebView->page()->setLinkDelegationPolicy( QWebPage::DelegateAllLinks ); //Handle link clicks by yourself
124 mWebView->setContextMenuPolicy( Qt::NoContextMenu ); //No context menu is allowed if you don't need it
125 connect( mWebView, &QWebView::linkClicked, this, &QgsMapTip::onLinkClicked );
126 connect( mWebView, &QWebView::loadFinished, this, [=]( bool ) { resizeAndMoveToolTip(); } );
127#endif
128
129 mWebView->page()->settings()->setAttribute( QWebSettings::DeveloperExtrasEnabled, true );
130 mWebView->page()->settings()->setAttribute( QWebSettings::JavascriptEnabled, true );
131 mWebView->page()->settings()->setAttribute( QWebSettings::LocalStorageEnabled, true );
132
133 // Disable scrollbars, avoid random resizing issues
134 mWebView->page()->mainFrame()->setScrollBarPolicy( Qt::Horizontal, Qt::ScrollBarAlwaysOff );
135 mWebView->page()->mainFrame()->setScrollBarPolicy( Qt::Vertical, Qt::ScrollBarAlwaysOff );
136 }
137
138 // Only supported layer types here:
139 switch ( pLayer->type() )
140 {
142 tipText = fetchFeature( pLayer, mapPosition, pMapCanvas );
143 break;
145 tipText = fetchRaster( pLayer, mapPosition, pMapCanvas );
146 break;
147 default:
148 break;
149 }
150
151 mMapTipVisible = !tipText.isEmpty();
152 if ( !mMapTipVisible )
153 {
154 clear();
155 return;
156 }
157
158 if ( tipText == lastTipText )
159 {
160 return;
161 }
162
163 // Compute offset from the cursor position
164 int cursorOffset = 0;
166 {
167 // The following calculations are taken
168 // from QgsApplication::getThemeCursor, and are used to calculate the correct cursor size
169 // for both hi-dpi and non-hi-dpi screens.
170 double scale = Qgis::UI_SCALE_FACTOR * QgsApplication::instance()->fontMetrics().height() / 32.0;
171 cursorOffset = static_cast<int>( std::ceil( scale * 32 ) );
172 }
173
174 // Ensures the map tip is never larger than the available space
175 const int MAX_WIDTH = std::max( pixelPosition.x(), pMapCanvas->width() - pixelPosition.x() ) - cursorOffset - 5;
176 const int MAX_HEIGHT = std::max( pixelPosition.y(), pMapCanvas->height() - pixelPosition.y() ) - 5;
177
178 mWebView->setMaximumSize( MAX_WIDTH, MAX_HEIGHT );
179
180 tipHtml = QgsMapTip::htmlText( tipText, MAX_WIDTH );
181
182 QgsDebugMsgLevel( tipHtml, 2 );
183
184 mPosition = pixelPosition;
185 mMapCanvas = pMapCanvas;
186 mWebView->setHtml( tipHtml );
187 lastTipText = tipText;
188
189#if !WITH_QTWEBKIT
190 resizeAndMoveToolTip();
191#endif
192}
193
194void QgsMapTip::resizeAndMoveToolTip()
195{
196#if WITH_QTWEBKIT
197 // Get the content size
198 const QWebElement container = mWebView->page()->mainFrame()->findFirstElement(
199 QStringLiteral( "#QgsWebViewContainer" )
200 );
201 const int width = container.geometry().width();
202 const int height = container.geometry().height();
203 mWebView->resize( width, height );
204#else
205 mWebView->adjustSize();
206#endif
207
208 int cursorOffset = 0;
209 // attempt to shift the tip away from the cursor.
211 {
212 // The following calculations are taken
213 // from QgsApplication::getThemeCursor, and are used to calculate the correct cursor size
214 // for both hi-dpi and non-hi-dpi screens.
215 double scale = Qgis::UI_SCALE_FACTOR * QgsApplication::instance()->fontMetrics().height() / 32.0;
216 cursorOffset = static_cast<int>( std::ceil( scale * 32 ) );
217 }
218
219 if ( !mMapCanvas )
220 {
221 mWebView->move( mPosition );
222 mWebView->show();
223 return;
224 }
225
226 // Check if there is enough space to the right of the cursor
227 int availableWidthRight = mMapCanvas->width() - mPosition.x() - cursorOffset;
228 int availableWidthLeft = mPosition.x() - cursorOffset;
229 int availableHeightBottom = mMapCanvas->height() - mPosition.y();
230 int availableHeightTop = mPosition.y();
231 int x, y;
232 // If there is enough space on the right, or more space on the right than on the left, move the map tip to the right of the cursor
233 if ( mWebView->width() < availableWidthRight || availableWidthRight > availableWidthLeft )
234 {
235 x = mPosition.x() + cursorOffset;
236 }
237 // Otherwise, move the map tip to the left of the cursor
238 else
239 {
240 x = mPosition.x() - mWebView->width() - cursorOffset;
241 }
242
243 // If there is enough space on the bottom, or more space on the bottom than on the top, move the map tip to the bottom of the cursor
244 if ( mWebView->height() < availableHeightBottom || availableHeightBottom > availableHeightTop )
245 {
246 y = mPosition.y();
247 }
248 // Otherwise, move the map tip to the top of the cursor
249 else
250 {
251 y = mPosition.y() - mWebView->height();
252 }
253 mWebView->move( x, y );
254 mWebView->show();
255}
256
257void QgsMapTip::clear( QgsMapCanvas *, int msDelay )
258{
259 if ( !mMapTipVisible )
260 {
261 return;
262 }
263
264 // Skip clearing the map tip if the user interacts with it or the timer still runs
265 if ( mDelayedClearTimer.isActive() || mWebView->underMouse() )
266 {
267 return;
268 }
269
270 if ( msDelay > 0 )
271 {
272 mDelayedClearTimer.start( msDelay );
273 return;
274 }
275 mWebView->setHtml( QString() );
276 mWebView->hide();
277
278 // Reset the visible flag
279 mMapTipVisible = false;
280}
281
282QString QgsMapTip::fetchFeature( QgsMapLayer *layer, QgsPointXY &mapPosition, QgsMapCanvas *mapCanvas )
283{
284 QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( layer );
285 if ( !vlayer || !vlayer->isSpatial() || !vlayer->mapTipsEnabled() )
286 {
287 return QString();
288 }
289
290 if ( !layer->isInScaleRange( mapCanvas->mapSettings().scale() ) || ( mapCanvas->mapSettings().isTemporal() && layer->temporalProperties() && !layer->temporalProperties()->isVisibleInTemporalRange( mapCanvas->temporalRange() ) ) )
291 {
292 return QString();
293 }
294
295 const double searchRadius = QgsMapTool::searchRadiusMU( mapCanvas );
296
297 QgsRectangle r;
298 r.setXMinimum( mapPosition.x() - searchRadius );
299 r.setYMinimum( mapPosition.y() - searchRadius );
300 r.setXMaximum( mapPosition.x() + searchRadius );
301 r.setYMaximum( mapPosition.y() + searchRadius );
302
303 r = mapCanvas->mapSettings().mapToLayerCoordinates( layer, r );
304
306 context.appendScope( QgsExpressionContextUtils::mapSettingsScope( mapCanvas->mapSettings() ) );
307 context.appendScope( QgsExpressionContextUtils::mapLayerPositionScope( r.center() ) );
308
309 const QString canvasFilter = QgsMapCanvasUtils::filterForLayer( mapCanvas, vlayer );
310 if ( canvasFilter == QLatin1String( "FALSE" ) )
311 {
312 return QString();
313 }
314
315 const QString mapTip = vlayer->mapTipTemplate();
316 QString tipString;
317 QgsExpression exp( vlayer->displayExpression() );
318 QgsFeature feature;
319
320 QgsFeatureRequest request;
321 request.setFilterRect( r );
323 if ( !canvasFilter.isEmpty() )
324 {
325 request.setFilterExpression( canvasFilter );
326 }
327
328 if ( mapTip.isEmpty() )
329 {
330 exp.prepare( &context );
331 request.setSubsetOfAttributes( exp.referencedColumns(), vlayer->fields() );
332 }
333
335 renderCtx.setExpressionContext( mapCanvas->createExpressionContext() );
337
338 bool filter = false;
339 std::unique_ptr<QgsFeatureRenderer> renderer;
340 if ( vlayer->renderer() )
341 {
342 renderer.reset( vlayer->renderer()->clone() );
343 renderer->startRender( renderCtx, vlayer->fields() );
344 filter = renderer->capabilities() & QgsFeatureRenderer::Filter;
345
346 const QString filterExpression = renderer->filter( vlayer->fields() );
347 if ( !filterExpression.isEmpty() )
348 {
349 request.combineFilterExpression( filterExpression );
350 }
351 }
352 request.setExpressionContext( renderCtx.expressionContext() );
353
354 QgsFeatureIterator it = vlayer->getFeatures( request );
355 QElapsedTimer timer;
356 timer.start();
357 while ( it.nextFeature( feature ) )
358 {
359 context.setFeature( feature );
360
361 renderCtx.expressionContext().setFeature( feature );
362 if ( filter && renderer && !renderer->willRenderFeature( feature, renderCtx ) )
363 {
364 continue;
365 }
366
367 if ( !mapTip.isEmpty() )
368 {
369 tipString = QgsExpression::replaceExpressionText( mapTip, &context );
370 }
371 else
372 {
373 tipString = exp.evaluate( &context ).toString();
374 }
375
376 if ( !tipString.isEmpty() || timer.elapsed() >= 1000 )
377 {
378 break;
379 }
380 }
381
382 if ( renderer )
383 {
384 renderer->stopRender( renderCtx );
385 }
386
387 return tipString;
388}
389
390QString QgsMapTip::fetchRaster( QgsMapLayer *layer, QgsPointXY &mapPosition, QgsMapCanvas *mapCanvas )
391{
392 QgsRasterLayer *rlayer = qobject_cast<QgsRasterLayer *>( layer );
393 if ( !rlayer || !rlayer->mapTipsEnabled() )
394 {
395 return QString();
396 }
397
398 if ( !layer->isInScaleRange( mapCanvas->mapSettings().scale() ) || ( mapCanvas->mapSettings().isTemporal() && !layer->temporalProperties()->isVisibleInTemporalRange( mapCanvas->temporalRange() ) ) )
399 {
400 return QString();
401 }
402
403 if ( rlayer->mapTipTemplate().isEmpty() )
404 {
405 return QString();
406 }
407
408 const QgsPointXY mappedPosition { mapCanvas->mapSettings().mapToLayerCoordinates( layer, mapPosition ) };
409
410 if ( !layer->extent().contains( mappedPosition ) )
411 {
412 return QString();
413 }
414
416 context.appendScope( QgsExpressionContextUtils::mapSettingsScope( mapCanvas->mapSettings() ) );
417 context.appendScope( QgsExpressionContextUtils::mapLayerPositionScope( mappedPosition ) );
418 return QgsExpression::replaceExpressionText( rlayer->mapTipTemplate(), &context );
419}
420
421QString QgsMapTip::htmlText( const QString &text, int maxWidth )
422{
423 const QgsSettings settings;
424 const QFont defaultFont = qApp->font();
425 const int fontSize = defaultFont.pointSize();
426 const QString fontFamily = defaultFont.family();
427 const QString backgroundColor = QgsApplication::palette().base().color().name();
428 const QString strokeColor = QgsApplication::palette().shadow().color().name();
429 const QString textColor = QgsApplication::palette().toolTipText().color().name();
430 return sMapTipTemplate.arg( fontSize ).arg( fontFamily ).arg( textColor ).arg( maxWidth == -1 ? "" : QString::number( maxWidth ) ).arg( backgroundColor ).arg( strokeColor ).arg( text );
431}
432
433// This slot handles all clicks
434void QgsMapTip::onLinkClicked( const QUrl &url )
435{
436 QDesktopServices::openUrl( url );
437}
438
439
440QString QgsMapTip::vectorMapTipPreviewText( QgsMapLayer *layer, QgsMapCanvas *mapCanvas, const QString &mapTemplate, const QString &displayExpression )
441{
442 // Only spatial layers can have map tips
443 QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( layer );
444 if ( !mapCanvas || !vlayer || !vlayer->isSpatial() )
445 return QString();
446
447 // If no map tip template or display expression is set, return an empty string
448 if ( mapTemplate.isEmpty() && displayExpression.isEmpty() )
449 return QString();
450
451 // Create an expression context
454
455 // Get the first feature if any, and add it to the expression context
456 QgsFeature previewFeature;
457 if ( vlayer->featureCount() > 0 )
458 {
459 QgsFeatureIterator it = vlayer->getFeatures( QgsFeatureRequest().setLimit( 1 ) );
460 it.nextFeature( previewFeature );
461 }
462 else
463 {
464 previewFeature = QgsFeature( vlayer->fields() );
465 }
466 context.setFeature( previewFeature );
467
468 // Generate the map tip text from the context and the mapTipTemplate/displayExpression
469 QString tipText;
470 if ( mapTemplate.isEmpty() )
471 {
472 QgsExpression exp( displayExpression );
473 exp.prepare( &context );
474 tipText = exp.evaluate( &context ).toString();
475 }
476 else
477 {
478 tipText = QgsExpression::replaceExpressionText( mapTemplate, &context );
479 }
480
481 // Insert the map tip text into the html template
482 return QgsMapTip::htmlText( tipText, mapCanvas->width() / 2 );
483}
484
485QString QgsMapTip::rasterMapTipPreviewText( QgsMapLayer *layer, QgsMapCanvas *mapCanvas, const QString &mapTemplate )
486{
487 QgsRasterLayer *rlayer = qobject_cast<QgsRasterLayer *>( layer );
488 if ( !mapCanvas || !rlayer || mapTemplate.isEmpty() )
489 {
490 return QString();
491 }
492
493 // Create an expression context
496
497 // Get the position of the center of the layer, and add it to the expression context
498 const QgsPointXY mappedPosition { layer->extent().center() };
500
501 // Generate the map tip text from the context and the mapTipTemplate
502 const QString tipText = QgsExpression::replaceExpressionText( mapTemplate, &context );
503
504 // Insert the map tip text into the html template
505 return QgsMapTip::htmlText( tipText, mapCanvas->width() / 2 );
506}
@ ExactIntersect
Use exact geometry intersection (slower) instead of bounding boxes.
@ Vector
Vector layer.
@ Raster
Raster layer.
static const double UI_SCALE_FACTOR
UI scaling factor.
Definition qgis.h:5733
static QgsApplication * instance()
Returns the singleton instance of the QgsApplication.
static QgsExpressionContextScope * mapLayerPositionScope(const QgsPointXY &position)
Sets the expression context variables which are available for expressions triggered by moving the mou...
static QgsExpressionContextScope * mapSettingsScope(const QgsMapSettings &mapSettings)
Creates a new scope which contains variables and functions relating to a QgsMapSettings object.
static QList< QgsExpressionContextScope * > globalProjectLayerScopes(const QgsMapLayer *layer)
Creates a list of three scopes: global, layer's project and layer.
static QgsExpressionContextScope * layerScope(const QgsMapLayer *layer)
Creates a new scope which contains variables and functions relating to a QgsMapLayer.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
void appendScope(QgsExpressionContextScope *scope)
Appends a scope to the end of the context.
void setFeature(const QgsFeature &feature)
Convenience function for setting a feature for the context.
Class for parsing and evaluation of expressions (formerly called "search strings").
bool prepare(const QgsExpressionContext *context)
Gets the expression ready for evaluation - find out column indexes.
static QString replaceExpressionText(const QString &action, const QgsExpressionContext *context, const QgsDistanceArea *distanceArea=nullptr)
This function replaces each expression between [% and %] in the string with the result of its evaluat...
QVariant evaluate()
Evaluate the feature and return the result.
Wrapper for iterator of features from vector data provider or vector layer.
bool nextFeature(QgsFeature &f)
Fetch next feature and stores in f, returns true on success.
@ Filter
Features may be filtered, i.e. some features may not be rendered (categorized, rule based ....
virtual QgsFeatureRenderer * clone() const =0
Create a deep copy of this renderer.
This class wraps a request for features to a vector layer (or directly its vector data provider).
QgsFeatureRequest & setFlags(Qgis::FeatureRequestFlags flags)
Sets flags that affect how features will be fetched.
QgsFeatureRequest & combineFilterExpression(const QString &expression)
Modifies the existing filter expression to add an additional expression filter.
QgsFeatureRequest & setSubsetOfAttributes(const QgsAttributeList &attrs)
Set a subset of attributes that will be fetched.
QgsFeatureRequest & setFilterExpression(const QString &expression)
Set the filter expression.
QgsFeatureRequest & setExpressionContext(const QgsExpressionContext &context)
Sets the expression context used to evaluate filter expressions.
QgsFeatureRequest & setFilterRect(const QgsRectangle &rectangle)
Sets the rectangle from which features will be taken.
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Definition qgsfeature.h:58
static QString filterForLayer(QgsMapCanvas *canvas, QgsVectorLayer *layer)
Constructs a filter to use for selecting features from the given layer, in order to apply filters whi...
Map canvas is a class for displaying all GIS data types on a canvas.
QgsExpressionContext createExpressionContext() const override
This method needs to be reimplemented in all classes which implement this interface and return an exp...
const QgsDateTimeRange & temporalRange() const
Returns map canvas datetime range.
QList< QgsMapLayer * > layers(bool expandGroupLayers=false) const
Returns the list of layers shown within the map canvas.
const QgsMapSettings & mapSettings() const
Gets access to properties used for map rendering.
virtual bool isVisibleInTemporalRange(const QgsDateTimeRange &range) const
Returns true if the layer should be visible and rendered for the specified time range.
Base class for all map layer types.
Definition qgsmaplayer.h:76
bool isInScaleRange(double scale) const
Tests whether the layer should be visible at the specified scale.
virtual QgsRectangle extent() const
Returns the extent of the layer.
Qgis::LayerType type
Definition qgsmaplayer.h:86
virtual QgsMapLayerTemporalProperties * temporalProperties()
Returns the layer's temporal properties.
bool mapTipsEnabled
Definition qgsmaplayer.h:90
QString mapTipTemplate
Definition qgsmaplayer.h:89
double scale() const
Returns the calculated map scale.
QgsPointXY mapToLayerCoordinates(const QgsMapLayer *layer, QgsPointXY point) const
transform point coordinates from output CRS to layer's CRS
void showMapTip(QgsMapLayer *thepLayer, QgsPointXY &mapPosition, const QPoint &pixelPosition, QgsMapCanvas *mpMapCanvas)
Show a maptip at a given point on the map canvas.
Definition qgsmaptip.cpp:87
static QString rasterMapTipPreviewText(QgsMapLayer *layer, QgsMapCanvas *mapCanvas, const QString &mapTemplate)
Returns the html that would be displayed in a maptip for a given layer.
static QString vectorMapTipPreviewText(QgsMapLayer *layer, QgsMapCanvas *mapCanvas, const QString &mapTemplate, const QString &displayExpression)
Returns the html that would be displayed in a maptip for a given layer.
QgsMapTip()
Default constructor.
Definition qgsmaptip.cpp:78
void clear(QgsMapCanvas *mpMapCanvas=nullptr, int msDelay=0)
Clear the current maptip if it exists.
static double searchRadiusMU(const QgsRenderContext &context)
Gets search radius in map units for given context.
A class to represent a 2D point.
Definition qgspointxy.h:60
double y
Definition qgspointxy.h:64
double x
Definition qgspointxy.h:63
Represents a raster layer.
A rectangle specified with double values.
bool contains(const QgsRectangle &rect) const
Returns true when rectangle contains other rectangle.
void setYMinimum(double y)
Set the minimum y value.
void setXMinimum(double x)
Set the minimum x value.
void setYMaximum(double y)
Set the maximum y value.
void setXMaximum(double x)
Set the maximum x value.
QgsPointXY center
Contains information about the context of a rendering operation.
QgsExpressionContext & expressionContext()
Gets the expression context.
static QgsRenderContext fromMapSettings(const QgsMapSettings &mapSettings)
create initialized QgsRenderContext instance from given QgsMapSettings
void setExpressionContext(const QgsExpressionContext &context)
Sets the expression context.
This class is a composition of two QSettings instances:
Definition qgssettings.h:64
bool isTemporal() const
Returns true if the object's temporal range is enabled, and the object will be filtered when renderin...
Represents a vector layer which manages a vector based data sets.
long long featureCount(const QString &legendKey) const
Number of features rendered with specified legend key.
bool isSpatial() const FINAL
Returns true if this is a geometry layer and false in case of NoGeometry (table only) or UnknownGeome...
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const FINAL
Queries the layer for features specified in request.
QgsFeatureRenderer * renderer()
Returns the feature renderer used for rendering the features in the layer in 2D map views.
QString displayExpression
The QgsWebView class is a collection of stubs to mimic the API of QWebView on systems where the real ...
Definition qgswebview.h:66
#define QgsDebugMsgLevel(str, level)
Definition qgslogger.h:39