Skip to content

Commit

Permalink
fix #4523:
Browse files Browse the repository at this point in the history
- make geometry validation optional: none, QGIS and GEOS
- move internal validation to QgsGeometryValidator thread
- cache wkt in QgsCoordinateReferenceSystem
- fTools: leave progress of geometry validatation at 100%
- move coordinate capture to vector menu
  • Loading branch information
jef-n committed Jan 3, 2012
1 parent cc9864e commit e6167d2
Show file tree
Hide file tree
Showing 22 changed files with 700 additions and 425 deletions.
2 changes: 1 addition & 1 deletion python/plugins/fTools/tools/doValidate.py
Expand Up @@ -211,7 +211,7 @@ def run( self ):
self.running = True
output = self.check_geometry( self.vlayer )
self.emit( SIGNAL( "runFinished(PyQt_PyObject)" ), output )
self.emit( SIGNAL( "runStatus(PyQt_PyObject)" ), 0 )
self.emit( SIGNAL( "runStatus(PyQt_PyObject)" ), 100 )

def stop(self):
self.running = False
Expand Down
13 changes: 11 additions & 2 deletions src/app/main.cpp
Expand Up @@ -21,7 +21,6 @@
#include <QFile>
#include <QFileInfo>
#include <QFont>
#include <QMessageBox>
#include <QPixmap>
#include <QLocale>
#include <QSettings>
Expand All @@ -35,6 +34,7 @@

#include "qgscustomization.h"
#include "qgspluginregistry.h"
#include "qgsmessagelog.h"

#include <cstdio>
#include <stdio.h>
Expand Down Expand Up @@ -164,11 +164,20 @@ void myMessageOutput( QtMsgType type, const char *msg )
case QtWarningMsg:
fprintf( stderr, "Warning: %s\n", msg );

#ifdef QGISDEBUG
if ( 0 == strncmp( msg, "Object::", 8 )
|| 0 == strncmp( msg, "QWidget::", 9 )
|| 0 == strncmp( msg, "QPainter::", 10 ) )
{
QgsMessageLog::logMessage( msg, "Qt" );
}
#endif

// TODO: Verify this code in action.
if ( 0 == strncmp( msg, "libpng error:", 13 ) )
{
// Let the user know
QMessageBox::warning( 0, "libpng Error", msg );
QgsMessageLog::logMessage( msg, "libpng" );
}

break;
Expand Down
68 changes: 55 additions & 13 deletions src/app/qgsmaptoolcapture.cpp
Expand Up @@ -23,6 +23,7 @@
#include "qgsmaprenderer.h"
#include "qgsvectorlayer.h"
#include "qgslogger.h"
#include "qgsgeometryvalidator.h"

