QGIS API Documentation 4.1.0-Master (60fea48833c)
Loading...
Searching...
No Matches
qgsmaphittest.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsmaphittest.cpp
3 ---------------------
4 begin : September 2014
5 copyright : (C) 2014 by Martin Dobias
6 email : wonder dot sk at gmail 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
16#include "qgsmaphittest.h"
17
19#include "qgsfeatureiterator.h"
20#include "qgsgeometry.h"
21#include "qgsgeometryengine.h"
22#include "qgsmaplayerstyle.h"
23#include "qgsrasterlayer.h"
24#include "qgsrasterlayerutils.h"
25#include "qgsrasterrenderer.h"
26#include "qgsrendercontext.h"
27#include "qgsrenderer.h"
28#include "qgssymbollayerutils.h"
29#include "qgsvectorlayer.h"
31
32#include "moc_qgsmaphittest.cpp"
33
34QgsMapHitTest::QgsMapHitTest( const QgsMapSettings &settings, const QgsGeometry &polygon, const LayerFilterExpression &layerFilterExpression )
35 : mSettings( QgsLayerTreeFilterSettings( settings ) )
36{
37 mSettings.setLayerFilterExpressions( layerFilterExpression );
38 mSettings.setFilterPolygon( polygon );
39}
40
41QgsMapHitTest::QgsMapHitTest( const QgsMapSettings &settings, const LayerFilterExpression &layerFilterExpression )
42 : mSettings( QgsLayerTreeFilterSettings( settings ) )
43{
44 mSettings.setLayerFilterExpressions( layerFilterExpression );
46}
47
49 : mSettings( settings )
50{}
51
53{
54 const QgsMapSettings &mapSettings = mSettings.mapSettings();
55
56 // TODO: do we need this temp image?
57 QImage tmpImage( mapSettings.outputSize(), mapSettings.outputImageFormat() );
58 tmpImage.setDotsPerMeterX( static_cast< int >( std::round( mapSettings.outputDpi() * 25.4 ) ) );
59 tmpImage.setDotsPerMeterY( static_cast< int >( std::round( mapSettings.outputDpi() * 25.4 ) ) );
60 QPainter painter( &tmpImage );
61
63 context.setPainter( &painter ); // we are not going to draw anything, but we still need a working painter
64
65 const QList< QgsMapLayer * > layers = mSettings.layers();
66 for ( QgsMapLayer *layer : layers )
67 {
68 QgsGeometry extent;
69 if ( !( mSettings.flags() & Qgis::LayerTreeFilterFlag::SkipVisibilityCheck ) )
70 {
71 if ( !layer->isInScaleRange( mapSettings.scale() ) )
72 {
73 continue;
74 }
75
76 extent = mSettings.combinedVisibleExtentForLayer( layer );
77
78 context.setCoordinateTransform( mapSettings.layerTransform( layer ) );
79 context.setExtent( extent.boundingBox() );
80 }
81
82 if ( QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( layer ) )
83 {
84 if ( !vl->renderer() )
85 continue;
86
88 SymbolSet &usedSymbols = mHitTest[vl->id()];
89 SymbolSet &usedSymbolsRuleKey = mHitTestRuleKey[vl->id()];
90
91 QgsMapLayerStyleOverride styleOverride( vl );
92 if ( mapSettings.layerStyleOverrides().contains( vl->id() ) )
93 styleOverride.setOverrideStyle( mapSettings.layerStyleOverrides().value( vl->id() ) );
94
95 auto source = std::make_unique< QgsVectorLayerFeatureSource >( vl );
96 runHitTestFeatureSource( source.get(), vl->id(), vl->fields(), vl->renderer(), usedSymbols, usedSymbolsRuleKey, context, nullptr, extent );
97 }
98 else if ( QgsRasterLayer *rl = qobject_cast<QgsRasterLayer *>( layer ) )
99 {
100 if ( !rl->renderer() || !rl->dataProvider() )
101 continue;
102
103 QgsRasterMinMaxOrigin minMaxOrigin = rl->renderer()->minMaxOrigin();
104
105 runHitTestRasterSource( rl->dataProvider(), rl->id(), rl->renderer()->inputBand(), minMaxOrigin, minMaxOrigin.limits(), context, nullptr, extent );
106 }
107 else if ( QgsMeshLayer *ml = qobject_cast<QgsMeshLayer *>( layer ) )
108 {
109 QgsMeshDatasetIndex datasetIndex = ml->activeScalarDatasetIndex( context );
110 QgsMeshRendererScalarSettings scalarSettings = ml->rendererSettings().scalarSettings( datasetIndex.dataset() );
111
112 runHitTestMeshSource( ml, ml->id(), datasetIndex, context, nullptr, extent );
113 }
114 }
115
116 painter.end();
117}
118
119QMap<QString, QSet<QString> > QgsMapHitTest::results() const
120{
121 return mHitTestRuleKey;
122}
123
125QMap<QString, QList<QString> > QgsMapHitTest::resultsPy() const
126{
127 QMap<QString, QList<QString> > res;
128 for ( auto it = mHitTestRuleKey.begin(); it != mHitTestRuleKey.end(); ++it )
129 {
130 res.insert( it.key(), qgis::setToList( it.value() ) );
131 }
132 return res;
133}
135
137{
138 if ( !symbol || !layer )
139 return false;
140
141 auto it = mHitTest.constFind( layer->id() );
142 if ( it == mHitTest.constEnd() )
143 return false;
144
145 return it->contains( QgsSymbolLayerUtils::symbolProperties( symbol ) );
146}
147
148bool QgsMapHitTest::legendKeyVisible( const QString &ruleKey, QgsVectorLayer *layer ) const
149{
150 if ( !layer )
151 return false;
152
153 auto it = mHitTestRuleKey.constFind( layer->id() );
154 if ( it == mHitTestRuleKey.constEnd() )
155 return false;
156
157 return it->contains( ruleKey );
158}
159
160void QgsMapHitTest::runHitTestFeatureSource(
162 const QString &layerId,
163 const QgsFields &fields,
164 const QgsFeatureRenderer *renderer,
165 SymbolSet &usedSymbols,
166 SymbolSet &usedSymbolsRuleKey,
167 QgsRenderContext &context,
168 QgsFeedback *feedback,
169 const QgsGeometry &visibleExtent
170)
171{
172 std::unique_ptr< QgsFeatureRenderer > r( renderer->clone() );
173 const bool moreSymbolsPerFeature = r->capabilities() & QgsFeatureRenderer::MoreSymbolsPerFeature;
174 r->startRender( context, fields );
175
176 // shortcut early if we know that there's nothing visible
177 if ( r->canSkipRender() )
178 {
179 r->stopRender( context );
180 return;
181 }
182
183 // if there's no legend items for this layer, shortcut out early
184 QSet< QString > remainingKeysToFind = r->legendKeys();
185 if ( remainingKeysToFind.empty() )
186 {
187 r->stopRender( context );
188 return;
189 }
190
191 QgsFeatureRequest request;
192 if ( feedback )
193 request.setFeedback( feedback );
194
195 const QString rendererFilterExpression = r->filter( fields );
196 if ( !rendererFilterExpression.isEmpty() )
197 {
198 request.setFilterExpression( rendererFilterExpression );
199 }
200
201 request.setExpressionContext( context.expressionContext() );
202
203 QSet<QString> requiredAttributes = r->usedAttributes( context );
204
205 QgsGeometry transformedPolygon = visibleExtent;
206 if ( transformedPolygon.type() != Qgis::GeometryType::Polygon )
207 {
208 transformedPolygon = QgsGeometry();
209 }
210
211 if ( feedback && feedback->isCanceled() )
212 {
213 r->stopRender( context );
214 return;
215 }
216
217 const QMap<QString, QString> layerFilterExpressions = mSettings.layerFilterExpressions();
218 if ( auto it = layerFilterExpressions.constFind( layerId ); it != layerFilterExpressions.constEnd() )
219 {
220 const QString expression = *it;
221 QgsExpression expr( expression );
222 expr.prepare( &context.expressionContext() );
223
224 requiredAttributes.unite( expr.referencedColumns() );
225 request.combineFilterExpression( expression );
226 }
227
228 request.setSubsetOfAttributes( requiredAttributes, fields );
229
230 std::unique_ptr< QgsGeometryEngine > polygonEngine;
231 if ( !( mSettings.flags() & Qgis::LayerTreeFilterFlag::SkipVisibilityCheck ) )
232 {
233 if ( transformedPolygon.isNull() )
234 {
235 request.setFilterRect( context.extent() );
237 }
238 else
239 {
240 request.setFilterRect( transformedPolygon.boundingBox() );
241 polygonEngine.reset( QgsGeometry::createGeometryEngine( transformedPolygon.constGet() ) );
242 polygonEngine->prepareGeometry();
243 }
244 }
245
246 if ( feedback && feedback->isCanceled() )
247 {
248 r->stopRender( context );
249 return;
250 }
251
252 QgsFeatureIterator fi = source->getFeatures( request );
253
254 usedSymbols.clear();
255 usedSymbolsRuleKey.clear();
256
257 QgsFeature f;
258 while ( fi.nextFeature( f ) )
259 {
260 if ( feedback && feedback->isCanceled() )
261 break;
262
263 // filter out elements outside of the polygon
264 if ( f.hasGeometry() && polygonEngine )
265 {
266 if ( !polygonEngine->intersects( f.geometry().constGet() ) )
267 {
268 continue;
269 }
270 }
271
272 context.expressionContext().setFeature( f );
273
274 //make sure we store string representation of symbol, not pointer
275 //otherwise layer style override changes will delete original symbols and leave hanging pointers
276 const QSet< QString > legendKeysForFeature = r->legendKeysForFeature( f, context );
277 for ( const QString &legendKey : legendKeysForFeature )
278 {
279 usedSymbolsRuleKey.insert( legendKey );
280 remainingKeysToFind.remove( legendKey );
281 }
282
283 if ( moreSymbolsPerFeature )
284 {
285 const QgsSymbolList originalSymbolsForFeature = r->originalSymbolsForFeature( f, context );
286 for ( QgsSymbol *s : originalSymbolsForFeature )
287 {
288 if ( s )
289 usedSymbols.insert( QgsSymbolLayerUtils::symbolProperties( s ) );
290 }
291 }
292 else
293 {
294 QgsSymbol *s = r->originalSymbolForFeature( f, context );
295 if ( s )
296 usedSymbols.insert( QgsSymbolLayerUtils::symbolProperties( s ) );
297 }
298
299 if ( remainingKeysToFind.empty() )
300 {
301 // already found features for all legend items, no need to keep searching
302 break;
303 }
304 }
305 r->stopRender( context );
306}
307
308void QgsMapHitTest::runHitTestRasterSource(
309 QgsRasterDataProvider *provider,
310 const QString &layerId,
311 const int band,
312 const QgsRasterMinMaxOrigin minMaxOrigin,
313 const Qgis::RasterRangeLimit rangeLimit,
314 const QgsRenderContext &context,
315 QgsFeedback *feedback,
316 const QgsGeometry &visibleExtent
317)
318{
319 if ( feedback && feedback->isCanceled() )
320 return;
321
322 QgsRectangle transformedExtent;
323 if ( visibleExtent.type() != Qgis::GeometryType::Polygon )
324 {
325 transformedExtent = context.extent();
326 }
327 else
328 {
329 transformedExtent = visibleExtent.boundingBox();
330 }
331
332 double min = std::numeric_limits<double>::quiet_NaN();
333 double max = std::numeric_limits<double>::quiet_NaN();
334 bool found = false;
335
336 switch ( minMaxOrigin.extent() )
337 {
339 {
340 if ( provider->extent().intersects( transformedExtent ) )
341 {
342 QgsRasterLayerUtils::computeMinMax( provider, band, minMaxOrigin, rangeLimit, transformedExtent, static_cast<int>( QgsRasterLayer::SAMPLE_SIZE ), min, max );
343 found = true;
344 }
345 break;
346 }
349 break;
350 }
351
352 if ( found )
353 {
354 mHitTestRenderersUpdatedCanvas.insert( layerId, std::pair<double, double>( min, max ) );
355 }
356}
357
358void QgsMapHitTest::runHitTestMeshSource(
359 QgsMeshLayer *layer, const QString &layerId, const QgsMeshDatasetIndex datasetIndex, const QgsRenderContext &context, QgsFeedback *feedback, const QgsGeometry &visibleExtent
360)
361{
362 if ( feedback && feedback->isCanceled() )
363 return;
364
365 QgsRectangle transformedExtent;
366 if ( visibleExtent.type() != Qgis::GeometryType::Polygon )
367 {
368 transformedExtent = context.extent();
369 }
370 else
371 {
372 transformedExtent = visibleExtent.boundingBox();
373 }
374
375 Qgis::MeshRangeExtent rangeExtent = layer->rendererSettings().scalarSettings( datasetIndex.group() ).extent();
376 Qgis::MeshRangeLimit rangeLimit = layer->rendererSettings().scalarSettings( datasetIndex.group() ).limits();
377
378 double min = std::numeric_limits<double>::quiet_NaN();
379 double max = std::numeric_limits<double>::quiet_NaN();
380 bool found = false;
381
382 if ( datasetIndex.isValid() )
383 {
384 switch ( rangeExtent )
385 {
387 {
388 switch ( rangeLimit )
389 {
391 {
392 found = layer->minimumMaximumActiveScalarDataset( transformedExtent, datasetIndex, min, max );
393 break;
394 }
396 break;
397 }
398 break;
399 }
402 break;
403 }
404 }
405
406 if ( found )
407 {
408 mHitTestRenderersUpdatedCanvas.insert( layerId, std::pair<double, double>( min, max ) );
409 }
410}
411
412//
413// QgsMapHitTestTask
414//
415
417 : QgsTask( tr( "Updating Legend" ), QgsTask::Flag::CanCancel | QgsTask::Flag::CancelWithoutPrompt | QgsTask::Flag::Silent )
418 , mSettings( settings )
419{
420 prepare();
421}
422
423QMap<QString, QSet<QString> > QgsMapHitTestTask::results() const
424{
425 return mResults;
426}
427
429QMap<QString, QList<QString> > QgsMapHitTestTask::resultsPy() const
430{
431 QMap<QString, QList<QString> > res;
432 for ( auto it = mResults.begin(); it != mResults.end(); ++it )
433 {
434 res.insert( it.key(), qgis::setToList( it.value() ) );
435 }
436 return res;
437}
439
440void QgsMapHitTestTask::prepare()
441{
442 const QgsMapSettings &mapSettings = mSettings.mapSettings();
443
444 const QList< QgsMapLayer * > layers = mSettings.layers();
445
446 QgsRenderContext context = QgsRenderContext::fromMapSettings( mapSettings );
447
448 for ( QgsMapLayer *layer : layers )
449 {
450 QgsGeometry extent;
451 if ( !( mSettings.flags() & Qgis::LayerTreeFilterFlag::SkipVisibilityCheck ) )
452 {
453 if ( !layer->isInScaleRange( mapSettings.scale() ) )
454 {
455 continue;
456 }
457
458 extent = mSettings.combinedVisibleExtentForLayer( layer );
459 }
460
461 if ( QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( layer ) )
462 {
463 if ( !vl->renderer() )
464 continue;
465
466 QgsMapLayerStyleOverride styleOverride( vl );
467 if ( mapSettings.layerStyleOverrides().contains( vl->id() ) )
468 styleOverride.setOverrideStyle( mapSettings.layerStyleOverrides().value( vl->id() ) );
469
470 PreparedLayerData layerData;
471 layerData.source = std::make_unique< QgsVectorLayerFeatureSource >( vl );
472 layerData.layerId = vl->id();
473 layerData.fields = vl->fields();
474 layerData.renderer.reset( vl->renderer()->clone() );
475 layerData.transform = mapSettings.layerTransform( vl );
476 layerData.extent = extent;
477 layerData.layerScope.reset( QgsExpressionContextUtils::layerScope( vl ) );
478
479 mPreparedData.emplace_back( std::move( layerData ) );
480 }
481 else if ( QgsRasterLayer *rl = qobject_cast<QgsRasterLayer *>( layer ) )
482 {
483 if ( !rl->dataProvider() || !rl->renderer() )
484 continue;
485
486 QgsRasterMinMaxOrigin minMaxOrigin = rl->renderer()->minMaxOrigin();
487
488 PreparedRasterData rasterData;
489 rasterData.provider = std::unique_ptr< QgsRasterDataProvider >( rl->dataProvider()->clone() );
490 rasterData.provider->moveToThread( nullptr );
491
492 rasterData.layerId = rl->id();
493 rasterData.band = rl->renderer()->inputBand();
494 rasterData.minMaxOrigin = minMaxOrigin;
495 rasterData.rangeLimit = minMaxOrigin.limits();
496 rasterData.transform = mapSettings.layerTransform( rl );
497 rasterData.extent = extent;
498
499 mPreparedRasterData.emplace_back( std::move( rasterData ) );
500 }
501 else if ( QgsMeshLayer *ml = qobject_cast<QgsMeshLayer *>( layer ) )
502 {
503 PreparedMeshData meshData;
504 meshData.layer = std::unique_ptr< QgsMeshLayer >( ml->clone() );
505 meshData.layer->moveToThread( nullptr );
506
507 meshData.layerId = ml->id();
508 meshData.datasetIndex = ml->activeScalarDatasetIndex( context );
509 meshData.transform = mapSettings.layerTransform( ml );
510 meshData.extent = extent;
511
512 mPreparedMeshData.emplace_back( std::move( meshData ) );
513 }
514 }
515}
516
518{
519 if ( mFeedback )
520 mFeedback->cancel();
521
523}
524
526{
527 mFeedback = std::make_unique< QgsFeedback >();
528 connect( mFeedback.get(), &QgsFeedback::progressChanged, this, &QgsTask::progressChanged );
529
530 auto hitTest = std::make_unique< QgsMapHitTest >( mSettings );
531
532 // TODO: do we need this temp image?
533 const QgsMapSettings &mapSettings = mSettings.mapSettings();
534
535 QImage tmpImage( mapSettings.outputSize(), mapSettings.outputImageFormat() );
536 tmpImage.setDotsPerMeterX( static_cast< int >( std::round( mapSettings.outputDpi() * 25.4 ) ) );
537 tmpImage.setDotsPerMeterY( static_cast< int >( std::round( mapSettings.outputDpi() * 25.4 ) ) );
538 QPainter painter( &tmpImage );
539
541
542 context.setPainter( &painter ); // we are not going to draw anything, but we still need a working painter
543
544 std::size_t layerIdx = 0;
545 const std::size_t totalCount = mPreparedData.size() + mPreparedRasterData.size() + mPreparedMeshData.size();
546
547 for ( auto &layerData : mPreparedData )
548 {
549 mFeedback->setProgress( static_cast< double >( layerIdx ) / static_cast< double >( totalCount ) * 100.0 );
550 if ( mFeedback->isCanceled() )
551 break;
552
553 QgsMapHitTest::SymbolSet &usedSymbols = hitTest->mHitTest[layerData.layerId];
554 QgsMapHitTest::SymbolSet &usedSymbolsRuleKey = hitTest->mHitTestRuleKey[layerData.layerId];
555
556 context.setCoordinateTransform( layerData.transform );
557 context.setExtent( layerData.extent.boundingBox() );
558
559 QgsExpressionContextScope *layerScope = layerData.layerScope.release();
560 QgsExpressionContextScopePopper scopePopper( context.expressionContext(), layerScope );
561
562 hitTest->runHitTestFeatureSource( layerData.source.get(), layerData.layerId, layerData.fields, layerData.renderer.get(), usedSymbols, usedSymbolsRuleKey, context, mFeedback.get(), layerData.extent );
563 layerIdx++;
564 }
565
566 layerIdx = 0;
567 for ( PreparedRasterData &rasterData : mPreparedRasterData )
568 {
569 rasterData.provider->moveToThread( QThread::currentThread() );
570
571 mFeedback->setProgress( ( static_cast<double>( mPreparedData.size() ) + static_cast< double >( layerIdx ) ) / static_cast< double >( totalCount ) * 100.0 );
572 if ( mFeedback->isCanceled() )
573 break;
574
575 context.setCoordinateTransform( rasterData.transform );
576 context.setExtent( rasterData.extent.boundingBox() );
577
578 hitTest->runHitTestRasterSource( rasterData.provider.get(), rasterData.layerId, rasterData.band, rasterData.minMaxOrigin, rasterData.rangeLimit, context, mFeedback.get(), rasterData.extent );
579 layerIdx++;
580 }
581
582 layerIdx = 0;
583 for ( PreparedMeshData &meshData : mPreparedMeshData )
584 {
585 mFeedback->setProgress(
586 ( static_cast<double>( mPreparedData.size() ) + static_cast<double>( mPreparedRasterData.size() ) + static_cast< double >( layerIdx ) ) / static_cast< double >( totalCount ) * 100.0
587 );
588 if ( mFeedback->isCanceled() )
589 break;
590
591 context.setCoordinateTransform( meshData.transform );
592 context.setExtent( meshData.extent.boundingBox() );
593
594 meshData.layer->moveToThread( QThread::currentThread() );
595 meshData.layer->updateTriangularMesh();
596
597 hitTest->runHitTestMeshSource( meshData.layer.get(), meshData.layerId, meshData.datasetIndex, context, mFeedback.get(), meshData.extent );
598 layerIdx++;
599 }
600
601 mResults = hitTest->mHitTestRuleKey;
602
603 mResultsRenderersUpdatedCanvas = hitTest->mHitTestRenderersUpdatedCanvas;
604
605 mFeedback.reset();
606
607 // data moved to the task thread above need to explicitly emptied here
608 // otherwise destructors run in the main thread may comply
609 // raster data
610 mPreparedRasterData.clear();
611 //mesh data
612 mPreparedMeshData.clear();
613
614 return true;
615}
MeshRangeLimit
Describes the limits used to compute mesh ranges (min/max values).
Definition qgis.h:6406
@ MinimumMaximum
Real min-max values.
Definition qgis.h:6408
@ NotSet
User defined.
Definition qgis.h:6407
RasterRangeLimit
Describes the limits used to compute raster ranges (min/max values).
Definition qgis.h:1623
@ SkipVisibilityCheck
If set, the standard visibility check should be skipped.
Definition qgis.h:4680
@ ExactIntersect
Use exact geometry intersection (slower) instead of bounding boxes.
Definition qgis.h:2278
MeshRangeExtent
Describes the extent used to compute mesh ranges (min/max values).
Definition qgis.h:6418
@ UpdatedCanvas
Constantly updated extent of the canvas is used to compute statistics.
Definition qgis.h:6421
@ WholeMesh
Whole mesh is used to compute statistics.
Definition qgis.h:6419
@ FixedCanvas
Current extent of the canvas (at the time of computation) is used to compute statistics.
Definition qgis.h:6420
@ Polygon
Polygons.
Definition qgis.h:382
@ UpdatedCanvas
Constantly updated extent of the canvas is used to compute statistics.
Definition qgis.h:1642
@ WholeRaster
Whole raster is used to compute statistics.
Definition qgis.h:1640
@ FixedCanvas
Current extent of the canvas (at the time of computation) is used to compute statistics.
Definition qgis.h:1641
Base class that can be used for any class that is capable of returning features.
virtual QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest())=0
Gets an iterator for features matching the specified request.
RAII class to pop scope from an expression context on destruction.
Single scope for storing variables and functions for use within a QgsExpressionContext.
static QgsExpressionContextScope * layerScope(const QgsMapLayer *layer)
Creates a new scope which contains variables and functions relating to a QgsMapLayer.
void setFeature(const QgsFeature &feature)
Convenience function for setting a feature for the context.
bool nextFeature(QgsFeature &f)
Fetch next feature and stores in f, returns true on success.
Abstract base class for all 2D vector feature renderers.
@ MoreSymbolsPerFeature
May use more than one symbol to render a feature: symbolsForFeature() will return them.
virtual QgsFeatureRenderer * clone() const =0
Create a deep copy of this renderer.
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.
void setFeedback(QgsFeedback *feedback)
Attach a feedback object that can be queried regularly by the iterator to check if it should be cance...
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.
QgsGeometry geometry
Definition qgsfeature.h:71
bool hasGeometry() const
Returns true if the feature has an associated geometry.
Base class for feedback objects to be used for cancellation of something running in a worker thread.
Definition qgsfeedback.h:44
bool isCanceled() const
Tells whether the operation has been canceled already.
Definition qgsfeedback.h:56
void progressChanged(double progress)
Emitted when the feedback object reports a progress change.
Container of fields for a vector layer.
Definition qgsfields.h:46
A geometry is the spatial representation of a feature.
const QgsAbstractGeometry * constGet() const
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
Qgis::GeometryType type
QgsRectangle boundingBox() const
Returns the bounding box of the geometry.
static QgsGeometryEngine * createGeometryEngine(const QgsAbstractGeometry *geometry, double precision=0.0, Qgis::GeosCreationFlags flags=Qgis::GeosCreationFlag::SkipEmptyInteriorRings)
Creates and returns a new geometry engine representing the specified geometry using precision on a gr...
Contains settings relating to filtering the contents of QgsLayerTreeModel and views.
QMap< QString, QSet< QString > > results() const
Returns the hit test results, which are a map of layer ID to visible symbol legend keys.
QgsMapHitTestTask(const QgsLayerTreeFilterSettings &settings)
Constructor for QgsMapHitTestTask, using the specified filter settings.
bool run() override
Performs the task's operation.
PRIVATE void cancel() override
Notifies the task that it should terminate.
void run()
Runs the map hit test.
bool symbolVisible(QgsSymbol *symbol, QgsVectorLayer *layer) const
Tests whether a symbol is visible for a specified layer.
bool legendKeyVisible(const QString &ruleKey, QgsVectorLayer *layer) const
Tests whether a given legend key is visible for a specified layer.
QgsMapHitTest(const QgsMapSettings &settings, const QgsGeometry &polygon=QgsGeometry(), const QgsMapHitTest::LayerFilterExpression &layerFilterExpression=QgsMapHitTest::LayerFilterExpression())
Constructor for QgsMapHitTest.
QMap< QString, QSet< QString > > results() const
Returns the hit test results, which are a map of layer ID to visible symbol legend keys.
QMap< QString, QString > LayerFilterExpression
Maps an expression string to a layer id.
Restore overridden layer style on destruction.
void setOverrideStyle(const QString &style)
Temporarily apply a different style to the layer.
Base class for all map layer types.
Definition qgsmaplayer.h:83
bool isInScaleRange(double scale) const
Tests whether the layer should be visible at the specified scale.
QString id
Definition qgsmaplayer.h:86
Contains configuration for rendering maps.
double scale() const
Returns the calculated map scale.
QgsCoordinateTransform layerTransform(const QgsMapLayer *layer) const
Returns the coordinate transform from layer's CRS to destination CRS.
QSize outputSize() const
Returns the size of the resulting map image, in pixels.
QImage::Format outputImageFormat() const
format of internal QImage, default QImage::Format_ARGB32_Premultiplied
double outputDpi() const
Returns the DPI (dots per inch) used for conversion between real world units (e.g.
QMap< QString, QString > layerStyleOverrides() const
Returns the map of map layer style overrides (key: layer ID, value: style name) where a different sty...
An index that identifies the dataset group (e.g.
bool isValid() const
Returns whether index is valid, ie at least groups is set.
int group() const
Returns a group index.
int dataset() const
Returns a dataset index within group().
Represents a mesh layer supporting display of data on structured or unstructured meshes.
QgsMeshRendererSettings rendererSettings() const
Returns renderer settings.
bool minimumMaximumActiveScalarDataset(const QgsRectangle &extent, const QgsMeshDatasetIndex &datasetIndex, double &min, double &max)
Extracts minimum and maximum value for active scalar dataset on mesh faces.
Represents a mesh renderer settings for scalar datasets.
Qgis::MeshRangeExtent extent() const
Returns the mesh extent for minimum maximum calculation.
Qgis::MeshRangeLimit limits() const
Returns the range limits type for minimum maximum calculation.
QgsMeshRendererScalarSettings scalarSettings(int groupIndex) const
Returns renderer settings.
Base class for raster data providers.
QgsRectangle extent() const override=0
Returns the extent of the layer.
static void computeMinMax(QgsRasterDataProvider *provider, int band, const QgsRasterMinMaxOrigin &mmo, Qgis::RasterRangeLimit limits, const QgsRectangle &extent, int sampleSize, double &min, double &max)
Compute the min max values for provider along band according to MinMaxOrigin parameters mmo and exten...
Represents a raster layer.
static const double SAMPLE_SIZE
Default sample size (number of pixels) for estimated statistics/histogram calculation.
Describes the origin of minimum and maximum values in a raster.
Qgis::RasterRangeExtent extent() const
Returns the raster extent.
Qgis::RasterRangeLimit limits() const
Returns the raster limits.
bool intersects(const QgsRectangle &rect) const
Returns true when rectangle intersects with other rectangle.
Contains information about the context of a rendering operation.
void setCoordinateTransform(const QgsCoordinateTransform &t)
Sets the current coordinate transform for the context.
QgsExpressionContext & expressionContext()
Gets the expression context.
const QgsRectangle & extent() const
When rendering a map layer, calling this method returns the "clipping" extent for the layer (in the l...
void setExtent(const QgsRectangle &extent)
When rendering a map layer, calling this method sets the "clipping" extent for the layer (in the laye...
void setPainter(QPainter *p)
Sets the destination QPainter for the render operation.
static QgsRenderContext fromMapSettings(const QgsMapSettings &mapSettings)
create initialized QgsRenderContext instance from given QgsMapSettings
static QString symbolProperties(QgsSymbol *symbol)
Returns a string representing the symbol.
Abstract base class for all rendered symbols.
Definition qgssymbol.h:227
void progressChanged(double progress)
Will be emitted by task when its progress changes.
virtual void cancel()
Notifies the task that it should terminate.
QgsTask(const QString &description=QString(), QgsTask::Flags flags=AllFlags)
Constructor for QgsTask.
Flag
Task flags.
@ CanCancel
Task can be canceled.
@ CancelWithoutPrompt
Task can be canceled without any users prompts, e.g. when closing a project or QGIS.
@ Silent
Don't show task updates (such as completion/failure messages) as operating-system level notifications...
Represents a vector layer which manages a vector based dataset.
QList< QgsSymbol * > QgsSymbolList
Definition qgsrenderer.h:51