Skip to content

Commit 59b0d23

Browse files
author
jef
committed
[FEATURE] allow editing of invalid geometry in node tool
git-svn-id: http://svn.osgeo.org/qgis/trunk@12749 c8812cc2-4d05-0410-92ff-de0c093fc19c
1 parent 41654d5 commit 59b0d23

File tree

6 files changed

+473
-41
lines changed

6 files changed

+473
-41
lines changed

src/app/qgsmaptoolnodetool.cpp

+68-11
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@
2424
#include <math.h>
2525
#include <QMouseEvent>
2626
#include <QMessageBox>
27+
#include "qgslogger.h"
28+
#include "qgisapp.h"
29+
30+
#include <QStatusBar>
2731

2832

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

777-
//remove all data from selected feature (no change to rubber bands itself
781+
//remove all data from selected feature (no change to rubber bands itself)
778782
if ( mSelectionFeature != NULL )
779783
mSelectionFeature->cleanRubberBandsData();
780784
}
@@ -936,8 +940,46 @@ void SelectionFeature::setSelectedFeature( int featureId, QgsVectorLayer* vlaye
936940
{
937941
mFeature = feature;
938942
}
943+
939944
//createvertexmap
940945
createVertexMap();
946+
947+
validateGeometry();
948+
}
949+
950+
void SelectionFeature::validateGeometry( QgsGeometry *g )
951+
{
952+
QgsDebugMsg( "validating geometry" );
953+
954+
if ( g == NULL )
955+
g = mFeature->geometry();
956+
957+
g->validateGeometry( mGeomErrors );
958+
959+
while ( !mGeomErrorMarkers.isEmpty() )
960+
{
961+
delete mGeomErrorMarkers.takeFirst();
962+
}
963+
964+
QString tip;
965+
966+
for ( int i = 0; i < mGeomErrors.size(); i++ )
967+
{
968+
tip += mGeomErrors[i].what() + "\n";
969+
if ( !mGeomErrors[i].hasWhere() )
970+
continue;
971+
972+
QgsVertexMarker *vm = createVertexMarker( mGeomErrors[i].where(), QgsVertexMarker::ICON_X );
973+
vm->setToolTip( mGeomErrors[i].what() );
974+
vm->setColor( Qt::green );
975+
vm->setZValue( vm->zValue() + 1 );
976+
mGeomErrorMarkers << vm;
977+
}
978+
979+
QStatusBar *sb = QgisApp::instance()->statusBar();
980+
sb->showMessage( QObject::tr( "%n geometry error(s) found.", "number of geometry errors", mGeomErrors.size() ) );
981+
if ( !tip.isEmpty() )
982+
sb->setToolTip( tip );
941983
}
942984

943985
void SelectionFeature::deleteSelectedVertexes()
@@ -983,7 +1025,10 @@ void SelectionFeature::deleteSelectedVertexes()
9831025
}
9841026
QgsFeature f;
9851027
mVlayer->featureAtId( mFeatureId, f, true, false );
986-
if ( !GEOSisValid( f.geometry()->asGeos() ) )
1028+
1029+
bool wasValid = false; // mGeomErrors.isEmpty();
1030+
bool isValid = GEOSisValid( f.geometry()->asGeos() );
1031+
if ( wasValid && !isValid )
9871032
{
9881033
QMessageBox::warning( NULL,
9891034
tr( "Node tool" ),
@@ -992,7 +1037,7 @@ void SelectionFeature::deleteSelectedVertexes()
9921037
QMessageBox::Ok );
9931038
}
9941039

995-
if ( count != 0 && GEOSisValid( f.geometry()->asGeos() ) )
1040+
if ( count != 0 && ( !wasValid || isValid ) )
9961041
{
9971042
mVlayer->endEditCommand();
9981043
}
@@ -1054,7 +1099,9 @@ void SelectionFeature::moveSelectedVertexes( double changeX, double changeY )
10541099
}
10551100
QgsFeature f;
10561101
mVlayer->featureAtId( mFeatureId, f, true, false );
1057-
if ( !GEOSisValid( f.geometry()->asGeos() ) )
1102+
bool wasValid = false; // mGeomErrors.isEmpty();
1103+
bool isValid = GEOSisValid( f.geometry()->asGeos() );
1104+
if ( wasValid && !isValid )
10581105
{
10591106
QMessageBox::warning( NULL,
10601107
tr( "Node tool" ),
@@ -1068,17 +1115,18 @@ void SelectionFeature::moveSelectedVertexes( double changeX, double changeY )
10681115
else
10691116
{
10701117
mVlayer->endEditCommand();
1118+
validateGeometry( f.geometry() );
10711119
}
10721120
updateFeature();
10731121
}
10741122

1075-
QgsVertexMarker* SelectionFeature::createVertexMarker( QgsPoint center )
1123+
QgsVertexMarker *SelectionFeature::createVertexMarker( QgsPoint center, QgsVertexMarker::IconType type )
10761124
{
1077-
QgsVertexMarker* marker = new QgsVertexMarker( mCanvas );
1125+
QgsVertexMarker *marker = new QgsVertexMarker( mCanvas );
10781126
QgsPoint newCenter = mCanvas->mapRenderer()->layerToMapCoordinates( mVlayer, center );
10791127
marker->setCenter( newCenter );
10801128

1081-
marker->setIconType( QgsVertexMarker::ICON_BOX );
1129+
marker->setIconType( type );
10821130

10831131
marker->setColor( Qt::red );
10841132

@@ -1103,6 +1151,11 @@ void SelectionFeature::deleteVertexMap()
11031151
VertexEntry entry = mVertexMap.takeLast();
11041152
delete entry.vertexMarker;
11051153
}
1154+
1155+
while ( !mGeomErrorMarkers.isEmpty() )
1156+
{
1157+
delete mGeomErrorMarkers.takeFirst();
1158+
}
11061159
}
11071160