#include <QCursor>
#include <QPixmap>
Expand All @@ -35,6 +36,7 @@ QgsMapToolCapture::QgsMapToolCapture( QgsMapCanvas* canvas, enum CaptureMode too
: QgsMapToolEdit( canvas )
, mCaptureMode( tool )
, mRubberBand( 0 )
, mValidator( 0 )
{
mCaptureModeFromLayer = tool == CaptureNone;
mCapturing = false;
Expand All @@ -52,6 +54,12 @@ QgsMapToolCapture::~QgsMapToolCapture()
delete mSnappingMarkers.takeFirst();

stopCapturing();

if( mValidator )
{
mValidator->deleteLater();
mValidator = 0;
}
}

void QgsMapToolCapture::deactivate()
Expand Down Expand Up @@ -271,12 +279,25 @@ void QgsMapToolCapture::closePolygon()

void QgsMapToolCapture::validateGeometry()
{
QSettings settings;
if ( settings.value( "/qgis/digitizing/validate_geometries", 1 ).toInt() == 0 )
return;

if( mValidator )
{
mValidator->deleteLater();
mValidator = 0;
}

mTip = "";
mGeomErrors.clear();
while ( !mGeomErrorMarkers.isEmpty() )
{
delete mGeomErrorMarkers.takeFirst();
}

QgsGeometry *g;

switch ( mCaptureMode )
{
case CaptureNone:
Expand All @@ -285,38 +306,59 @@ void QgsMapToolCapture::validateGeometry()
case CaptureLine:
if ( mCaptureList.size() < 2 )
return;
QgsGeometry::validatePolyline( mGeomErrors, 0, mCaptureList.toVector() );
g = QgsGeometry::fromPolyline( mCaptureList.toVector() );
break;
case CapturePolygon:
if ( mCaptureList.size() < 3 )
return;
QgsGeometry::validatePolyline( mGeomErrors, 0, mCaptureList.toVector() << mCaptureList[0], true );
g = QgsGeometry::fromPolygon( QgsPolygon() << ( QgsPolyline () << mCaptureList.toVector() << mCaptureList[0] ) );
break;
}

if ( !g )
return;

mValidator = new QgsGeometryValidator( g );
connect( mValidator, SIGNAL( errorFound( QgsGeometry::Error ) ), this, SLOT( addError( QgsGeometry::Error ) ) );
connect( mValidator, SIGNAL( finished() ), this, SLOT( validationFinished() ) );
mValidator->start();

QStatusBar *sb = QgisApp::instance()->statusBar();
sb->showMessage( tr( "Validation started." ) );
}

void QgsMapToolCapture::addError( QgsGeometry::Error e )
{
mGeomErrors << e;
QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( mCanvas->currentLayer() );
if ( !vlayer )
return;

QString tip;
for ( int i = 0; i < mGeomErrors.size(); i++ )
{
tip += mGeomErrors[i].what() + "\n";
if ( !mGeomErrors[i].hasWhere() )
continue;
if ( !mTip.isEmpty() )
mTip += "\n";

mTip += e.what();

if ( e.hasWhere() )
{
QgsVertexMarker *vm = new QgsVertexMarker( mCanvas );
vm->setCenter( mCanvas->mapRenderer()->layerToMapCoordinates( vlayer, mGeomErrors[i].where() ) );
vm->setCenter( mCanvas->mapRenderer()->layerToMapCoordinates( vlayer, e.where() ) );
vm->setIconType( QgsVertexMarker::ICON_X );
vm->setPenWidth( 2 );
vm->setToolTip( mGeomErrors[i].what() );
vm->setToolTip( e.what() );
vm->setColor( Qt::green );
vm->setZValue( vm->zValue() + 1 );
mGeomErrorMarkers << vm;
}

QStatusBar *sb = QgisApp::instance()->statusBar();
sb->showMessage( QObject::tr( "%n geometry error(s) found.", "number of geometry errors", mGeomErrors.size() ) );
if ( !tip.isEmpty() )
sb->setToolTip( tip );
sb->showMessage( e.what() );
if ( !mTip.isEmpty() )
sb->setToolTip( mTip );
}

void QgsMapToolCapture::validationFinished()
{
QStatusBar *sb = QgisApp::instance()->statusBar();
sb->showMessage( tr( "Validation finished." ) );
}
12 changes: 8 additions & 4 deletions src/app/qgsmaptoolcapture.h
Expand Up @@ -22,13 +22,13 @@
#include "qgsgeometry.h"
#include "qgslegend.h"

class QgsGeometry;
#include <QPoint>
#include <QList>

class QgsRubberBand;
class QgsVertexMarker;
class QgsMapLayer;

#include <QPoint>
#include <QList>
class QgsGeometryValidator;

class QgsMapToolCapture : public QgsMapToolEdit
{
Expand Down Expand Up @@ -69,6 +69,8 @@ class QgsMapToolCapture : public QgsMapToolEdit

public slots:
void currentLayerChanged( QgsMapLayer *layer );
void addError( QgsGeometry::Error );
void validationFinished();

protected:
int nextPoint( const QPoint &p, QgsPoint &layerPoint, QgsPoint &mapPoint );
Expand Down Expand Up @@ -105,6 +107,8 @@ class QgsMapToolCapture : public QgsMapToolEdit
QList<QgsPoint> mCaptureList;

void validateGeometry();
QString mTip;
QgsGeometryValidator *mValidator;
QList< QgsGeometry::Error > mGeomErrors;
QList< QgsVertexMarker * > mGeomErrorMarkers;

Expand Down
78 changes: 52 additions & 26 deletions src/app/qgsmaptoolnodetool.cpp
Expand Up @@ -21,13 +21,13 @@
#include "qgsvectordataprovider.h"
#include "qgstolerance.h"
#include "qgsgeometry.h"
#include <cmath>
#include <QMouseEvent>
#include <QMessageBox>
#include "qgslogger.h"
#include "qgisapp.h"
#include "qgslegend.h"

#include <cmath>
#include <QMouseEvent>
#include <QMessageBox>
#include <QStatusBar>


Expand Down Expand Up @@ -458,7 +458,7 @@ bool QgsMapToolNodeTool::checkCorrectnessOfFeature( QgsVectorLayer *vlayer )
qDebug( "feature doesn't exist any more" );
QMessageBox::warning( NULL,
tr( "Node tool" ),
tr( "Feature was deleted on background.\n" ),
tr( "Feature was deleted on background." ),
QMessageBox::Ok ,
QMessageBox::Ok );
delete mSelectionFeature;
Expand Down Expand Up @@ -890,6 +890,7 @@ SelectionFeature::SelectionFeature()
mFeature = new QgsFeature();
mFeatureId = 0;
mFeatureSelected = false;
mValidator = 0;
}

SelectionFeature::~SelectionFeature()
Expand All @@ -900,6 +901,12 @@ SelectionFeature::~SelectionFeature()
{
delete mGeomErrorMarkers.takeFirst();
}

if( mValidator )
{
mValidator->deleteLater();
mValidator = 0;
}
}

void SelectionFeature::updateFeature()
Expand Down Expand Up @@ -954,43 +961,63 @@ void SelectionFeature::setSelectedFeature( QgsFeatureId featureId,

void SelectionFeature::validateGeometry( QgsGeometry *g )
{
if ( g == NULL )
g = mFeature->geometry();

if ( g->isGeosValid() )
{
QgsDebugMsg( "geometry is valid - not validating." );
QSettings settings;
if ( settings.value( "/qgis/digitizing/validate_geometries", 1 ).toInt() == 0 )
return;
}

if ( !g )
g = mFeature->geometry();

QgsDebugMsg( "validating geometry" );

g->validateGeometry( mGeomErrors );
mTip.clear();

mGeomErrors.clear();
while ( !mGeomErrorMarkers.isEmpty() )
{
delete mGeomErrorMarkers.takeFirst();
}

QString tip;

for ( int i = 0; i < mGeomErrors.size(); i++ )
if( mValidator )
{
tip += mGeomErrors[i].what() + "\n";
if ( !mGeomErrors[i].hasWhere() )
continue;
mValidator->deleteLater();
mValidator = 0;
}

mValidator = new QgsGeometryValidator( g );
connect( mValidator, SIGNAL( errorFound( QgsGeometry::Error ) ), this, SLOT( addError( QgsGeometry::Error ) ) );
connect( mValidator, SIGNAL( finished() ), this, SLOT( validationFinished() ) );
mValidator->start();

QStatusBar *sb = QgisApp::instance()->statusBar();
sb->showMessage( tr( "Validation started." ) );
}

void SelectionFeature::addError( QgsGeometry::Error e )
{
mGeomErrors << e;
if ( !mTip.isEmpty() )
mTip += "\n";
mTip += e.what();

QgsVertexMarker *vm = createVertexMarker( mGeomErrors[i].where(), QgsVertexMarker::ICON_X );
vm->setToolTip( mGeomErrors[i].what() );
if ( e.hasWhere() )
{
QgsVertexMarker *vm = createVertexMarker( e.where(), QgsVertexMarker::ICON_X );
vm->setToolTip( e.what() );
vm->setColor( Qt::green );
vm->setZValue( vm->zValue() + 1 );
mGeomErrorMarkers << vm;
}

QStatusBar *sb = QgisApp::instance()->statusBar();
sb->showMessage( QObject::tr( "%n geometry error(s) found.", "number of geometry errors", mGeomErrors.size() ) );
if ( !tip.isEmpty() )
sb->setToolTip( tip );
sb->showMessage( e.what() );
sb->setToolTip( mTip );
}

void SelectionFeature::validationFinished()
{
QStatusBar *sb = QgisApp::instance()->statusBar();
sb->showMessage( tr( "Validation finished." ) );
}

void SelectionFeature::deleteSelectedVertexes()
Expand Down Expand Up @@ -1043,7 +1070,7 @@ void SelectionFeature::deleteSelectedVertexes()
{
QMessageBox::warning( NULL,
tr( "Node tool" ),
tr( "Result geometry is invalid. Reverting last changes.\n" ),
tr( "Result geometry is invalid. Reverting last changes." ),
QMessageBox::Ok ,
QMessageBox::Ok );
}
Expand All @@ -1061,7 +1088,6 @@ void SelectionFeature::deleteSelectedVertexes()
updateFromFeature();
}


void SelectionFeature::moveSelectedVertexes( double changeX, double changeY )
{
mVlayer->beginEditCommand( QObject::tr( "Moved vertices" ) );
Expand Down Expand Up @@ -1117,7 +1143,7 @@ void SelectionFeature::moveSelectedVertexes( double changeX, double changeY )
{
QMessageBox::warning( NULL,
tr( "Node tool" ),
tr( "Result geometry is invalid. Reverting last changes.\n" ),
tr( "Result geometry is invalid. Reverting last changes." ),
QMessageBox::Ok ,
QMessageBox::Ok );
//redo last operations
Expand Down
7 changes: 7 additions & 0 deletions src/app/qgsmaptoolnodetool.h
Expand Up @@ -19,6 +19,8 @@
#include "qgsmaptoolvertexedit.h"
#include "qgsfeature.h"
#include "qgsvertexmarker.h"
#include "qgsgeometryvalidator.h"

#include <QRect>
#include <QRubberBand>

Expand Down Expand Up @@ -169,6 +171,9 @@ class SelectionFeature: public QObject
*/
QgsVectorLayer* vlayer();

public slots:
void addError( QgsGeometry::Error );
void validationFinished();

private:
/**
Expand Down Expand Up @@ -214,6 +219,8 @@ class SelectionFeature: public QObject
QList<VertexEntry> mVertexMap;
QgsMapCanvas* mCanvas;

QgsGeometryValidator *mValidator;
QString mTip;
QList< QgsGeometry::Error > mGeomErrors;
QList< QgsVertexMarker * > mGeomErrorMarkers;
};
Expand Down

0 comments on commit e6167d2

Please sign in to comment.