Skip to content

Commit

Permalink
[FEATURE] add validation to capture tool
Browse files Browse the repository at this point in the history
git-svn-id: http://svn.osgeo.org/qgis/trunk/qgis@12830 c8812cc2-4d05-0410-92ff-de0c093fc19c
  • Loading branch information
jef committed Jan 24, 2010
1 parent 7d15e18 commit f1b1598
Show file tree
Hide file tree
Showing 11 changed files with 339 additions and 219 deletions.
10 changes: 10 additions & 0 deletions python/core/qgsgeometry.sip
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,16 @@ class QgsGeometry
/** Returns true if wkb of the geometry is of WKBMulti* type */
bool isMultipart();

/** compare geometries using GEOS
@note added in 1.5
*/
bool isGeosEqual( QgsGeometry & );

/** check validity using GEOS
@note added in 1.5
*/
bool isGeosValid();

/**
Set the geometry, feeding in a geometry in GEOS format.
*/
Expand Down
115 changes: 47 additions & 68 deletions src/app/qgsmaptooladdfeature.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,7 @@ void QgsMapToolAddFeature::canvasReleaseEvent( QMouseEvent * e )
layerWKBType == QGis::WKBMultiLineString25D || layerWKBType == QGis::WKBPoint25D || layerWKBType == QGis::WKBMultiPoint25D )
{
QMessageBox::critical( 0, tr( "2.5D shape type not supported" ), tr( "Adding features to 2.5D shapetypes is not supported yet" ) );
delete mRubberBand;
mRubberBand = NULL;
mCapturing = FALSE;
mCaptureList.clear();
mCanvas->refresh();
stopCapturing();
return;
}

Expand All @@ -85,7 +81,7 @@ void QgsMapToolAddFeature::canvasReleaseEvent( QMouseEvent * e )
}

