Skip to content

Commit

Permalink
[FEATURE] allow editing of invalid geometry in node tool
Browse files Browse the repository at this point in the history
git-svn-id: http://svn.osgeo.org/qgis/trunk/qgis@12749 c8812cc2-4d05-0410-92ff-de0c093fc19c
  • Loading branch information
jef committed Jan 12, 2010
1 parent 3b73852 commit 3dbb09b
Show file tree
Hide file tree
Showing 6 changed files with 473 additions and 41 deletions.
79 changes: 68 additions & 11 deletions src/app/qgsmaptoolnodetool.cpp
Expand Up @@ -24,6 +24,10 @@
#include <math.h>
#include <QMouseEvent>
#include <QMessageBox>
#include "qgslogger.h"
#include "qgisapp.h"

#include <QStatusBar>


QgsRubberBand* QgsMapToolNodeTool::createRubberBandMarker( QgsPoint center, QgsVectorLayer* vlayer )
Expand Down Expand Up @@ -128,7 +132,7 @@ void QgsMapToolNodeTool::layerModified( bool onlyGeometry )
catch ( ... )
{
//GEOS is throwing exception when polygon is not valid to be able to edit it
//Only possibility to fix this operation sice node tool doesn't allow to strore invalid geometry after editing
//Only possibility to fix this operation since node tool doesn't allow to store invalid geometry after editing
mSelectionFeature->updateFromFeature();
//if it does update markers just to be sure of correctness
}
Expand All @@ -148,7 +152,7 @@ void QgsMapToolNodeTool::createMovingRubberBands()
for ( int i = 0; i < vertexMap.size(); i++ )
{
//create rubber band
if ( vertexMap[i].selected && !( vertexMap[i].inRubberBand ) )
if ( vertexMap[i].selected && !vertexMap[i].inRubberBand )
{
geometry->adjacentVertices( i, beforeVertex, afterVertex );
vertex = i;
Expand Down Expand Up @@ -774,7 +778,7 @@ void QgsMapToolNodeTool::removeRubberBands()
mTopologyMovingVertexes.clear();
mTopologyRubberBandVertexes.clear();

//remove all data from selected feature (no change to rubber bands itself
//remove all data from selected feature (no change to rubber bands itself)
if ( mSelectionFeature != NULL )
mSelectionFeature->cleanRubberBandsData();
}
Expand Down Expand Up @@ -936,8 +940,46 @@ void SelectionFeature::setSelectedFeature( int featureId, QgsVectorLayer* vlaye
{
mFeature = feature;
}

//createvertexmap
createVertexMap();

validateGeometry();
}

void SelectionFeature::validateGeometry( QgsGeometry *g )
{
QgsDebugMsg( "validating geometry" );

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

g->validateGeometry( mGeomErrors );

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

QString tip;

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

QgsVertexMarker *vm = createVertexMarker( mGeomErrors[i].where(), QgsVertexMarker::ICON_X );
vm->setToolTip( mGeomErrors[i].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 );
}

void SelectionFeature::deleteSelectedVertexes()
Expand Down Expand Up @@ -983,7 +1025,10 @@ void SelectionFeature::deleteSelectedVertexes()
}
QgsFeature f;
mVlayer->featureAtId( mFeatureId, f, true, false );
if ( !GEOSisValid( f.geometry()->asGeos() ) )

bool wasValid = false; // mGeomErrors.isEmpty();
bool isValid = GEOSisValid( f.geometry()->asGeos() );
if ( wasValid && !isValid )
{
QMessageBox::warning( NULL,
tr( "Node tool" ),
Expand All @@ -992,7 +1037,7 @@ void SelectionFeature::deleteSelectedVertexes()
QMessageBox::Ok );
}

