Skip to content

Commit

Permalink
[tracer] improved reporting of warnings
Browse files Browse the repository at this point in the history
  • Loading branch information
wonder-sk committed Jan 11, 2016
1 parent 2c414ce commit e7d277f
Show file tree
Hide file tree
Showing 7 changed files with 100 additions and 41 deletions.
4 changes: 1 addition & 3 deletions src/app/qgisapp.cpp
Expand Up @@ -1974,10 +1974,8 @@ void QgisApp::createToolBars()
// Cad toolbar
mAdvancedDigitizeToolBar->insertAction( mActionUndo, mAdvancedDigitizingDockWidget->enableAction() );

mTracer = new QgsMapCanvasTracer( mMapCanvas );
mTracer = new QgsMapCanvasTracer( mMapCanvas, messageBar() );
mAdvancedDigitizeToolBar->insertAction( mActionUndo, mTracer->actionEnableTracing() );
connect( mTracer, SIGNAL( messageEmitted( QString, QgsMessageBar::MessageLevel ) ),
this, SLOT( displayMapToolMessage( QString, QgsMessageBar::MessageLevel ) ) );
}

void QgisApp::createStatusBar()
Expand Down
25 changes: 21 additions & 4 deletions src/core/qgstracer.cpp
Expand Up @@ -486,14 +486,14 @@ bool QgsTracer::initGraph()
}

extract_linework( f.geometry(), mpl );

++featuresCounted;
if ( mMaxFeatureCount != 0 && featuresCounted >= mMaxFeatureCount )
return false;
}
}
int timeExtract = t1.elapsed();

if ( mMaxFeatureCount != 0 && featuresCounted >= mMaxFeatureCount )
return false;

// resolve intersections

t2.start();
Expand Down Expand Up @@ -611,18 +611,32 @@ void QgsTracer::onGeometryChanged( QgsFeatureId fid, QgsGeometry& geom )
invalidateGraph();
}

