Skip to content

Commit bbe3598

Browse files
committed
[tracer] Integration of tracing into GUI
Checking the new 'enable tracing' button will switch capture tools to tracing mode. Tracing can be turned on/off even while digitizing is in progress
1 parent 0cd9b68 commit bbe3598

10 files changed

+719
-3
lines changed

images/images.qrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -529,6 +529,7 @@
529529
<file>flags/zh.png</file>
530530
<file>icons/qgis-icon-16x16_xmas.png</file>
531531
<file>icons/qgis-icon-60x60_xmas.png</file>
532+
<file>themes/default/mActionTracing.png</file>
532533
</qresource>
533534
<qresource prefix="/images/tips">
534535
<file alias="symbol_levels.png">qgis_tips/symbol_levels.png</file>
1.14 KB
Loading

images/themes/default/mActionTracing.svg

Lines changed: 524 additions & 0 deletions
Loading

src/app/qgisapp.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,7 @@
164164
#include "qgslogger.h"
165165
#include "qgsmapcanvas.h"
166166
#include "qgsmapcanvassnappingutils.h"
167+
#include "qgsmapcanvastracer.h"
167168
#include "qgsmaplayer.h"
168169
#include "qgsmaplayerregistry.h"
169170
#include "qgsmaplayerstyleguiutils.h"
@@ -554,6 +555,7 @@ QgisApp::QgisApp( QSplashScreen *splash, bool restorePlugins, QWidget * parent,
554555
, mComposerManager( nullptr )
555556
, mpTileScaleWidget( nullptr )
556557
, mpGpsWidget( nullptr )
558+
, mTracer( nullptr )
557559
, mSnappingUtils( nullptr )
558560
, mProjectLastModified()
559561
, mWelcomePage( nullptr )
@@ -1020,6 +1022,7 @@ QgisApp::QgisApp()
10201022
, mMacrosWarn( nullptr )
10211023
, mUserInputDockWidget( nullptr )
10221024
, mVectorLayerTools( nullptr )
1025+
, mTracer( nullptr )
10231026
, mActionFilterLegend( nullptr )
10241027
, mLegendExpressionFilterButton( nullptr )
10251028
, mSnappingUtils( nullptr )
@@ -1098,6 +1101,8 @@ QgisApp::~QgisApp()
10981101

10991102
delete mComposerManager;
11001103

1104+
delete mTracer;
1105+
11011106
delete mVectorLayerTools;
11021107
delete mWelcomePage;
11031108

@@ -1968,6 +1973,9 @@ void QgisApp::createToolBars()
19681973

19691974
// Cad toolbar
19701975
mAdvancedDigitizeToolBar->insertAction( mActionUndo, mAdvancedDigitizingDockWidget->enableAction() );
1976+
1977+
mTracer = new QgsMapCanvasTracer( mMapCanvas );
1978+
mAdvancedDigitizeToolBar->insertAction( mActionUndo, mTracer->actionEnableTracing() );
19711979
}
19721980

19731981
void QgisApp::createStatusBar()
@@ -9626,6 +9634,7 @@ void QgisApp::activateDeactivateLayerRelatedActions( QgsMapLayer* layer )
96269634
mActionMergeFeatures->setEnabled( false );
96279635
mActionMergeFeatureAttributes->setEnabled( false );
96289636
mActionRotatePointSymbols->setEnabled( false );
9637+
mTracer->actionEnableTracing()->setEnabled( false );
96299638

96309639
mActionPinLabels->setEnabled( false );
96319640
mActionShowHideLabels->setEnabled( false );
@@ -9746,6 +9755,9 @@ void QgisApp::activateDeactivateLayerRelatedActions( QgsMapLayer* layer )
97469755
mActionRotateFeature->setEnabled( isEditable && canChangeGeometry );
97479756
mActionNodeTool->setEnabled( isEditable && canChangeGeometry );
97489757