if ( count != 0 && GEOSisValid( f.geometry()->asGeos() ) )
if ( count != 0 && ( !wasValid || isValid ) )
{
mVlayer->endEditCommand();
}
Expand Down Expand Up @@ -1054,7 +1099,9 @@ void SelectionFeature::moveSelectedVertexes( double changeX, double changeY )
}
QgsFeature f;
mVlayer->featureAtId( mFeatureId, f, true, false );
if ( !GEOSisValid( f.geometry()->asGeos() ) )
bool wasValid = false; // mGeomErrors.isEmpty();
bool isValid = GEOSisValid( f.geometry()->asGeos() );
if ( wasValid && !isValid )
{
QMessageBox::warning( NULL,
tr( "Node tool" ),
Expand All @@ -1068,17 +1115,18 @@ void SelectionFeature::moveSelectedVertexes( double changeX, double changeY )
else
{
mVlayer->endEditCommand();
validateGeometry( f.geometry() );
}
updateFeature();
}

QgsVertexMarker* SelectionFeature::createVertexMarker( QgsPoint center )
QgsVertexMarker *SelectionFeature::createVertexMarker( QgsPoint center, QgsVertexMarker::IconType type )
{
QgsVertexMarker* marker = new QgsVertexMarker( mCanvas );
QgsVertexMarker *marker = new QgsVertexMarker( mCanvas );
QgsPoint newCenter = mCanvas->mapRenderer()->layerToMapCoordinates( mVlayer, center );
marker->setCenter( newCenter );

marker->setIconType( QgsVertexMarker::ICON_BOX );
marker->setIconType( type );

marker->setColor( Qt::red );

Expand All @@ -1103,6 +1151,11 @@ void SelectionFeature::deleteVertexMap()
VertexEntry entry = mVertexMap.takeLast();
delete entry.vertexMarker;
}

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

bool SelectionFeature::isSelected( int vertexNr )
Expand Down Expand Up @@ -1134,6 +1187,7 @@ void SelectionFeature::createVertexMapPolygon()
entry.originalIndex = i;
entry.inRubberBand = false;
QgsVertexMarker* marker = createVertexMarker( poly[i] );
marker->setToolTip( tr( "ring %1, vertex %2" ).arg( i2 ).arg( i ) );
entry.vertexMarker = marker;
mVertexMap.insert( y + i, entry );
}
Expand Down Expand Up @@ -1161,7 +1215,7 @@ void SelectionFeature::createVertexMapPolygon()
entry.originalIndex = y + i - 1;
entry.inRubberBand = false;
QgsVertexMarker* marker = createVertexMarker( poly[i] );

marker->setToolTip( tr( "polygon %1, ring %2, vertex %3" ).arg( i2 ).arg( i3 ).arg( i ) );
entry.vertexMarker = marker;
mVertexMap.insert( y + i, entry );
}
Expand Down Expand Up @@ -1194,6 +1248,7 @@ void SelectionFeature::createVertexMapLine()
entry.originalIndex = i;
entry.inRubberBand = false;
QgsVertexMarker* marker = createVertexMarker( poly[i] );
marker->setToolTip( tr( "polyline %1, vertex %2" ).arg( i2 ).arg( i ) );
entry.vertexMarker = marker;
mVertexMap.insert( y + i, entry );
}
Expand All @@ -1214,6 +1269,7 @@ void SelectionFeature::createVertexMapLine()
entry.originalIndex = i;
entry.inRubberBand = false;
QgsVertexMarker* marker = createVertexMarker( poly[i] );
marker->setToolTip( tr( "vertex %1" ).arg( i ) );
entry.vertexMarker = marker;
mVertexMap.insert( i, entry );
}
Expand All @@ -1236,6 +1292,7 @@ void SelectionFeature::createVertexMapPoint()
entry.originalIndex = 1;
entry.inRubberBand = false;
QgsVertexMarker* marker = createVertexMarker( poly[i] );
marker->setToolTip( tr( "point %1" ).arg( i ) );
entry.vertexMarker = marker;
mVertexMap.insert( i, entry );
}
Expand All @@ -1251,6 +1308,7 @@ void SelectionFeature::createVertexMapPoint()
entry.originalIndex = 1;
entry.inRubberBand = false;
QgsVertexMarker* marker = createVertexMarker( poly );
marker->setToolTip( tr( "single point" ) );
entry.vertexMarker = marker;
mVertexMap.insert( 1, entry );
}
Expand Down Expand Up @@ -1372,4 +1430,3 @@ QgsVectorLayer* SelectionFeature::vlayer()
{
return mVlayer;
}

14 changes: 10 additions & 4 deletions src/app/qgsmaptoolnodetool.h
Expand Up @@ -161,7 +161,7 @@ class SelectionFeature: public QObject
* @param center center of marker
* @return created vertex marker
*/
QgsVertexMarker* createVertexMarker( QgsPoint center );
QgsVertexMarker* createVertexMarker( QgsPoint center, QgsVertexMarker::IconType type = QgsVertexMarker::ICON_BOX );

/**
* Getter for getting vector layer which selection is working
Expand All @@ -171,7 +171,6 @@ class SelectionFeature: public QObject


private:

/**
* Deletes whole vertex map.
*/
Expand All @@ -198,17 +197,25 @@ class SelectionFeature: public QObject
void createVertexMapPoint();

/**
* Updates stored feauture to actual one loaded from layer
* Updates stored feature to actual one loaded from layer
*/
void updateFeature();

/**
* Validates the geometry
*/
void validateGeometry( QgsGeometry *g = NULL );

QgsFeature* mFeature;
int mFeatureId;
bool mFeatureSelected;
QgsVectorLayer* mVlayer;
QgsRubberBand* mRubberBand;
QList<VertexEntry> mVertexMap;
QgsMapCanvas* mCanvas;

QList< QgsGeometry::Error > mGeomErrors;
QList< QgsVertexMarker * > mGeomErrorMarkers;
};

/**A maptool to move/deletes/adds vertices of line or polygon features*/
Expand Down Expand Up @@ -367,7 +374,6 @@ class QgsMapToolNodeTool: public QgsMapToolVertexEdit

/** flag to tell if edition points */
bool mIsPoint;

};


Expand Down

0 comments on commit 3dbb09b

Please sign in to comment.