11081161
bool SelectionFeature::isSelected( int vertexNr )
@@ -1134,6 +1187,7 @@ void SelectionFeature::createVertexMapPolygon()
11341187
entry.originalIndex = i;
11351188
entry.inRubberBand = false;
11361189
QgsVertexMarker* marker = createVertexMarker( poly[i] );
1190+
marker->setToolTip( tr( "ring %1, vertex %2" ).arg( i2 ).arg( i ) );
11371191
entry.vertexMarker = marker;
11381192
mVertexMap.insert( y + i, entry );
11391193
}
@@ -1161,7 +1215,7 @@ void SelectionFeature::createVertexMapPolygon()
11611215
entry.originalIndex = y + i - 1;
11621216
entry.inRubberBand = false;
11631217
QgsVertexMarker* marker = createVertexMarker( poly[i] );
1164-
1218+
marker->setToolTip( tr( "polygon %1, ring %2, vertex %3" ).arg( i2 ).arg( i3 ).arg( i ) );
11651219
entry.vertexMarker = marker;
11661220
mVertexMap.insert( y + i, entry );
11671221
}
@@ -1194,6 +1248,7 @@ void SelectionFeature::createVertexMapLine()
11941248
entry.originalIndex = i;
11951249
entry.inRubberBand = false;
11961250
QgsVertexMarker* marker = createVertexMarker( poly[i] );
1251+
marker->setToolTip( tr( "polyline %1, vertex %2" ).arg( i2 ).arg( i ) );
11971252
entry.vertexMarker = marker;
11981253
mVertexMap.insert( y + i, entry );
11991254
}
@@ -1214,6 +1269,7 @@ void SelectionFeature::createVertexMapLine()
12141269
entry.originalIndex = i;
12151270
entry.inRubberBand = false;
12161271
QgsVertexMarker* marker = createVertexMarker( poly[i] );
1272+
marker->setToolTip( tr( "vertex %1" ).arg( i ) );
12171273
entry.vertexMarker = marker;
12181274
mVertexMap.insert( i, entry );
12191275
}
@@ -1236,6 +1292,7 @@ void SelectionFeature::createVertexMapPoint()
12361292
entry.originalIndex = 1;
12371293
entry.inRubberBand = false;
12381294
QgsVertexMarker* marker = createVertexMarker( poly[i] );
1295+
marker->setToolTip( tr( "point %1" ).arg( i ) );
12391296
entry.vertexMarker = marker;
12401297
mVertexMap.insert( i, entry );
12411298
}
@@ -1251,6 +1308,7 @@ void SelectionFeature::createVertexMapPoint()
12511308
entry.originalIndex = 1;
12521309
entry.inRubberBand = false;
12531310
QgsVertexMarker* marker = createVertexMarker( poly );
1311+
marker->setToolTip( tr( "single point" ) );
12541312
entry.vertexMarker = marker;
12551313
mVertexMap.insert( 1, entry );
12561314
}
@@ -1372,4 +1430,3 @@ QgsVectorLayer* SelectionFeature::vlayer()
13721430
{
13731431
return mVlayer;
13741432
}
1375-

src/app/qgsmaptoolnodetool.h

+10-4
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ class SelectionFeature: public QObject
161161
* @param center center of marker
162162
* @return created vertex marker
163163
*/
164-
QgsVertexMarker* createVertexMarker( QgsPoint center );
164+
QgsVertexMarker* createVertexMarker( QgsPoint center, QgsVertexMarker::IconType type = QgsVertexMarker::ICON_BOX );
165165

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

172172

173173
private:
174-
175174
/**
176175
* Deletes whole vertex map.
177176
*/
@@ -198,17 +197,25 @@ class SelectionFeature: public QObject
198197
void createVertexMapPoint();
199198

200199
/**
201-
* Updates stored feauture to actual one loaded from layer
200+
* Updates stored feature to actual one loaded from layer
202201
*/
203202
void updateFeature();
204203

204+
/**
205+
* Validates the geometry
206+
*/
207+
void validateGeometry( QgsGeometry *g = NULL );
208+
205209
QgsFeature* mFeature;
206210
int mFeatureId;
207211
bool mFeatureSelected;
208212
QgsVectorLayer* mVlayer;
209213
QgsRubberBand* mRubberBand;
210214
QList<VertexEntry> mVertexMap;
211215
QgsMapCanvas* mCanvas;
216+
217+
QList< QgsGeometry::Error > mGeomErrors;
218+
QList< QgsVertexMarker * > mGeomErrorMarkers;
212219
};
213220

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

368375
/** flag to tell if edition points */
369376
bool mIsPoint;
370-
371377
};
372378

373379

0 commit comments

Comments
 (0)