9758+
mTracer->actionEnableTracing()->setEnabled( isEditable && canAddFeatures &&
9759+
( vlayer->geometryType() == QGis::Line || vlayer->geometryType() == QGis::Polygon ) );
9760+
97499761
if ( vlayer->geometryType() == QGis::Point )
97509762
{
97519763
mActionAddFeature->setIcon( QgsApplication::getThemeIcon( "/mActionCapturePoint.svg" ) );

src/app/qgisapp.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ class QgsAdvancedDigitizingDockWidget;
8181
class QgsSnappingDialog;
8282
class QgsGPSInformationWidget;
8383
class QgsStatisticalSummaryDockWidget;
84+
class QgsMapCanvasTracer;
8485

8586
class QgsDecorationItem;
8687

@@ -1690,6 +1691,9 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
16901691

16911692
QgsVectorLayerTools* mVectorLayerTools;
16921693

1694+
//! A class that facilitates tracing of features
1695+
QgsMapCanvasTracer* mTracer;
1696+
16931697
QAction* mActionFilterLegend;
16941698

16951699
QgsLegendFilterButton* mLegendExpressionFilterButton;

src/gui/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,7 @@ SET(QGIS_GUI_SRCS
212212
qgsmapcanvasmap.cpp
213213
qgsmapcanvassnapper.cpp
214214
qgsmapcanvassnappingutils.cpp
215+
qgsmapcanvastracer.cpp
215216
qgsmaplayeractionregistry.cpp
216217
qgsmaplayercombobox.cpp
217218
qgsmaplayermodel.cpp
@@ -344,6 +345,7 @@ SET(QGIS_GUI_MOC_HDRS
344345
qgsmanageconnectionsdialog.h
345346
qgsmapcanvas.h
346347
qgsmapcanvassnappingutils.h
348+
qgsmapcanvastracer.h
347349
qgsmaplayeractionregistry.h
348350
qgsmaplayercombobox.h
349351
qgsmaplayermodel.h
@@ -557,6 +559,7 @@ SET(QGIS_GUI_HDRS
557559
qgsmapcanvasmap.h
558560
qgsmapcanvassnapper.h
559561
qgsmapcanvassnappingutils.h
562+
qgsmapcanvastracer.h
560563
qgsmaptip.h
561564
qgsmapmouseevent.h
562565
qgsnumericsortlistviewitem.h

src/gui/qgsmapcanvastracer.cpp

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
#include "qgsmapcanvastracer.h"
2+
3+
#include "qgsapplication.h"
4+
#include "qgsmapcanvas.h"
5+
#include "qgsmaplayerregistry.h"
6+
#include "qgsvectorlayer.h"
7+
8+
#include <QAction>
9+
10+
QHash<QgsMapCanvas*, QgsMapCanvasTracer*> QgsMapCanvasTracer::sTracers;
11+
12+
13+
QgsMapCanvasTracer::QgsMapCanvasTracer( QgsMapCanvas* canvas )
14+
: mCanvas( canvas )
15+
{
16+
sTracers.insert( canvas, this );
17+
18+
connect( canvas, SIGNAL( destinationCrsChanged() ), this, SLOT( updateSettings() ) );
19+
connect( canvas, SIGNAL( layersChanged() ), this, SLOT( updateSettings() ) );
20+
// TODO: watch for snapping changes
21+
22+
mActionEnableTracing = new QAction( QIcon( QgsApplication::getThemeIcon( "/mActionTracing.png" ) ), tr( "Enable Tracing" ), this );
23+
mActionEnableTracing->setShortcut( Qt::Key_T );
24+
mActionEnableTracing->setCheckable( true );
25+
26+
updateSettings(); // initialize
27+
}
28+
29+
QgsMapCanvasTracer::~QgsMapCanvasTracer()
30+
{
31+
sTracers.remove( mCanvas );
32+
}
33+
34+
QgsMapCanvasTracer* QgsMapCanvasTracer::tracerForCanvas( QgsMapCanvas* canvas )
35+
{
36+
return sTracers.value( canvas, 0 );
37+
}
38+
39+
void QgsMapCanvasTracer::updateSettings()
40+
{
41+
QList<QgsVectorLayer*> layers;
42+
foreach ( const QString& layerId, mCanvas->mapSettings().layers() )
43+
{
44+
QgsVectorLayer* vl = qobject_cast<QgsVectorLayer*>( QgsMapLayerRegistry::instance()->mapLayer( layerId ) );
45+
if ( vl )
46+
layers << vl;
47+
}
48+
setLayers( layers );
49+
50+
setDestinationCrs( mCanvas->mapSettings().destinationCrs() );
51+
}

src/gui/qgsmapcanvastracer.h

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#ifndef QGSMAPCANVASTRACER_H
2+
#define QGSMAPCANVASTRACER_H
3+
4+
#include "qgstracer.h"
5+
6+
class QAction;
7+
class QgsMapCanvas;
8+
9+
class GUI_EXPORT QgsMapCanvasTracer : public QgsTracer
10+
{
11+
Q_OBJECT
12+
13+
public:
14+
explicit QgsMapCanvasTracer( QgsMapCanvas* canvas );
15+
~QgsMapCanvasTracer();
16+
17+
QAction* actionEnableTracing() { return mActionEnableTracing; }
18+
19+
//! Retrieve instance of this class associated with given canvas (if any).
20+
//! The class keeps a simple registry of tracers associated with map canvas
21+
//! instances for easier access to the common tracer by various map tools
22+
static QgsMapCanvasTracer* tracerForCanvas( QgsMapCanvas* canvas );
23+
24+
private slots:
25+
void updateSettings();
26+
27+
private:
28+
QgsMapCanvas* mCanvas;
29+
30+
QAction* mActionEnableTracing;
31+
32+
static QHash<QgsMapCanvas*, QgsMapCanvasTracer*> sTracers;
33+
};
34+
35+
#endif // QGSMAPCANVASTRACER_H

src/gui/qgsmaptoolcapture.cpp

Lines changed: 81 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "qgslinestringv2.h"
2222
#include "qgslogger.h"
2323
#include "qgsmapcanvas.h"
24+
#include "qgsmapcanvastracer.h"
2425
#include "qgsmapmouseevent.h"
2526
#include "qgsmaprenderer.h"
2627
#include "qgspolygonv2.h"
@@ -134,6 +135,63 @@ void QgsMapToolCapture::currentLayerChanged( QgsMapLayer *layer )
134135
}
135136
}
136137

138+
139+
bool QgsMapToolCapture::tracingEnabled()
140+
{
141+
QgsMapCanvasTracer* tracer = QgsMapCanvasTracer::tracerForCanvas( mCanvas );
142+
return tracer && tracer->actionEnableTracing()->isChecked();
143+
}
144+
145+
146+
void QgsMapToolCapture::tracingMouseMove( QgsMapMouseEvent* e )
147+
{
148+
if ( !e->isSnapped() )
149+
return;
150+
151+
QgsPointV2 v;
152+
QgsVertexId::VertexType vt;
153+
mCaptureCurve.pointAt( mCaptureCurve.numPoints() - 1, v, vt );
154+
155+
QgsMapCanvasTracer* tracer = QgsMapCanvasTracer::tracerForCanvas( mCanvas );
156+
if ( !tracer )
157+
return; // this should not happen!
158+
159+
QVector<QgsPoint> points = tracer->findShortestPath( QgsPoint( v.x(), v.y() ), e->mapPoint() );
160+
if ( points.isEmpty() )
161+
return;
162+
163+
// update rubberband
164+
mTempRubberBand->reset( mCaptureMode == CapturePolygon ? QGis::Polygon : QGis::Line );
165+
for ( int i = 0; i < points.count(); ++i )
166+
mTempRubberBand->addPoint( points.at( i ), i == points.count() - 1 );
167+
}
168+
169+
170+
void QgsMapToolCapture::tracingAddVertex( const QgsPoint& point )
171+
{
172+
QgsMapCanvasTracer* tracer = QgsMapCanvasTracer::tracerForCanvas( mCanvas );
173+
if ( !tracer )
174+
return; // this should not happen!
175+
176+
QgsPointV2 v;
177+
QgsVertexId::VertexType vt;
178+
mCaptureCurve.pointAt( mCaptureCurve.numPoints() - 1, v, vt );
179+
180+
QVector<QgsPoint> points = tracer->findShortestPath( QgsPoint( v.x(), v.y() ), point );
181+
if ( points.isEmpty() )
182+
return; // ignore the vertex - can't find path to the end point!
183+
184+
QgsPoint lp; // in layer coords
185+
for ( int i = 1; i < points.count(); ++i )
186+
{
187+
if ( nextPoint( points[i], lp ) != 0 )
188+
continue; // TODO: should completely abort
189+
mRubberBand->addPoint( points[i], i == points.count() - 1 );
190+
mCaptureCurve.addVertex( QgsPointV2( lp.x(), lp.y() ) );
191+
}
192+
}
193+
194+
137195
void QgsMapToolCapture::cadCanvasMoveEvent( QgsMapMouseEvent * e )
138196
{
139197
QgsMapToolAdvancedDigitizing::cadCanvasMoveEvent( e );
@@ -165,9 +223,17 @@ void QgsMapToolCapture::cadCanvasMoveEvent( QgsMapMouseEvent * e )
165223
mTempRubberBand->addPoint( point );
166224
}
167225

226+
168227
if ( mCaptureMode != CapturePoint && mTempRubberBand && mCapturing )
169228
{
170-
mTempRubberBand->movePoint( point );
229+
if ( tracingEnabled() && mCaptureCurve.numPoints() != 0 )
230+
{
231+
tracingMouseMove( e );
232+
}
233+
else
234+
{
235+
mTempRubberBand->movePoint( point );
236+
}
171237
}
172238
} // mouseMoveEvent
173239

@@ -220,8 +286,19 @@ int QgsMapToolCapture::addVertex( const QgsPoint& point )
220286
{
221287
mRubberBand = createRubberBand( mCaptureMode == CapturePolygon ? QGis::Polygon : QGis::Line );
222288
}
223-
mRubberBand->addPoint( point );
224-
mCaptureCurve.addVertex( QgsPointV2( layerPoint.x(), layerPoint.y() ) );
289+
290+
if ( tracingEnabled() && mCaptureCurve.numPoints() != 0 )
291+
{
292+
tracingAddVertex( point );
293+
}
294+
else
295+
{
296+
// ordinary digitizing
297+
mRubberBand->addPoint( point );
298+
mCaptureCurve.addVertex( QgsPointV2( layerPoint.x(), layerPoint.y() ) );
299+
}
300+
301+
// re-initialize temporary rubber band for further digitizing
225302

226303
if ( !mTempRubberBand )
227304
{
@@ -231,6 +308,7 @@ int QgsMapToolCapture::addVertex( const QgsPoint& point )
231308
{
232309
mTempRubberBand->reset( mCaptureMode == CapturePolygon ? QGis::Polygon : QGis::Line );
233310
}
311+
234312
if ( mCaptureMode == CaptureLine )
235313
{
236314
mTempRubberBand->addPoint( point );

src/gui/qgsmaptoolcapture.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,14 @@ class GUI_EXPORT QgsMapToolCapture : public QgsMapToolAdvancedDigitizing
140140
*/
141141
void closePolygon();
142142

143+
private:
144+
//! whether tracing has been requested by the user
145+
bool tracingEnabled();
146+
//! handle of mouse movement when tracing enabled and capturing has started
147+
void tracingMouseMove( QgsMapMouseEvent* e );
148+
//! handle of addition of clicked point (with the rest of the trace) when tracing enabled
149+
void tracingAddVertex( const QgsPoint& point );
150+
143151
private:
144152
/** Flag to indicate a map canvas capture operation is taking place */
145153
bool mCapturing;

0 commit comments

Comments
 (0)