QVector<QgsPoint> QgsTracer::findShortestPath( const QgsPoint& p1, const QgsPoint& p2 )
QVector<QgsPoint> QgsTracer::findShortestPath(const QgsPoint& p1, const QgsPoint& p2, PathError* error )
{
init(); // does nothing if the graph exists already
if ( !mGraph )
{
if ( error ) *error = ErrTooManyFeatures;
return QVector<QgsPoint>();
}

QTime t;
t.start();
int v1 = point_in_graph( *mGraph, p1 );
int v2 = point_in_graph( *mGraph, p2 );
int tPrep = t.elapsed();

if ( v1 == -1 )
{
if ( error ) *error = ErrPoint1;
return QVector<QgsPoint>();
}
if ( v2 == -1 )
{
if ( error ) *error = ErrPoint2;
return QVector<QgsPoint>();
}

QTime t2;
t2.start();
QgsPolyline points = shortest_path( *mGraph, v1, v2 );
Expand All @@ -632,6 +646,9 @@ QVector<QgsPoint> QgsTracer::findShortestPath( const QgsPoint& p1, const QgsPoin

reset_graph( *mGraph );

if ( error )
*error = points.isEmpty() ? ErrNoPath : ErrNone;

return points;
}

Expand Down
11 changes: 10 additions & 1 deletion src/core/qgstracer.h
Expand Up @@ -68,11 +68,20 @@ class CORE_EXPORT QgsTracer : public QObject
//! if necessary.
virtual bool init();

enum PathError
{
ErrNone,
ErrTooManyFeatures,
ErrPoint1,
ErrPoint2,
ErrNoPath,
};

//! Given two points, find the shortest path and return points on the way.
//! If the points are not located on existing vertices or edges,
//! search will fail and return empty array. The search will also fail
//! if the two points are not connected.
QVector<QgsPoint> findShortestPath( const QgsPoint& p1, const QgsPoint& p2 );
QVector<QgsPoint> findShortestPath( const QgsPoint& p1, const QgsPoint& p2, PathError* error = 0 );

//! Find out whether the point is snapped to a vertex or edge (i.e. it can be used for tracing start/stop)
bool isPointSnapped( const QgsPoint& pt );
Expand Down
50 changes: 44 additions & 6 deletions src/gui/qgsmapcanvastracer.cpp
Expand Up @@ -4,6 +4,7 @@
#include "qgsmapcanvas.h"
#include "qgsmaplayerregistry.h"
#include "qgsmessagebar.h"
#include "qgsmessagebaritem.h"
#include "qgssnappingutils.h"
#include "qgsvectorlayer.h"

Expand All @@ -12,8 +13,10 @@
QHash<QgsMapCanvas*, QgsMapCanvasTracer*> QgsMapCanvasTracer::sTracers;


QgsMapCanvasTracer::QgsMapCanvasTracer( QgsMapCanvas* canvas )
QgsMapCanvasTracer::QgsMapCanvasTracer( QgsMapCanvas* canvas, QgsMessageBar* messageBar )
: mCanvas( canvas )
, mMessageBar( messageBar )
, mLastMessage( nullptr )
{
sTracers.insert( canvas, this );

Expand All @@ -29,7 +32,7 @@ QgsMapCanvasTracer::QgsMapCanvasTracer( QgsMapCanvas* canvas )

// arbitrarily chosen limit that should allow for fairly fast initialization
// of the underlying graph structure
setMaxFeatureCount( 10000 );
setMaxFeatureCount( QSettings().value( "/qgis/digitizing/tracing_max_feature_count", 10000 ).toInt() );

updateSettings(); // initialize
updateLayerSettings();
Expand All @@ -43,10 +46,6 @@ QgsMapCanvasTracer::~QgsMapCanvasTracer()
bool QgsMapCanvasTracer::init()
{
bool res = QgsTracer::init();

if ( !res )
emit messageEmitted( tr( "Tracing disabled because there are too many features displayed. Try zooming in or disable some layers." ) );

return res;
}

Expand All @@ -55,6 +54,45 @@ QgsMapCanvasTracer* QgsMapCanvasTracer::tracerForCanvas( QgsMapCanvas* canvas )
return sTracers.value( canvas, 0 );
}

void QgsMapCanvasTracer::reportError( QgsTracer::PathError err, bool addingVertex )
{
if ( !mMessageBar )
return;

// remove previous message (if any)
mMessageBar->popWidget( mLastMessage );
mLastMessage = nullptr;

QString message;
switch ( err )
{
case ErrTooManyFeatures:
message = tr( "Disabled - there are too many features displayed. Try zooming in or disable some layers." );
break;
case ErrPoint1:
message = tr( "The start point needs to be snapped and in the visible map view" );
break;
case ErrPoint2:
if ( addingVertex )
message = tr( "The end point needs to be snapped" );
break;
case ErrNoPath:
if ( addingVertex )
message = tr( "Endpoints are not connected" );
break;
case ErrNone:
default:
break;
}

if ( message.isEmpty() )
return;

mLastMessage = new QgsMessageBarItem( tr( "Tracing" ), message, QgsMessageBar::WARNING,
QSettings().value( "/qgis/messageTimeout", 5 ).toInt() );
mMessageBar->pushItem( mLastMessage );
}

void QgsMapCanvasTracer::updateSettings()
{
setDestinationCrs( mCanvas->mapSettings().destinationCrs() );
Expand Down
15 changes: 7 additions & 8 deletions src/gui/qgsmapcanvastracer.h
@@ -1,18 +1,19 @@
#ifndef QGSMAPCANVASTRACER_H
#define QGSMAPCANVASTRACER_H

#include "qgsmessagebar.h"
#include "qgstracer.h"

class QAction;
class QgsMapCanvas;
class QgsMessageBar;
class QgsMessageBarItem;

class GUI_EXPORT QgsMapCanvasTracer : public QgsTracer
{
Q_OBJECT

public:
explicit QgsMapCanvasTracer( QgsMapCanvas* canvas );
explicit QgsMapCanvasTracer( QgsMapCanvas* canvas, QgsMessageBar* messageBar = 0 );
~QgsMapCanvasTracer();

QAction* actionEnableTracing() { return mActionEnableTracing; }
Expand All @@ -24,12 +25,8 @@ class GUI_EXPORT QgsMapCanvasTracer : public QgsTracer
//! instances for easier access to the common tracer by various map tools
static QgsMapCanvasTracer* tracerForCanvas( QgsMapCanvas* canvas );

signals:
//! emit a message
void messageEmitted( const QString& message, QgsMessageBar::MessageLevel = QgsMessageBar::INFO );

//! emit signal to clear previous message
//void messageDiscarded();
//! Report a path finding error to the user
void reportError( PathError err, bool addingVertex );

private slots:
void updateSettings();
Expand All @@ -38,6 +35,8 @@ class GUI_EXPORT QgsMapCanvasTracer : public QgsTracer

private:
QgsMapCanvas* mCanvas;
QgsMessageBar* mMessageBar;
QgsMessageBarItem* mLastMessage;

QAction* mActionEnableTracing;

Expand Down
34 changes: 16 additions & 18 deletions src/gui/qgsmaptoolcapture.cpp
Expand Up @@ -174,14 +174,15 @@ void QgsMapToolCapture::tracingMouseMove( QgsMapMouseEvent* e )
if ( !tracer )
return; // this should not happen!

if ( !tracer->init() ) // normally no-op if the graph is built already
return; // graph would be too big

mTempRubberBand->reset( mCaptureMode == CapturePolygon ? QGis::Polygon : QGis::Line );

QVector<QgsPoint> points = tracer->findShortestPath( pt0, e->mapPoint() );
QgsTracer::PathError err;
QVector<QgsPoint> points = tracer->findShortestPath( pt0, e->mapPoint(), &err );
if ( points.isEmpty() )
{
tracer->reportError( err, false );
return;
}

if ( mCaptureMode == CapturePolygon )
mTempRubberBand->addPoint( *mRubberBand->getPoint( 0, 0 ), false );
Expand All @@ -192,19 +193,20 @@ void QgsMapToolCapture::tracingMouseMove( QgsMapMouseEvent* e )
}


bool QgsMapToolCapture::tracingAddVertex( const QgsPoint& point, bool& pathNotFound )
bool QgsMapToolCapture::tracingAddVertex( const QgsPoint& point )
{
pathNotFound = false;

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

if ( !tracer->init() ) // normally no-op if the graph is built already
return false; // graph would be too big

if ( mCaptureCurve.numPoints() == 0 )
{
if ( !tracer->init() )
{
tracer->reportError( QgsTracer::ErrTooManyFeatures, true );
return false;
}

// only accept first point if it is snapped to the graph (to vertex or edge)
bool res = tracer->isPointSnapped( point );
if ( res )
Expand All @@ -222,10 +224,11 @@ bool QgsMapToolCapture::tracingAddVertex( const QgsPoint& point, bool& pathNotFo
if ( pt0 == QgsPoint() )
return false;

QVector<QgsPoint> points = tracer->findShortestPath( pt0, point );
QgsTracer::PathError err;
QVector<QgsPoint> points = tracer->findShortestPath( pt0, point, &err );
if ( points.isEmpty() )
{
pathNotFound = true;
tracer->reportError( err, true );
return false; // ignore the vertex - can't find path to the end point!
}

Expand Down Expand Up @@ -369,14 +372,9 @@ int QgsMapToolCapture::addVertex( const QgsPoint& point )

if ( tracingEnabled() )
{
bool pathNotFound;
bool res = tracingAddVertex( point, pathNotFound );
bool res = tracingAddVertex( point );
if ( !res )
{
if ( pathNotFound )
emit messageEmitted( tr( "Tracing: The point needs to be snapped to a geometry" ), QgsMessageBar::WARNING );
return 1; // early exit if the point cannot be accepted
}
}
else
{
Expand Down
2 changes: 1 addition & 1 deletion src/gui/qgsmaptoolcapture.h
Expand Up @@ -148,7 +148,7 @@ class GUI_EXPORT QgsMapToolCapture : public QgsMapToolAdvancedDigitizing
//! 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
bool tracingAddVertex( const QgsPoint& point, bool& pathNotFound );
bool tracingAddVertex( const QgsPoint& point );

private:
/** Flag to indicate a map canvas capture operation is taking place */
Expand Down

0 comments on commit e7d277f

Please sign in to comment.