Skip to content
Permalink
Browse files

[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
  • Loading branch information
wonder-sk committed Jan 10, 2016
1 parent 0cd9b68 commit bbe359867ac24ff4e0e6d09fe29f4143bd2be821
@@ -529,6 +529,7 @@
<file>flags/zh.png</file>
<file>icons/qgis-icon-16x16_xmas.png</file>
<file>icons/qgis-icon-60x60_xmas.png</file>
<file>themes/default/mActionTracing.png</file>
</qresource>
<qresource prefix="/images/tips">
<file alias="symbol_levels.png">qgis_tips/symbol_levels.png</file>
Binary file not shown.

Large diffs are not rendered by default.

@@ -164,6 +164,7 @@
#include "qgslogger.h"
#include "qgsmapcanvas.h"
#include "qgsmapcanvassnappingutils.h"
#include "qgsmapcanvastracer.h"
#include "qgsmaplayer.h"
#include "qgsmaplayerregistry.h"
#include "qgsmaplayerstyleguiutils.h"
@@ -554,6 +555,7 @@ QgisApp::QgisApp( QSplashScreen *splash, bool restorePlugins, QWidget * parent,
, mComposerManager( nullptr )
, mpTileScaleWidget( nullptr )
, mpGpsWidget( nullptr )
, mTracer( nullptr )
, mSnappingUtils( nullptr )
, mProjectLastModified()
, mWelcomePage( nullptr )
@@ -1020,6 +1022,7 @@ QgisApp::QgisApp()
, mMacrosWarn( nullptr )
, mUserInputDockWidget( nullptr )
, mVectorLayerTools( nullptr )
, mTracer( nullptr )
, mActionFilterLegend( nullptr )
, mLegendExpressionFilterButton( nullptr )
, mSnappingUtils( nullptr )
@@ -1098,6 +1101,8 @@ QgisApp::~QgisApp()

delete mComposerManager;

delete mTracer;

delete mVectorLayerTools;
delete mWelcomePage;

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

// Cad toolbar
mAdvancedDigitizeToolBar->insertAction( mActionUndo, mAdvancedDigitizingDockWidget->enableAction() );

mTracer = new QgsMapCanvasTracer( mMapCanvas );
mAdvancedDigitizeToolBar->insertAction( mActionUndo, mTracer->actionEnableTracing() );
}

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

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

mTracer->actionEnableTracing()->setEnabled( isEditable && canAddFeatures &&
( vlayer->geometryType() == QGis::Line || vlayer->geometryType() == QGis::Polygon ) );

if ( vlayer->geometryType() == QGis::Point )
{
mActionAddFeature->setIcon( QgsApplication::getThemeIcon( "/mActionCapturePoint.svg" ) );
@@ -81,6 +81,7 @@ class QgsAdvancedDigitizingDockWidget;
class QgsSnappingDialog;
class QgsGPSInformationWidget;
class QgsStatisticalSummaryDockWidget;
class QgsMapCanvasTracer;

class QgsDecorationItem;

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

QgsVectorLayerTools* mVectorLayerTools;

//! A class that facilitates tracing of features
QgsMapCanvasTracer* mTracer;

QAction* mActionFilterLegend;

QgsLegendFilterButton* mLegendExpressionFilterButton;
@@ -212,6 +212,7 @@ SET(QGIS_GUI_SRCS
qgsmapcanvasmap.cpp
qgsmapcanvassnapper.cpp
qgsmapcanvassnappingutils.cpp
qgsmapcanvastracer.cpp
qgsmaplayeractionregistry.cpp
qgsmaplayercombobox.cpp
qgsmaplayermodel.cpp
@@ -344,6 +345,7 @@ SET(QGIS_GUI_MOC_HDRS
qgsmanageconnectionsdialog.h
qgsmapcanvas.h
qgsmapcanvassnappingutils.h
qgsmapcanvastracer.h
qgsmaplayeractionregistry.h
qgsmaplayercombobox.h
qgsmaplayermodel.h
@@ -557,6 +559,7 @@ SET(QGIS_GUI_HDRS
qgsmapcanvasmap.h
qgsmapcanvassnapper.h
qgsmapcanvassnappingutils.h
qgsmapcanvastracer.h
qgsmaptip.h
qgsmapmouseevent.h
qgsnumericsortlistviewitem.h
@@ -0,0 +1,51 @@
#include "qgsmapcanvastracer.h"

#include "qgsapplication.h"
#include "qgsmapcanvas.h"
#include "qgsmaplayerregistry.h"
#include "qgsvectorlayer.h"

#include <QAction>

QHash<QgsMapCanvas*, QgsMapCanvasTracer*> QgsMapCanvasTracer::sTracers;


QgsMapCanvasTracer::QgsMapCanvasTracer( QgsMapCanvas* canvas )
: mCanvas( canvas )
{
sTracers.insert( canvas, this );

connect( canvas, SIGNAL( destinationCrsChanged() ), this, SLOT( updateSettings() ) );
connect( canvas, SIGNAL( layersChanged() ), this, SLOT( updateSettings() ) );
// TODO: watch for snapping changes

mActionEnableTracing = new QAction( QIcon( QgsApplication::getThemeIcon( "/mActionTracing.png" ) ), tr( "Enable Tracing" ), this );
mActionEnableTracing->setShortcut( Qt::Key_T );
mActionEnableTracing->setCheckable( true );

updateSettings(); // initialize
}

QgsMapCanvasTracer::~QgsMapCanvasTracer()
{
sTracers.remove( mCanvas );
}

QgsMapCanvasTracer* QgsMapCanvasTracer::tracerForCanvas( QgsMapCanvas* canvas )
{
return sTracers.value( canvas, 0 );
}

void QgsMapCanvasTracer::updateSettings()
{
QList<QgsVectorLayer*> layers;
foreach ( const QString& layerId, mCanvas->mapSettings().layers() )
{
QgsVectorLayer* vl = qobject_cast<QgsVectorLayer*>( QgsMapLayerRegistry::instance()->mapLayer( layerId ) );
if ( vl )
layers << vl;
}
setLayers( layers );

setDestinationCrs( mCanvas->mapSettings().destinationCrs() );
}
@@ -0,0 +1,35 @@
#ifndef QGSMAPCANVASTRACER_H
#define QGSMAPCANVASTRACER_H

#include "qgstracer.h"

class QAction;
class QgsMapCanvas;

class GUI_EXPORT QgsMapCanvasTracer : public QgsTracer
{
Q_OBJECT

public:
explicit QgsMapCanvasTracer( QgsMapCanvas* canvas );
~QgsMapCanvasTracer();

QAction* actionEnableTracing() { return mActionEnableTracing; }

//! Retrieve instance of this class associated with given canvas (if any).
//! The class keeps a simple registry of tracers associated with map canvas
//! instances for easier access to the common tracer by various map tools
static QgsMapCanvasTracer* tracerForCanvas( QgsMapCanvas* canvas );

private slots:
void updateSettings();

private:
QgsMapCanvas* mCanvas;

QAction* mActionEnableTracing;

static QHash<QgsMapCanvas*, QgsMapCanvasTracer*> sTracers;
};

#endif // QGSMAPCANVASTRACER_H
@@ -21,6 +21,7 @@
#include "qgslinestringv2.h"
#include "qgslogger.h"
#include "qgsmapcanvas.h"
#include "qgsmapcanvastracer.h"
#include "qgsmapmouseevent.h"
#include "qgsmaprenderer.h"
#include "qgspolygonv2.h"
@@ -134,6 +135,63 @@ void QgsMapToolCapture::currentLayerChanged( QgsMapLayer *layer )
}
}


bool QgsMapToolCapture::tracingEnabled()
{
QgsMapCanvasTracer* tracer = QgsMapCanvasTracer::tracerForCanvas( mCanvas );
return tracer && tracer->actionEnableTracing()->isChecked();
}


void QgsMapToolCapture::tracingMouseMove( QgsMapMouseEvent* e )
{
if ( !e->isSnapped() )
return;

QgsPointV2 v;
QgsVertexId::VertexType vt;
mCaptureCurve.pointAt( mCaptureCurve.numPoints() - 1, v, vt );

QgsMapCanvasTracer* tracer = QgsMapCanvasTracer::tracerForCanvas( mCanvas );
if ( !tracer )
return; // this should not happen!

QVector<QgsPoint> points = tracer->findShortestPath( QgsPoint( v.x(), v.y() ), e->mapPoint() );
if ( points.isEmpty() )
return;

// update rubberband
mTempRubberBand->reset( mCaptureMode == CapturePolygon ? QGis::Polygon : QGis::Line );
for ( int i = 0; i < points.count(); ++i )
mTempRubberBand->addPoint( points.at( i ), i == points.count() - 1 );
}


void QgsMapToolCapture::tracingAddVertex( const QgsPoint& point )
{
QgsMapCanvasTracer* tracer = QgsMapCanvasTracer::tracerForCanvas( mCanvas );
if ( !tracer )
return; // this should not happen!

QgsPointV2 v;
QgsVertexId::VertexType vt;
mCaptureCurve.pointAt( mCaptureCurve.numPoints() - 1, v, vt );

QVector<QgsPoint> points = tracer->findShortestPath( QgsPoint( v.x(), v.y() ), point );
if ( points.isEmpty() )
return; // ignore the vertex - can't find path to the end point!

QgsPoint lp; // in layer coords
for ( int i = 1; i < points.count(); ++i )
{
if ( nextPoint( points[i], lp ) != 0 )
continue; // TODO: should completely abort
mRubberBand->addPoint( points[i], i == points.count() - 1 );
mCaptureCurve.addVertex( QgsPointV2( lp.x(), lp.y() ) );
}
}


void QgsMapToolCapture::cadCanvasMoveEvent( QgsMapMouseEvent * e )
{
QgsMapToolAdvancedDigitizing::cadCanvasMoveEvent( e );
@@ -165,9 +223,17 @@ void QgsMapToolCapture::cadCanvasMoveEvent( QgsMapMouseEvent * e )
mTempRubberBand->addPoint( point );
}


if ( mCaptureMode != CapturePoint && mTempRubberBand && mCapturing )
{
mTempRubberBand->movePoint( point );
if ( tracingEnabled() && mCaptureCurve.numPoints() != 0 )
{
tracingMouseMove( e );
}
else
{
mTempRubberBand->movePoint( point );
}
}
} // mouseMoveEvent

@@ -220,8 +286,19 @@ int QgsMapToolCapture::addVertex( const QgsPoint& point )
{
mRubberBand = createRubberBand( mCaptureMode == CapturePolygon ? QGis::Polygon : QGis::Line );
}
mRubberBand->addPoint( point );
mCaptureCurve.addVertex( QgsPointV2( layerPoint.x(), layerPoint.y() ) );

if ( tracingEnabled() && mCaptureCurve.numPoints() != 0 )
{
tracingAddVertex( point );
}
else
{
// ordinary digitizing
mRubberBand->addPoint( point );
mCaptureCurve.addVertex( QgsPointV2( layerPoint.x(), layerPoint.y() ) );
}

// re-initialize temporary rubber band for further digitizing

if ( !mTempRubberBand )
{
@@ -231,6 +308,7 @@ int QgsMapToolCapture::addVertex( const QgsPoint& point )
{
mTempRubberBand->reset( mCaptureMode == CapturePolygon ? QGis::Polygon : QGis::Line );
}

if ( mCaptureMode == CaptureLine )
{
mTempRubberBand->addPoint( point );
@@ -140,6 +140,14 @@ class GUI_EXPORT QgsMapToolCapture : public QgsMapToolAdvancedDigitizing
*/
void closePolygon();

private:
//! whether tracing has been requested by the user
bool tracingEnabled();
//! handle of mouse movement when tracing enabled and capturing has started
void tracingMouseMove( QgsMapMouseEvent* e );
//! handle of addition of clicked point (with the rest of the trace) when tracing enabled
void tracingAddVertex( const QgsPoint& point );

private:
/** Flag to indicate a map canvas capture operation is taking place */
bool mCapturing;

0 comments on commit bbe3598

Please sign in to comment.
You can’t perform that action at this time.