Skip to content

Commit f18bc52

Browse files
committedSep 24, 2018
Fixes #18902 Snapping and tracing inconsistent behaviour
1 parent 6286cf1 commit f18bc52

File tree

4 files changed

+85
-6
lines changed

4 files changed

+85
-6
lines changed
 

‎python/core/auto_generated/qgstracer.sip.in

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,16 @@ Returns the CRS used for tracing.
4848
.. seealso:: :py:func:`setDestinationCrs`
4949
%End
5050

51-
void setDestinationCrs( const QgsCoordinateReferenceSystem &crs, const QgsCoordinateTransformContext &context );
51+
void setDestinationCrs( const QgsCoordinateReferenceSystem &crs, const QgsCoordinateTransformContext &transform );
5252
%Docstring
5353
Sets the ``crs`` and transform ``context`` used for tracing.
5454

5555
.. seealso:: :py:func:`destinationCrs`
56+
%End
57+
58+
void setRenderContext( const QgsRenderContext *render );
59+
%Docstring
60+
Sets the ``render`` context used for tracing only on visible features.
5661
%End
5762

5863
QgsRectangle extent() const;

‎src/core/qgstracer.cpp

Lines changed: 65 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "qgslogger.h"
2424
#include "qgsvectorlayer.h"
2525
#include "qgsexception.h"
26+
#include "qgsrenderer.h"
2627

2728
#include <queue>
2829
#include <vector>
@@ -458,7 +459,8 @@ QgsTracer::QgsTracer() = default;
458459
bool QgsTracer::initGraph()
459460
{
460461
if ( mGraph )
461-
return true; // already initialized
462+
return true;
463+
// already initialized
462464

463465
mHasTopologyProblem = false;
464466

@@ -476,7 +478,28 @@ bool QgsTracer::initGraph()
476478
for ( QgsVectorLayer *vl : qgis::as_const( mLayers ) )
477479
{
478480
QgsFeatureRequest request;
479-
request.setSubsetOfAttributes( QgsAttributeList() );
481+
482+
bool filter = false;
483+
std::unique_ptr< QgsFeatureRenderer > renderer( vl->renderer() ? vl->renderer()->clone() : nullptr );
484+
QgsRenderContext *ctx = nullptr;
485+
if ( mRenderContext )
486+
{
487+
mRenderContext->expressionContext() << QgsExpressionContextUtils::layerScope( vl );
488+
ctx = mRenderContext.get();
489+
if ( renderer )
490+
{
491+
// setup scale for scale dependent visibility (rule based)
492+
renderer->startRender( *ctx, vl->fields() );
493+
filter = renderer->capabilities() & QgsFeatureRenderer::Filter;
494+
request.setSubsetOfAttributes( renderer->usedAttributes( *ctx ), vl->fields() );
495+
}
496+
}
497+
else
498+
{
499+
request.setSubsetOfAttributes( QgsAttributeList() );
500+
501+
}
502+
480503
request.setDestinationCrs( mCRS, mTransformContext );
481504
if ( !mExtent.isEmpty() )
482505
request.setFilterRect( mExtent );
@@ -487,12 +510,26 @@ bool QgsTracer::initGraph()
487510
if ( !f.hasGeometry() )
488511
continue;
489512

513+
if ( filter && ctx && renderer )
514+
{
515+
ctx->expressionContext().setFeature( f );
516+
if ( !renderer->willRenderFeature( f, *ctx ) )
517+
{
518+
continue;
519+
}
520+
}
521+
490522
extractLinework( f.geometry(), mpl );
491523

492524
++featuresCounted;
493525
if ( mMaxFeatureCount != 0 && featuresCounted >= mMaxFeatureCount )
494526
return false;
495527
}
528+
529+
if ( ctx && renderer )
530+
{
531+
renderer->stopRender( *ctx );
532+
}
496533
}
497534
int timeExtract = t1.elapsed();
498535

@@ -544,6 +581,7 @@ bool QgsTracer::initGraph()
544581
Q_UNUSED( timeMake );
545582
QgsDebugMsg( QString( "tracer extract %1 ms, noding %2 ms (call %3 ms), make %4 ms" )
546583
.arg( timeExtract ).arg( timeNoding ).arg( timeNodingCall ).arg( timeMake ) );
584+
547585
return true;
548586
}
549587

@@ -562,6 +600,8 @@ void QgsTracer::setLayers( const QList<QgsVectorLayer *> &layers )
562600
disconnect( layer, &QgsVectorLayer::featureAdded, this, &QgsTracer::onFeatureAdded );
563601
disconnect( layer, &QgsVectorLayer::featureDeleted, this, &QgsTracer::onFeatureDeleted );
564602
disconnect( layer, &QgsVectorLayer::geometryChanged, this, &QgsTracer::onGeometryChanged );
603+
disconnect( layer, &QgsVectorLayer::attributeValueChanged, this, &QgsTracer::onAttributeValueChanged );
604+
disconnect( layer, &QgsVectorLayer::dataChanged, this, &QgsTracer::onDataChanged );
565605
disconnect( layer, &QObject::destroyed, this, &QgsTracer::onLayerDestroyed );
566606
}
567607