// POINT CAPTURING
if ( mCaptureMode == CapturePoint )
if ( mode() == CapturePoint )
{
//check we only use this tool for point/multipoint layers
if ( vlayer->geometryType() != QGis::Point )
Expand Down Expand Up @@ -129,7 +125,7 @@ void QgsMapToolAddFeature::canvasReleaseEvent( QMouseEvent * e )
QgsFeature* f = new QgsFeature( 0, "WKBPoint" );

int size = 0;
char end = QgsApplication::endian();
char endian = QgsApplication::endian();
unsigned char *wkb = NULL;
int wkbtype = 0;
double x = savePoint.x();
Expand All @@ -140,7 +136,7 @@ void QgsMapToolAddFeature::canvasReleaseEvent( QMouseEvent * e )
size = 1 + sizeof( int ) + 2 * sizeof( double );
wkb = new unsigned char[size];
wkbtype = QGis::WKBPoint;
memcpy( &wkb[0], &end, 1 );
memcpy( &wkb[0], &endian, 1 );
memcpy( &wkb[1], &wkbtype, sizeof( int ) );
memcpy( &wkb[5], &x, sizeof( double ) );
memcpy( &wkb[5] + sizeof( double ), &y, sizeof( double ) );
Expand All @@ -151,14 +147,14 @@ void QgsMapToolAddFeature::canvasReleaseEvent( QMouseEvent * e )
wkb = new unsigned char[size];
wkbtype = QGis::WKBMultiPoint;
int position = 0;
memcpy( &wkb[position], &end, 1 );
memcpy( &wkb[position], &endian, 1 );
position += 1;
memcpy( &wkb[position], &wkbtype, sizeof( int ) );
position += sizeof( int );
int npoint = 1;
memcpy( &wkb[position], &npoint, sizeof( int ) );
position += sizeof( int );
memcpy( &wkb[position], &end, 1 );
memcpy( &wkb[position], &endian, 1 );
position += 1;
int pointtype = QGis::WKBPoint;
memcpy( &wkb[position], &pointtype, sizeof( int ) );
Expand Down Expand Up @@ -209,18 +205,18 @@ void QgsMapToolAddFeature::canvasReleaseEvent( QMouseEvent * e )
}

}
else if ( mCaptureMode == CaptureLine || mCaptureMode == CapturePolygon )
else if ( mode() == CaptureLine || mode() == CapturePolygon )
{
//check we only use the line tool for line/multiline layers
if ( mCaptureMode == CaptureLine && vlayer->geometryType() != QGis::Line )
if ( mode() == CaptureLine && vlayer->geometryType() != QGis::Line )
{
QMessageBox::information( 0, tr( "Wrong editing tool" ),
tr( "Cannot apply the 'capture line' tool on this vector layer" ) );
return;
}

//check we only use the polygon tool for polygon/multipolygon layers
if ( mCaptureMode == CapturePolygon && vlayer->geometryType() != QGis::Polygon )
if ( mode() == CapturePolygon && vlayer->geometryType() != QGis::Polygon )
{
QMessageBox::information( 0, tr( "Wrong editing tool" ),
tr( "Cannot apply the 'capture polygon' tool on this vector layer" ) );
Expand All @@ -244,52 +240,46 @@ void QgsMapToolAddFeature::canvasReleaseEvent( QMouseEvent * e )

if ( e->button() == Qt::LeftButton )
{
mCapturing = TRUE;
startCapturing();
}
else if ( e->button() == Qt::RightButton )
{
// End of string

mCapturing = FALSE;

//lines: bail out if there are not at least two vertices
if ( mCaptureMode == CaptureLine && mCaptureList.size() < 2 )
if ( mode() == CaptureLine && size() < 2 )
{
delete mRubberBand;
mRubberBand = NULL;
mCaptureList.clear();
stopCapturing();
return;
}

//polygons: bail out if there are not at least two vertices
if ( mCaptureMode == CapturePolygon && mCaptureList.size() < 3 )
if ( mode() == CapturePolygon && size() < 3 )
{
delete mRubberBand;
mRubberBand = NULL;
mCaptureList.clear();
stopCapturing();
return;
}

//create QgsFeature with wkb representation
QgsFeature* f = new QgsFeature( 0, "WKBLineString" );
unsigned char* wkb;
int size;
char end = QgsApplication::endian();
int wkbsize;
char endian = QgsApplication::endian();

if ( mCaptureMode == CaptureLine )
if ( mode() == CaptureLine )
{
if ( layerWKBType == QGis::WKBLineString )
{
size = 1 + 2 * sizeof( int ) + 2 * mCaptureList.size() * sizeof( double );
wkb = new unsigned char[size];
wkbsize = 1 + 2 * sizeof( int ) + 2 * size() * sizeof( double );
wkb = new unsigned char[wkbsize];
int wkbtype = QGis::WKBLineString;
int length = mCaptureList.size();
memcpy( &wkb[0], &end, 1 );
int length = size();
memcpy( &wkb[0], &endian, 1 );
memcpy( &wkb[1], &wkbtype, sizeof( int ) );
memcpy( &wkb[1+sizeof( int )], &length, sizeof( int ) );
int position = 1 + 2 * sizeof( int );
double x, y;
for ( QList<QgsPoint>::iterator it = mCaptureList.begin(); it != mCaptureList.end(); ++it )
for ( QList<QgsPoint>::iterator it = begin(); it != end(); ++it )
{
QgsPoint savePoint = *it;
x = savePoint.x();
Expand All @@ -304,27 +294,27 @@ void QgsMapToolAddFeature::canvasReleaseEvent( QMouseEvent * e )
}
else if ( layerWKBType == QGis::WKBMultiLineString )
{
size = 1 + 2 * sizeof( int ) + 1 + 2 * sizeof( int ) + 2 * mCaptureList.size() * sizeof( double );
wkb = new unsigned char[size];
wkbsize = 1 + 2 * sizeof( int ) + 1 + 2 * sizeof( int ) + 2 * size() * sizeof( double );
wkb = new unsigned char[wkbsize];
int position = 0;
int wkbtype = QGis::WKBMultiLineString;
memcpy( &wkb[position], &end, 1 );
memcpy( &wkb[position], &endian, 1 );
position += 1;
memcpy( &wkb[position], &wkbtype, sizeof( int ) );
position += sizeof( int );
int nlines = 1;
memcpy( &wkb[position], &nlines, sizeof( int ) );
position += sizeof( int );
memcpy( &wkb[position], &end, 1 );
memcpy( &wkb[position], &endian, 1 );
position += 1;
int linewkbtype = QGis::WKBLineString;
memcpy( &wkb[position], &linewkbtype, sizeof( int ) );
position += sizeof( int );
int length = mCaptureList.size();
int length = size();
memcpy( &wkb[position], &length, sizeof( int ) );
position += sizeof( int );
double x, y;
for ( QList<QgsPoint>::iterator it = mCaptureList.begin(); it != mCaptureList.end(); ++it )
for ( QList<QgsPoint>::iterator it = begin(); it != end(); ++it )
{
QgsPoint savePoint = *it;
x = savePoint.x();
Expand All @@ -340,30 +330,28 @@ void QgsMapToolAddFeature::canvasReleaseEvent( QMouseEvent * e )
else
{
QMessageBox::critical( 0, tr( "Error" ), tr( "Cannot add feature. Unknown WKB type" ) );
delete mRubberBand;
mRubberBand = NULL;
mCaptureList.clear();
stopCapturing();
return; //unknown wkbtype
}
f->setGeometryAndOwnership( &wkb[0], size );
f->setGeometryAndOwnership( &wkb[0], wkbsize );
}
else // polygon
{
if ( layerWKBType == QGis::WKBPolygon )
{
size = 1 + 3 * sizeof( int ) + 2 * ( mCaptureList.size() + 1 ) * sizeof( double );
wkb = new unsigned char[size];
wkbsize = 1 + 3 * sizeof( int ) + 2 * ( size() + 1 ) * sizeof( double );
wkb = new unsigned char[wkbsize];
int wkbtype = QGis::WKBPolygon;
int length = mCaptureList.size() + 1;//+1 because the first point is needed twice
int length = size() + 1;//+1 because the first point is needed twice
int numrings = 1;
memcpy( &wkb[0], &end, 1 );
memcpy( &wkb[0], &endian, 1 );
memcpy( &wkb[1], &wkbtype, sizeof( int ) );
memcpy( &wkb[1+sizeof( int )], &numrings, sizeof( int ) );
memcpy( &wkb[1+2*sizeof( int )], &length, sizeof( int ) );
int position = 1 + 3 * sizeof( int );
double x, y;
QList<QgsPoint>::iterator it;
for ( it = mCaptureList.begin(); it != mCaptureList.end(); ++it )
for ( it = begin(); it != end(); ++it )
{
QgsPoint savePoint = *it;
x = savePoint.x();
Expand All @@ -376,7 +364,7 @@ void QgsMapToolAddFeature::canvasReleaseEvent( QMouseEvent * e )
position += sizeof( double );
}
// close the polygon
it = mCaptureList.begin();
it = begin();
QgsPoint savePoint = *it;
x = savePoint.x();
y = savePoint.y();
Expand All @@ -388,21 +376,21 @@ void QgsMapToolAddFeature::canvasReleaseEvent( QMouseEvent * e )
}
else if ( layerWKBType == QGis::WKBMultiPolygon )
{
size = 2 + 5 * sizeof( int ) + 2 * ( mCaptureList.size() + 1 ) * sizeof( double );
wkb = new unsigned char[size];
wkbsize = 2 + 5 * sizeof( int ) + 2 * ( size() + 1 ) * sizeof( double );
wkb = new unsigned char[wkbsize];
int wkbtype = QGis::WKBMultiPolygon;
int polygontype = QGis::WKBPolygon;
int length = mCaptureList.size() + 1;//+1 because the first point is needed twice
int length = size() + 1;//+1 because the first point is needed twice
int numrings = 1;
int numpolygons = 1;
int position = 0; //pointer position relative to &wkb[0]
memcpy( &wkb[position], &end, 1 );
memcpy( &wkb[position], &endian, 1 );
position += 1;
memcpy( &wkb[position], &wkbtype, sizeof( int ) );
position += sizeof( int );
memcpy( &wkb[position], &numpolygons, sizeof( int ) );
position += sizeof( int );
memcpy( &wkb[position], &end, 1 );
memcpy( &wkb[position], &endian, 1 );
position += 1;
memcpy( &wkb[position], &polygontype, sizeof( int ) );
position += sizeof( int );
Expand All @@ -412,7 +400,7 @@ void QgsMapToolAddFeature::canvasReleaseEvent( QMouseEvent * e )
position += sizeof( int );
double x, y;
QList<QgsPoint>::iterator it;
for ( it = mCaptureList.begin(); it != mCaptureList.end(); ++it )//add the captured points to the polygon
for ( it = begin(); it != end(); ++it )//add the captured points to the polygon
{
QgsPoint savePoint = *it;
x = savePoint.x();
Expand All @@ -425,7 +413,7 @@ void QgsMapToolAddFeature::canvasReleaseEvent( QMouseEvent * e )
position += sizeof( double );
}
// close the polygon
it = mCaptureList.begin();
it = begin();
QgsPoint savePoint = *it;
x = savePoint.x();
y = savePoint.y();
Expand All @@ -436,12 +424,10 @@ void QgsMapToolAddFeature::canvasReleaseEvent( QMouseEvent * e )
else
{
QMessageBox::critical( 0, tr( "Error" ), tr( "Cannot add feature. Unknown WKB type" ) );
delete mRubberBand;
mRubberBand = NULL;
mCaptureList.clear();
stopCapturing();
return; //unknown wkbtype
}
f->setGeometryAndOwnership( &wkb[0], size );
f->setGeometryAndOwnership( &wkb[0], wkbsize );

int avoidIntersectionsReturn = f->geometry()->avoidIntersections();
if ( avoidIntersectionsReturn == 1 )
Expand All @@ -453,9 +439,7 @@ void QgsMapToolAddFeature::canvasReleaseEvent( QMouseEvent * e )
//bail out...
QMessageBox::critical( 0, tr( "Error" ), tr( "The feature could not be added because removing the polygon intersections would change the geometry type" ) );
delete f;
delete mRubberBand;
mRubberBand = 0;
mCaptureList.clear();
stopCapturing();
return;
}
else if ( avoidIntersectionsReturn == 3 )
Expand Down Expand Up @@ -510,12 +494,7 @@ void QgsMapToolAddFeature::canvasReleaseEvent( QMouseEvent * e )
}
delete f;

delete mRubberBand;
mRubberBand = NULL;

// delete the elements of mCaptureList
mCaptureList.clear();
mCanvas->refresh();
stopCapturing();
}
}
}
20 changes: 7 additions & 13 deletions src/app/qgsmaptooladdisland.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,7 @@ void QgsMapToolAddIsland::canvasReleaseEvent( QMouseEvent * e )
if ( !selectionErrorMsg.isEmpty() )
{
QMessageBox::critical( 0, tr( "Error, could not add island" ), selectionErrorMsg );
mCaptureList.clear();
delete mRubberBand;
mRubberBand = 0;
stopCapturing();
return;
}

Expand All @@ -94,18 +92,15 @@ void QgsMapToolAddIsland::canvasReleaseEvent( QMouseEvent * e )

if ( e->button() == Qt::LeftButton )
{
mCapturing = TRUE;
startCapturing();
}
else if ( e->button() == Qt::RightButton )
{
mCapturing = FALSE;
delete mRubberBand;
mRubberBand = 0;

//close polygon
mCaptureList.push_back( *mCaptureList.begin() );
closePolygon();

vlayer->beginEditCommand( tr( "Part added" ) );
int errorCode = vlayer->addIsland( mCaptureList );
int errorCode = vlayer->addIsland( points() );
QString errorMessage;

if ( errorCode != 0 )
Expand Down Expand Up @@ -144,13 +139,12 @@ void QgsMapToolAddIsland::canvasReleaseEvent( QMouseEvent * e )
int topologicalEditing = QgsProject::instance()->readNumEntry( "Digitizing", "/TopologicalEditing", 0 );
if ( topologicalEditing )
{
addTopologicalPoints( mCaptureList );
addTopologicalPoints( points() );
}

vlayer->endEditCommand();
}

mCaptureList.clear();
mCanvas->refresh();
stopCapturing();
}
}
Loading

0 comments on commit f1b1598

Please sign in to comment.