QGIS API Documentation 3.99.0-Master (a8882ad4560)
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
52}
53
55{
56 const QgsMapSettings &mapSettings = mSettings.mapSettings();
57
58 // TODO: do we need this temp image?
59 QImage tmpImage( mapSettings.outputSize(), mapSettings.outputImageFormat() );
60 tmpImage.setDotsPerMeterX( static_cast< int >( std::round( mapSettings.outputDpi() * 25.4 ) ) );
61 tmpImage.setDotsPerMeterY( static_cast< int >( std::round( mapSettings.outputDpi() * 25.4 ) ) );
62 QPainter painter( &tmpImage );
63
65 context.setPainter( &painter ); // we are not going to draw anything, but we still need a working painter
66
67 const QList< QgsMapLayer * > layers = mSettings.layers();
68 for ( QgsMapLayer *layer : layers )
69 {
70
71 QgsGeometry extent;
72 if ( !( mSettings.flags() & Qgis::LayerTreeFilterFlag::SkipVisibilityCheck ) )
73 {
74 if ( !layer->isInScaleRange( mapSettings.scale() ) )
75 {
76 continue;
77 }
78
79 extent = mSettings.combinedVisibleExtentForLayer( layer );
80
81 context.setCoordinateTransform( mapSettings.layerTransform( layer ) );
82 context.setExtent( extent.boundingBox() );
83 }
84
85 if ( QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( layer ) )
86 {
87 if ( !vl->renderer() )
88 continue;
89
91 SymbolSet &usedSymbols = mHitTest[vl->id()];
92 SymbolSet &usedSymbolsRuleKey = mHitTestRuleKey[vl->id()];
93
94 QgsMapLayerStyleOverride styleOverride( vl );
95 if ( mapSettings.layerStyleOverrides().contains( vl->id() ) )
96 styleOverride.setOverrideStyle( mapSettings.layerStyleOverrides().value( vl->id() ) );
97
98 auto source = std::make_unique< QgsVectorLayerFeatureSource >( vl );
99 runHitTestFeatureSource( source.get(),
100 vl->id(), vl->fields(), vl->renderer(),
101 usedSymbols, usedSymbolsRuleKey, context,
102 nullptr, extent );
103 }
104 else if ( QgsRasterLayer *rl = qobject_cast<QgsRasterLayer *>( layer ) )
105 {
106 if ( !rl->renderer() || !rl->dataProvider() )
107 continue;
108
109 QgsRasterMinMaxOrigin minMaxOrigin = rl->renderer()->minMaxOrigin();
110
111 runHitTestRasterSource( rl->dataProvider(), rl->id(), rl->renderer()->inputBand(), minMaxOrigin, minMaxOrigin.limits(),
112 context, nullptr, extent );
113 }
114 else if ( QgsMeshLayer *ml = qobject_cast<QgsMeshLayer *>( layer ) )
115 {
116 QgsMeshDatasetIndex datasetIndex = ml->activeScalarDatasetIndex( context );
117 QgsMeshRendererScalarSettings scalarSettings = ml->rendererSettings().scalarSettings( datasetIndex.dataset() );
118
119 runHitTestMeshSource( ml, ml->id(), datasetIndex, context, nullptr, extent );
120 }
121 }
122
123 painter.end();
124}
125
126QMap<QString, QSet<QString> > QgsMapHitTest::results() const
127{
128 return mHitTestRuleKey;
129}
130
132QMap<QString, QList<QString> > QgsMapHitTest::resultsPy() const
133{
134 QMap<QString, QList<QString> > res;
135 for ( auto it = mHitTestRuleKey.begin(); it != mHitTestRuleKey.end(); ++it )
136 {
137 res.insert( it.key(), qgis::setToList( it.value() ) );
138 }
139 return res;
140}
142
144{
145 if ( !symbol || !layer )
146 return false;
147
148 auto it = mHitTest.constFind( layer->id() );
149 if ( it == mHitTest.constEnd() )
150 return false;
151
152 return it->contains( QgsSymbolLayerUtils::symbolProperties( symbol ) );
153}
154
155bool QgsMapHitTest::legendKeyVisible( const QString &ruleKey, QgsVectorLayer *layer ) const
156{
157 if ( !layer )
158 return false;
159
160 auto it = mHitTestRuleKey.constFind( layer->id() );
161 if ( it == mHitTestRuleKey.constEnd() )
162 return false;
163
164 return it->contains( ruleKey );
165}
166
167void QgsMapHitTest::runHitTestFeatureSource( QgsAbstractFeatureSource *source,
168 const QString &layerId,
169 const QgsFields &fields,
170 const QgsFeatureRenderer *renderer,
171 SymbolSet &usedSymbols,
172 SymbolSet &usedSymbolsRuleKey,
173 QgsRenderContext &context,
174 QgsFeedback *feedback,
175 const QgsGeometry &visibleExtent )
176{
177 std::unique_ptr< QgsFeatureRenderer > r( renderer->clone() );
178 const bool moreSymbolsPerFeature = r->capabilities() & QgsFeatureRenderer::MoreSymbolsPerFeature;
179 r->startRender( context, fields );
180
181 // shortcut early if we know that there's nothing visible
182 if ( r->canSkipRender() )
183 {
184 r->stopRender( context );
185 return;
186 }
187
188 // if there's no legend items for this layer, shortcut out early
189 QSet< QString > remainingKeysToFind = r->legendKeys();
190 if ( remainingKeysToFind.empty() )
191 {
192 r->stopRender( context );
193 return;
194 }
195
196 QgsFeatureRequest request;
197 if ( feedback )
198 request.setFeedback( feedback );
199
200 const QString rendererFilterExpression = r->filter( fields );
201 if ( !rendererFilterExpression.isEmpty() )
202 {
203 request.setFilterExpression( rendererFilterExpression );
204 }
205
206 request.setExpressionContext( context.expressionContext() );
207
208 QSet<QString> requiredAttributes = r->usedAttributes( context );
209
210 QgsGeometry transformedPolygon = visibleExtent;
211 if ( transformedPolygon.type() != Qgis::GeometryType::Polygon )
212 {
213 transformedPolygon = QgsGeometry();
214 }
215
216 if ( feedback && feedback->isCanceled() )
217 {
218 r->stopRender( context );
219 return;
220 }
221
222 const QMap<QString, QString> layerFilterExpressions = mSettings.layerFilterExpressions();
223 if ( auto it = layerFilterExpressions.constFind( layerId ); it != layerFilterExpressions.constEnd() )
224 {
225 const QString expression = *it;
226 QgsExpression expr( expression );
227 expr.prepare( &context.expressionContext() );
228
229 requiredAttributes.unite( expr.referencedColumns() );
230 request.combineFilterExpression( expression );
231 }
232
233 request.setSubsetOfAttributes( requiredAttributes, fields );
234
235 std::unique_ptr< QgsGeometryEngine > polygonEngine;
236 if ( !( mSettings.flags() & Qgis::LayerTreeFilterFlag::SkipVisibilityCheck ) )
237 {
238 if ( transformedPolygon.isNull() )
239 {
240 request.setFilterRect( context.extent() );
242 }
243 else
244 {
245 request.setFilterRect( transformedPolygon.boundingBox() );
246 polygonEngine.reset( QgsGeometry::createGeometryEngine( transformedPolygon.constGet() ) );
247 polygonEngine->prepareGeometry();
248 }
249 }
250
251 if ( feedback && feedback->isCanceled() )
252 {
253 r->stopRender( context );
254 return;
255 }
256
257 QgsFeatureIterator fi = source->getFeatures( request );
258
259 usedSymbols.clear();
260 usedSymbolsRuleKey.clear();
261
262 QgsFeature f;
263 while ( fi.nextFeature( f ) )
264 {
265 if ( feedback && feedback->isCanceled() )
266 break;
267
268 // filter out elements outside of the polygon
269 if ( f.hasGeometry() && polygonEngine )
270 {
271 if ( !polygonEngine->intersects( f.geometry().constGet() ) )
272 {
273 continue;
274 }
275 }
276
277 context.expressionContext().setFeature( f );
278
279 //make sure we store string representation of symbol, not pointer
280 //otherwise layer style override changes will delete original symbols and leave hanging pointers
281 const QSet< QString > legendKeysForFeature = r->legendKeysForFeature( f, context );
282 for ( const QString &legendKey : legendKeysForFeature )
283 {
284 usedSymbolsRuleKey.insert( legendKey );
285 remainingKeysToFind.remove( legendKey );
286 }
287
288 if ( moreSymbolsPerFeature )
289 {
290 const QgsSymbolList originalSymbolsForFeature = r->originalSymbolsForFeature( f, context );
291 for ( QgsSymbol *s : originalSymbolsForFeature )
292 {
293 if ( s )
294 usedSymbols.insert( QgsSymbolLayerUtils::symbolProperties( s ) );
295 }
296 }
297 else
298 {
299 QgsSymbol *s = r->originalSymbolForFeature( f, context );
300 if ( s )
301 usedSymbols.insert( QgsSymbolLayerUtils::symbolProperties( s ) );
302 }
303
304 if ( remainingKeysToFind.empty() )
305 {
306 // already found features for all legend items, no need to keep searching
307 break;
308 }
309 }
310 r->stopRender( context );
311}
312
313void QgsMapHitTest::runHitTestRasterSource( QgsRasterDataProvider *provider,
314 const QString &layerId,
315 const int band,
316 const QgsRasterMinMaxOrigin minMaxOrigin,
317 const Qgis::RasterRangeLimit rangeLimit,
318 const QgsRenderContext &context,
319 QgsFeedback *feedback,
320 const QgsGeometry &visibleExtent )
321{
322 if ( feedback && feedback->isCanceled() )
323 return;
324
325 QgsRectangle transformedExtent;
326 if ( visibleExtent.type() != Qgis::GeometryType::Polygon )
327 {
328 transformedExtent = context.extent();
329 }
330 else
331 {
332 transformedExtent = visibleExtent.boundingBox();
333 }
334
335 double min = std::numeric_limits<double>::quiet_NaN();
336 double max = std::numeric_limits<double>::quiet_NaN();
337 bool found = false;
338
339 switch ( minMaxOrigin.extent() )
340 {
342 {
343 if ( provider->extent().intersects( transformedExtent ) )
344 {
345 QgsRasterLayerUtils::computeMinMax( provider, band, minMaxOrigin, rangeLimit,
346 transformedExtent, static_cast<int>( QgsRasterLayer::SAMPLE_SIZE ), min, max );
347 found = true;
348 }
349 break;
350 }
353 break;
354 }
355
356 if ( found )
357 {
358 mHitTestRenderersUpdatedCanvas.insert( layerId, std::pair<double, double>( min, max ) );
359 }
360}
361
362void QgsMapHitTest::runHitTestMeshSource( QgsMeshLayer *layer,
363 const QString &layerId,
364 const QgsMeshDatasetIndex datasetIndex,
365 const QgsRenderContext &context,
366 QgsFeedback *feedback,
367 const QgsGeometry &visibleExtent )
368{
369 if ( feedback && feedback->isCanceled() )
370 return;
371
372 QgsRectangle transformedExtent;
373 if ( visibleExtent.type() != Qgis::GeometryType::Polygon )
374 {
375 transformedExtent = context.extent();
376 }
377 else
378 {
379 transformedExtent = visibleExtent.boundingBox();
380 }
381
382 Qgis::MeshRangeExtent rangeExtent = layer->rendererSettings().scalarSettings( datasetIndex.group() ).extent();
383 Qgis::MeshRangeLimit rangeLimit = layer->rendererSettings().scalarSettings( datasetIndex.group() ).limits();
384
385 double min = std::numeric_limits<double>::quiet_NaN();
386 double max = std::numeric_limits<double>::quiet_NaN();
387 bool found = false;
388
389 if ( datasetIndex.isValid() )
390 {
391 switch ( rangeExtent )
392 {
394 {
395 switch ( rangeLimit )
396 {
398 {
399 found = layer->minimumMaximumActiveScalarDataset( transformedExtent, datasetIndex, min, max );
400 break;
401 }
403 break;
404 }
405 break;
406 }
409 break;
410 }
411 }
412
413 if ( found )
414 {
415 mHitTestRenderersUpdatedCanvas.insert( layerId, std::pair<double, double>( min, max ) );
416 }
417}
418
419//
420// QgsMapHitTestTask
421//
422
424 : QgsTask( tr( "Updating Legend" ), QgsTask::Flag::CanCancel | QgsTask::Flag::CancelWithoutPrompt | QgsTask::Flag::Silent )
425 , mSettings( settings )
426{
427 prepare();
428}
429
430QMap<QString, QSet<QString> > QgsMapHitTestTask::results() const
431{
432 return mResults;
433}
434
436QMap<QString, QList<QString> > QgsMapHitTestTask::resultsPy() const
437{
438 QMap<QString, QList<QString> > res;
439 for ( auto it = mResults.begin(); it != mResults.end(); ++it )
440 {
441 res.insert( it.key(), qgis::setToList( it.value() ) );
442 }
443 return res;
444}
446
447void QgsMapHitTestTask::prepare()
448{
449 const QgsMapSettings &mapSettings = mSettings.mapSettings();
450
451 const QList< QgsMapLayer * > layers = mSettings.layers();
452
453 QgsRenderContext context = QgsRenderContext::fromMapSettings( mapSettings );
454
455 for ( QgsMapLayer *layer : layers )
456 {
457 QgsGeometry extent;
458 if ( !( mSettings.flags() & Qgis::LayerTreeFilterFlag::SkipVisibilityCheck ) )
459 {
460 if ( !layer->isInScaleRange( mapSettings.scale() ) )
461 {
462 continue;
463 }
464
465 extent = mSettings.combinedVisibleExtentForLayer( layer );
466 }
467
468 if ( QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( layer ) )
469 {
470 if ( !vl->renderer() )
471 continue;
472
473 QgsMapLayerStyleOverride styleOverride( vl );
474 if ( mapSettings.layerStyleOverrides().contains( vl->id() ) )
475 styleOverride.setOverrideStyle( mapSettings.layerStyleOverrides().value( vl->id() ) );
476
477 PreparedLayerData layerData;
478 layerData.source = std::make_unique< QgsVectorLayerFeatureSource >( vl );
479 layerData.layerId = vl->id();
480 layerData.fields = vl->fields();
481 layerData.renderer.reset( vl->renderer()->clone() );
482 layerData.transform = mapSettings.layerTransform( vl );
483 layerData.extent = extent;
484 layerData.layerScope.reset( QgsExpressionContextUtils::layerScope( vl ) );
485
486 mPreparedData.emplace_back( std::move( layerData ) );
487 }
488 else if ( QgsRasterLayer *rl = qobject_cast<QgsRasterLayer *>( layer ) )
489 {
490 if ( !rl->dataProvider() || !rl->renderer() )
491 continue;
492
493 QgsRasterMinMaxOrigin minMaxOrigin = rl->renderer()->minMaxOrigin();
494
495 PreparedRasterData rasterData;
496 rasterData.provider = std::unique_ptr< QgsRasterDataProvider >( rl->dataProvider()->clone() );
497 rasterData.provider->moveToThread( nullptr );
498
499 rasterData.layerId = rl->id();
500 rasterData.band = rl->renderer()->inputBand();
501 rasterData.minMaxOrigin = minMaxOrigin;
502 rasterData.rangeLimit = minMaxOrigin.limits();
503 rasterData.transform = mapSettings.layerTransform( rl );
504 rasterData.extent = extent;
505
506 mPreparedRasterData.emplace_back( std::move( rasterData ) );
507 }
508 else if ( QgsMeshLayer *ml = qobject_cast<QgsMeshLayer *>( layer ) )
509 {
510 PreparedMeshData meshData;
511 meshData.layer = std::unique_ptr< QgsMeshLayer >( ml->clone() );
512 meshData.layer->moveToThread( nullptr );
513
514 meshData.layerId = ml->id();
515 meshData.datasetIndex = ml->activeScalarDatasetIndex( context );
516 meshData.transform = mapSettings.layerTransform( ml );
517 meshData.extent = extent;
518
519 mPreparedMeshData.emplace_back( std::move( meshData ) );
520 }
521 }
522}
523
525{
526 if ( mFeedback )
527 mFeedback->cancel();
528
530}
531
533{
534 mFeedback = std::make_unique< QgsFeedback >();
535 connect( mFeedback.get(), &QgsFeedback::progressChanged, this, &QgsTask::progressChanged );
536
537 auto hitTest = std::make_unique< QgsMapHitTest >( mSettings );
538
539 // TODO: do we need this temp image?
540 const QgsMapSettings &mapSettings = mSettings.mapSettings();
541
542 QImage tmpImage( mapSettings.outputSize(), mapSettings.outputImageFormat() );
543 tmpImage.setDotsPerMeterX( static_cast< int >( std::round( mapSettings.outputDpi() * 25.4 ) ) );
544 tmpImage.setDotsPerMeterY( static_cast< int >( std::round( mapSettings.outputDpi() * 25.4 ) ) );
545 QPainter painter( &tmpImage );
546
548
549 context.setPainter( &painter ); // we are not going to draw anything, but we still need a working painter
550
551 std::size_t layerIdx = 0;
552 const std::size_t totalCount = mPreparedData.size() + mPreparedRasterData.size() + mPreparedMeshData.size();
553
554 for ( auto &layerData : mPreparedData )
555 {
556 mFeedback->setProgress( static_cast< double >( layerIdx ) / static_cast< double >( totalCount ) * 100.0 );
557 if ( mFeedback->isCanceled() )
558 break;
559
560 QgsMapHitTest::SymbolSet &usedSymbols = hitTest->mHitTest[layerData.layerId];
561 QgsMapHitTest::SymbolSet &usedSymbolsRuleKey = hitTest->mHitTestRuleKey[layerData.layerId];
562
563 context.setCoordinateTransform( layerData.transform );
564 context.setExtent( layerData.extent.boundingBox() );
565
566 QgsExpressionContextScope *layerScope = layerData.layerScope.release();
567 QgsExpressionContextScopePopper scopePopper( context.expressionContext(), layerScope );
568
569 hitTest->runHitTestFeatureSource( layerData.source.get(),
570 layerData.layerId,
571 layerData.fields,
572 layerData.renderer.get(),
573 usedSymbols,
574 usedSymbolsRuleKey,
575 context,
576 mFeedback.get(),
577 layerData.extent );
578 layerIdx++;
579 }
580
581 layerIdx = 0;
582 for ( PreparedRasterData &rasterData : mPreparedRasterData )
583 {
584 rasterData.provider->moveToThread( QThread:: currentThread() );
585
586 mFeedback->setProgress( ( static_cast<double>( mPreparedData.size() ) + static_cast< double >( layerIdx ) ) / static_cast< double >( totalCount ) * 100.0 );
587 if ( mFeedback->isCanceled() )
588 break;
589
590 context.setCoordinateTransform( rasterData.transform );
591 context.setExtent( rasterData.extent.boundingBox() );
592
593 hitTest->runHitTestRasterSource( rasterData.provider.get(),
594 rasterData.layerId,
595 rasterData.band,
596 rasterData.minMaxOrigin,
597 rasterData.rangeLimit,
598 context,
599 mFeedback.get(),
600 rasterData.extent );
601 layerIdx++;
602 }
603
604 layerIdx = 0;
605 for ( PreparedMeshData &meshData : mPreparedMeshData )
606 {
607 mFeedback->setProgress( ( static_cast<double>( mPreparedData.size() ) + static_cast<double>( mPreparedRasterData.size() ) + static_cast< double >( layerIdx ) ) / static_cast< double >( totalCount ) * 100.0 );
608 if ( mFeedback->isCanceled() )
609 break;
610
611 context.setCoordinateTransform( meshData.transform );
612 context.setExtent( meshData.extent.boundingBox() );
613
614 meshData.layer->moveToThread( QThread:: currentThread() );
615 meshData.layer->updateTriangularMesh();
616
617 hitTest->runHitTestMeshSource( meshData.layer.get(),
618 meshData.layerId,
619 meshData.datasetIndex,
620 context,
621 mFeedback.get(),
622 meshData.extent );
623 layerIdx++;
624 }
625
626 mResults = hitTest->mHitTestRuleKey;
627
628 mResultsRenderersUpdatedCanvas = hitTest->mHitTestRenderersUpdatedCanvas;
629
630 mFeedback.reset();
631
632 // data moved to the task thread above need to explicitly emptied here
633 // otherwise destructors run in the main thread may comply
634 // raster data
635 mPreparedRasterData.clear();
636 //mesh data
637 mPreparedMeshData.clear();
638
639 return true;
640}
641
MeshRangeLimit
Describes the limits used to compute mesh ranges (min/max values).
Definition qgis.h:6302
@ MinimumMaximum
Real min-max values.
Definition qgis.h:6304
@ NotSet
User defined.
Definition qgis.h:6303
RasterRangeLimit
Describes the limits used to compute raster ranges (min/max values).
Definition qgis.h:1590
@ SkipVisibilityCheck
If set, the standard visibility check should be skipped.
Definition qgis.h:4583
@ ExactIntersect
Use exact geometry intersection (slower) instead of bounding boxes.
Definition qgis.h:2244
MeshRangeExtent
Describes the extent used to compute mesh ranges (min/max values).
Definition qgis.h:6314
@ UpdatedCanvas
Constantly updated extent of the canvas is used to compute statistics.
Definition qgis.h:6317
@ WholeMesh
Whole mesh is used to compute statistics.
Definition qgis.h:6315
@ FixedCanvas
Current extent of the canvas (at the time of computation) is used to compute statistics.
Definition qgis.h:6316
@ Polygon
Polygons.
Definition qgis.h:368
@ UpdatedCanvas
Constantly updated extent of the canvas is used to compute statistics.
Definition qgis.h:1609
@ WholeRaster
Whole raster is used to compute statistics.
Definition qgis.h:1607
@ FixedCanvas
Current extent of the canvas (at the time of computation) is used to compute statistics.
Definition qgis.h:1608
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:69
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:55
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:80
bool isInScaleRange(double scale) const
Tests whether the layer should be visible at the specified scale.
QString id
Definition qgsmaplayer.h:83
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:231
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:49