@@ -572,16 +612,24 @@ void QgsTracer::setLayers( const QList<QgsVectorLayer *> &layers )
572612
connect( layer, &QgsVectorLayer::featureAdded, this, &QgsTracer::onFeatureAdded );
573613
connect( layer, &QgsVectorLayer::featureDeleted, this, &QgsTracer::onFeatureDeleted );
574614
connect( layer, &QgsVectorLayer::geometryChanged, this, &QgsTracer::onGeometryChanged );
615+
connect( layer, &QgsVectorLayer::attributeValueChanged, this, &QgsTracer::onAttributeValueChanged );
616+
connect( layer, &QgsVectorLayer::dataChanged, this, &QgsTracer::onDataChanged );
575617
connect( layer, &QObject::destroyed, this, &QgsTracer::onLayerDestroyed );
576618
}
577619

578620
invalidateGraph();
579621
}
580622

581-
void QgsTracer::setDestinationCrs( const QgsCoordinateReferenceSystem &crs, const QgsCoordinateTransformContext &context )
623+
void QgsTracer::setDestinationCrs( const QgsCoordinateReferenceSystem &crs, const QgsCoordinateTransformContext &transform )
582624
{
583625
mCRS = crs;
584-
mTransformContext = context;
626+
mTransformContext = transform;
627+
invalidateGraph();
628+
}
629+
630+
void QgsTracer::setRenderContext( const QgsRenderContext *render )
631+
{
632+
mRenderContext = std::unique_ptr<QgsRenderContext>( new QgsRenderContext( *render ) );
585633
invalidateGraph();
586634
}
587635

@@ -649,6 +697,19 @@ void QgsTracer::onGeometryChanged( QgsFeatureId fid, const QgsGeometry &geom )
649697
invalidateGraph();
650698
}
651699

700+
void QgsTracer::onAttributeValueChanged( QgsFeatureId fid, int idx, const QVariant &value )
701+
{
702+
Q_UNUSED( fid );
703+
Q_UNUSED( idx );
704+
Q_UNUSED( value );
705+
invalidateGraph();
706+
}
707+
708+
void QgsTracer::onDataChanged( )
709+
{
710+
invalidateGraph();
711+
}
712+
652713
void QgsTracer::onLayerDestroyed( QObject *obj )
653714
{
654715
// remove the layer before it is completely invalid (static_cast should be the safest cast)

‎src/core/qgstracer.h

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ class QgsVectorLayer;
2929
#include "qgsgeometry.h"
3030

3131
struct QgsTracerGraph;
32+
class QgsFeatureRenderer;
33+
class QgsRenderContext;
3234

3335
/**
3436
* \ingroup core
@@ -64,7 +66,12 @@ class CORE_EXPORT QgsTracer : public QObject
6466
* Sets the \a crs and transform \a context used for tracing.
6567
* \see destinationCrs()
6668
*/
67-
void setDestinationCrs( const QgsCoordinateReferenceSystem &crs, const QgsCoordinateTransformContext &context );
69+
void setDestinationCrs( const QgsCoordinateReferenceSystem &crs, const QgsCoordinateTransformContext &transform );
70+
71+
/**
72+
* Sets the \a render context used for tracing only on visible features.
73+
*/
74+
void setRenderContext( const QgsRenderContext *render );
6875

6976
//! Gets extent to which graph's features will be limited (empty extent means no limit)
7077
QgsRectangle extent() const { return mExtent; }
@@ -160,6 +167,8 @@ class CORE_EXPORT QgsTracer : public QObject
160167
void onFeatureAdded( QgsFeatureId fid );
161168
void onFeatureDeleted( QgsFeatureId fid );
162169
void onGeometryChanged( QgsFeatureId fid, const QgsGeometry &geom );
170+
void onAttributeValueChanged( QgsFeatureId fid, int idx, const QVariant &value );
171+
void onDataChanged( );
163172
void onLayerDestroyed( QObject *obj );
164173

165174
private:
@@ -171,6 +180,8 @@ class CORE_EXPORT QgsTracer : public QObject
171180
QgsCoordinateReferenceSystem mCRS;
172181
//! Coordinate transform context
173182
QgsCoordinateTransformContext mTransformContext;
183+
//! Render context
184+
std::unique_ptr<QgsRenderContext> mRenderContext;
174185
//! Extent for graph building (empty extent means no limit)
175186
QgsRectangle mExtent;
176187

‎src/gui/qgsmapcanvastracer.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,8 @@ void QgsMapCanvasTracer::reportError( QgsTracer::PathError err, bool addingVerte
9898
void QgsMapCanvasTracer::configure()
9999
{
100100
setDestinationCrs( mCanvas->mapSettings().destinationCrs(), mCanvas->mapSettings().transformContext() );
101+
QgsRenderContext ctx = QgsRenderContext::fromMapSettings( mCanvas->mapSettings() );
102+
setRenderContext( &ctx );
101103
setExtent( mCanvas->extent() );
102104

103105
QList<QgsVectorLayer *> layers;

0 commit comments

Comments
 (0)
Please sign in to comment.