29#include "moc_qgsmaphittest.cpp"
34 mSettings.setLayerFilterExpressions( layerFilterExpression );
35 mSettings.setFilterPolygon( polygon );
41 mSettings.setLayerFilterExpressions( layerFilterExpression );
46 : mSettings( settings )
57 tmpImage.setDotsPerMeterX(
static_cast< int >( std::round( mapSettings.
outputDpi() * 25.4 ) ) );
58 tmpImage.setDotsPerMeterY(
static_cast< int >( std::round( mapSettings.
outputDpi() * 25.4 ) ) );
59 QPainter painter( &tmpImage );
64 const QList< QgsMapLayer * > layers = mSettings.layers();
79 extent = mSettings.combinedVisibleExtentForLayer( vl );
86 SymbolSet &usedSymbols = mHitTest[vl->
id()];
87 SymbolSet &usedSymbolsRuleKey = mHitTestRuleKey[vl->
id()];
93 auto source = std::make_unique< QgsVectorLayerFeatureSource >( vl );
94 runHitTestFeatureSource( source.get(),
96 usedSymbols, usedSymbolsRuleKey, context,
105 return mHitTestRuleKey;
109QMap<QString, QList<QString> > QgsMapHitTest::resultsPy()
const
111 QMap<QString, QList<QString> > res;
112 for (
auto it = mHitTestRuleKey.begin(); it != mHitTestRuleKey.end(); ++it )
114 res.insert( it.key(), qgis::setToList( it.value() ) );
122 if ( !symbol || !layer )
125 auto it = mHitTest.constFind( layer->
id() );
126 if ( it == mHitTest.constEnd() )
137 auto it = mHitTestRuleKey.constFind( layer->
id() );
138 if ( it == mHitTestRuleKey.constEnd() )
141 return it->contains( ruleKey );
145 const QString &layerId,
148 SymbolSet &usedSymbols,
149 SymbolSet &usedSymbolsRuleKey,
154 std::unique_ptr< QgsFeatureRenderer > r( renderer->
clone() );
156 r->startRender( context, fields );
159 if ( r->canSkipRender() )
161 r->stopRender( context );
166 QSet< QString > remainingKeysToFind = r->legendKeys();
167 if ( remainingKeysToFind.empty() )
169 r->stopRender( context );
173 QgsFeatureRequest request;
177 const QString rendererFilterExpression = r->filter( fields );
178 if ( !rendererFilterExpression.isEmpty() )
185 QSet<QString> requiredAttributes = r->usedAttributes( context );
187 QgsGeometry transformedPolygon = visibleExtent;
190 transformedPolygon = QgsGeometry();
195 r->stopRender( context );
199 const QMap<QString, QString> layerFilterExpressions = mSettings.layerFilterExpressions();
200 if (
auto it = layerFilterExpressions.constFind( layerId ); it != layerFilterExpressions.constEnd() )
202 const QString expression = *it;
203 QgsExpression expr( expression );
206 requiredAttributes.unite( expr.referencedColumns() );
212 std::unique_ptr< QgsGeometryEngine > polygonEngine;
215 if ( transformedPolygon.
isNull() )
224 polygonEngine->prepareGeometry();
230 r->stopRender( context );
234 QgsFeatureIterator fi = source->
getFeatures( request );
237 usedSymbolsRuleKey.clear();
258 const QSet< QString > legendKeysForFeature = r->legendKeysForFeature( f, context );
259 for (
const QString &legendKey : legendKeysForFeature )
261 usedSymbolsRuleKey.insert( legendKey );
262 remainingKeysToFind.remove( legendKey );
265 if ( moreSymbolsPerFeature )
267 const QgsSymbolList originalSymbolsForFeature = r->originalSymbolsForFeature( f, context );
268 for ( QgsSymbol *s : originalSymbolsForFeature )
276 QgsSymbol *s = r->originalSymbolForFeature( f, context );
281 if ( remainingKeysToFind.empty() )
287 r->stopRender( context );
297 , mSettings( settings )
308QMap<QString, QList<QString> > QgsMapHitTestTask::resultsPy()
const
310 QMap<QString, QList<QString> > res;
311 for (
auto it = mResults.begin(); it != mResults.end(); ++it )
313 res.insert( it.key(), qgis::setToList( it.value() ) );
319void QgsMapHitTestTask::prepare()
321 const QgsMapSettings &mapSettings = mSettings.mapSettings();
323 const QList< QgsMapLayer * > layers = mSettings.layers();
324 for ( QgsMapLayer *layer : layers )
326 QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( layer );
330 QgsMapLayerStyleOverride styleOverride( vl );
342 extent = mSettings.combinedVisibleExtentForLayer( vl );
345 PreparedLayerData layerData;
346 layerData.source = std::make_unique< QgsVectorLayerFeatureSource >( vl );
347 layerData.layerId = vl->
id();
348 layerData.fields = vl->
fields();
351 layerData.extent = extent;
354 mPreparedData.emplace_back( std::move( layerData ) );
368 mFeedback = std::make_unique< QgsFeedback >();
371 auto hitTest = std::make_unique< QgsMapHitTest >( mSettings );
377 tmpImage.setDotsPerMeterX(
static_cast< int >( std::round( mapSettings.
outputDpi() * 25.4 ) ) );
378 tmpImage.setDotsPerMeterY(
static_cast< int >( std::round( mapSettings.
outputDpi() * 25.4 ) ) );
379 QPainter painter( &tmpImage );
385 std::size_t layerIdx = 0;
386 const std::size_t totalCount = mPreparedData.size();
387 for (
auto &layerData : mPreparedData )
389 mFeedback->setProgress(
static_cast< double >( layerIdx ) /
static_cast< double >( totalCount ) * 100.0 );
390 if ( mFeedback->isCanceled() )
393 QgsMapHitTest::SymbolSet &usedSymbols = hitTest->mHitTest[layerData.layerId];
394 QgsMapHitTest::SymbolSet &usedSymbolsRuleKey = hitTest->mHitTestRuleKey[layerData.layerId];
397 context.
setExtent( layerData.extent.boundingBox() );
402 hitTest->runHitTestFeatureSource( layerData.source.get(),
405 layerData.renderer.get(),
414 mResults = hitTest->mHitTestRuleKey;
@ SkipVisibilityCheck
If set, the standard visibility check should be skipped.
@ ExactIntersect
Use exact geometry intersection (slower) instead of bounding boxes.
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.
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.
bool isCanceled() const
Tells whether the operation has been canceled already.
void progressChanged(double progress)
Emitted when the feedback object reports a progress change.
Container of fields for a vector layer.
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.
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.
PRIVATE 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.
bool isInScaleRange(double scale) const
Tests whether the layer should be visible at the specified scale.
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...
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.
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.
@ 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.
QgsFeatureRenderer * renderer()
Returns the feature renderer used for rendering the features in the layer in 2D map views.
QList< QgsSymbol * > QgsSymbolList