QGIS API Documentation  3.20.0-Odense (decaadbb31)
qgsmapcanvastracer.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsmapcanvastracer.cpp
3  ---------------------
4  begin : January 2016
5  copyright : (C) 2016 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 #include "qgsmapcanvastracer.h"
16 
17 #include "qgsapplication.h"
18 #include "qgsmapcanvas.h"
19 #include "qgsproject.h"
20 #include "qgsmessagebar.h"
21 #include "qgsmessagebaritem.h"
22 #include "qgssnappingutils.h"
23 #include "qgsvectorlayer.h"
24 #include "qgssnappingconfig.h"
25 #include "qgssettingsregistrycore.h"
26 
27 #include <QAction>
28 
29 #include <QGlobalStatic>
30 
31 typedef QHash<QgsMapCanvas *, QgsMapCanvasTracer *> TracerCanvasHash;
33 
35  : mCanvas( canvas )
36  , mMessageBar( messageBar )
37 
38 {
39  sTracers()->insert( canvas, this );
40 
41  // when things change we just invalidate the graph - and set up new parameters again only when necessary
46  connect( canvas, &QgsMapCanvas::currentLayerChanged, this, &QgsMapCanvasTracer::onCurrentLayerChanged );
48  connect( canvas, &QObject::destroyed, this, [this]() { mCanvas = nullptr; } );
49 
50  // arbitrarily chosen limit that should allow for fairly fast initialization
51  // of the underlying graph structure
52  setMaxFeatureCount( QgsSettingsRegistryCore::settingsDigitizingTracingMaxFeatureCount.value() );
53 }
54 
56 {
57  sTracers->remove( mCanvas );
58 }
59 
61 {
62  return sTracers->value( canvas, nullptr );
63 }
64 
66 {
67  Q_UNUSED( addingVertex )
68 
69  if ( !mMessageBar )
70  return;
71 
72  // remove previous message (if any)
73  mMessageBar->popWidget( mLastMessage );
74  mLastMessage = nullptr;
75 
76  QString message;
77  switch ( err )
78  {
79  case ErrTooManyFeatures:
80  message = tr( "Disabled - there are too many features displayed. Try zooming in or disable some layers." );
81  break;
82  case ErrNone:
83  default:
84  break;
85  }
86 
87  if ( message.isEmpty() && hasTopologyProblem() )
88  {
89  message = tr( "Tracing may not work correctly. Please check topology of the input layers." );
90  }
91 
92  if ( message.isEmpty() )
93  return;
94 
95  mLastMessage = new QgsMessageBarItem( tr( "Tracing" ), message, Qgis::MessageLevel::Warning, QgsMessageBar::defaultMessageTimeout( Qgis::MessageLevel::Info ) );
96  mMessageBar->pushItem( mLastMessage );
97 }
98 
100 {
103  setRenderContext( &ctx );
104  setExtent( mCanvas->extent() );
105 
106  QList<QgsVectorLayer *> layers;
107  QList<QgsMapLayer *> visibleLayers = mCanvas->mapSettings().layers();
108 
109  switch ( mCanvas->snappingUtils()->config().mode() )
110  {
111  default:
113  {
114  QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( mCanvas->currentLayer() );
115  if ( vl && visibleLayers.contains( vl ) )
116  layers << vl;
117  }
118  break;
120  {
121  const auto constVisibleLayers = visibleLayers;
122  for ( QgsMapLayer *layer : constVisibleLayers )
123  {
124  QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( layer );
125  if ( vl )
126  layers << vl;
127  }
128  }
129  break;
131  {
132  const auto constLayers = mCanvas->snappingUtils()->layers();
133  for ( const QgsSnappingUtils::LayerConfig &cfg : constLayers )
134  {
135  if ( visibleLayers.contains( cfg.layer ) )
136  layers << cfg.layer;
137  }
138  }
139  break;
140  }
141 
142  setLayers( layers );
143 }
144 
145 void QgsMapCanvasTracer::onCurrentLayerChanged()
146 {
147  // no need to bother if we are not snapping
148  if ( mCanvas->snappingUtils()->config().mode() == QgsSnappingConfig::ActiveLayer )
149  invalidateGraph();
150 }
Extension of QgsTracer that provides extra functionality:
QgsMapCanvasTracer(QgsMapCanvas *canvas, QgsMessageBar *messageBar=nullptr)
Create tracer associated with a particular map canvas, optionally message bar for reporting.
void reportError(PathError err, bool addingVertex)
Report a path finding error to the user.
static QgsMapCanvasTracer * tracerForCanvas(QgsMapCanvas *canvas)
Retrieve instance of this class associated with given canvas (if any).
void configure() override
Sets configuration from current snapping settings and canvas settings.
Map canvas is a class for displaying all GIS data types on a canvas.
Definition: qgsmapcanvas.h:86
void extentsChanged()
Emitted when the extents of the map change.
void currentLayerChanged(QgsMapLayer *layer)
Emitted when the current layer is changed.
QgsSnappingUtils * snappingUtils() const
Returns snapping utility class that is associated with map canvas.
void destinationCrsChanged()
Emitted when map CRS has changed.
void transformContextChanged()
Emitted when the canvas transform context is changed.
void layersChanged()
Emitted when a new set of layers has been received.
const QgsMapSettings & mapSettings() const
Gets access to properties used for map rendering.
QgsRectangle extent() const
Returns the current zoom extent of the map canvas.
QgsMapLayer * currentLayer()
returns current layer (set by legend widget)
Base class for all map layer types.
Definition: qgsmaplayer.h:70
QList< QgsMapLayer * > layers() const
Returns the list of layers which will be rendered in the map.
QgsCoordinateReferenceSystem destinationCrs() const
Returns the destination coordinate reference system for the map render.
QgsCoordinateTransformContext transformContext() const
Returns the coordinate transform context, which stores various information regarding which datum tran...
Represents an item shown within a QgsMessageBar widget.
A bar for displaying non-blocking messages to the user.
Definition: qgsmessagebar.h:61
static int defaultMessageTimeout(Qgis::MessageLevel level=Qgis::MessageLevel::NoLevel)
Returns the default timeout in seconds for timed messages of the specified level.
bool popWidget(QgsMessageBarItem *item)
Remove the specified item from the bar, and display the next most recent one in the stack.
void pushItem(QgsMessageBarItem *item)
Display a message item on the bar, after hiding the currently visible one and putting it in a stack.
Contains information about the context of a rendering operation.
static QgsRenderContext fromMapSettings(const QgsMapSettings &mapSettings)
create initialized QgsRenderContext instance from given QgsMapSettings
@ ActiveLayer
On the active layer.
@ AdvancedConfiguration
On a per layer configuration basis.
@ AllLayers
On all vector layers.
SnappingMode mode() const
Returns the mode (all layers, active layer, per layer settings)
QList< QgsSnappingUtils::LayerConfig > layers() const
Query layers used for snapping.
void configChanged(const QgsSnappingConfig &snappingConfig)
Emitted when the snapping settings object changes.
QgsSnappingConfig config
void setMaxFeatureCount(int count)
Gets maximum possible number of features in graph. If the number is exceeded, graph is not created.
Definition: qgstracer.h:111
void setRenderContext(const QgsRenderContext *renderContext)
Sets the renderContext used for tracing only on visible features.
Definition: qgstracer.cpp:640
bool hasTopologyProblem() const
Whether there was an error during graph creation due to noding exception, indicating some input data ...
Definition: qgstracer.h:129
void setExtent(const QgsRectangle &extent)
Sets extent to which graph's features will be limited (empty extent means no limit)
Definition: qgstracer.cpp:646
PathError
Possible errors that may happen when calling findShortestPath()
Definition: qgstracer.h:133
@ ErrNone
No error.
Definition: qgstracer.h:134
@ ErrTooManyFeatures
Max feature count threshold was reached while reading features.
Definition: qgstracer.h:135
void setLayers(const QList< QgsVectorLayer * > &layers)
Sets layers used for tracing.
Definition: qgstracer.cpp:601
QList< QgsVectorLayer * > layers() const
Gets layers used for tracing.
Definition: qgstracer.h:55
void invalidateGraph()
Destroy the existing graph structure if any (de-initialize)
Definition: qgstracer.cpp:686
void setDestinationCrs(const QgsCoordinateReferenceSystem &crs, const QgsCoordinateTransformContext &context)
Sets the crs and transform context used for tracing.
Definition: qgstracer.cpp:633
Represents a vector layer which manages a vector based data sets.
QHash< QgsMapCanvas *, QgsMapCanvasTracer * > TracerCanvasHash
Q_GLOBAL_STATIC(TracerCanvasHash, sTracers)
Configures how a certain layer should be handled in a snapping operation.