[QGIS Commit] r11141 - trunk/qgis/src/app
svn_qgis at osgeo.org
svn_qgis at osgeo.org
Wed Jul 22 07:31:26 EDT 2009
Author: wonder
Date: 2009-07-22 07:31:25 -0400 (Wed, 22 Jul 2009)
New Revision: 11141
Modified:
trunk/qgis/src/app/qgsmaptoolnodetool.cpp
trunk/qgis/src/app/qgsmaptoolnodetool.h
Log:
Added support for topology editing in node tool. Contributed by Richard Kostecky.
Modified: trunk/qgis/src/app/qgsmaptoolnodetool.cpp
===================================================================
--- trunk/qgis/src/app/qgsmaptoolnodetool.cpp 2009-07-21 22:58:36 UTC (rev 11140)
+++ trunk/qgis/src/app/qgsmaptoolnodetool.cpp 2009-07-22 11:31:25 UTC (rev 11141)
@@ -20,12 +20,15 @@
#include "qgsvectorlayer.h"
#include "qgsvectordataprovider.h"
#include "qgstolerance.h"
+#include "qgsgeometry.h"
#include <math.h>
#include <QMouseEvent>
#include <QMessageBox>
+
QgsRubberBand* QgsMapToolNodeTool::createRubberBandMarker( QgsPoint center, QgsVectorLayer* vlayer )
{
+ //create rubber band marker for moving points
QgsRubberBand* marker = new QgsRubberBand( mCanvas, true );
marker->setColor( Qt::red );
marker->setWidth( 2 );
@@ -58,8 +61,12 @@
mClicked = false;
mChangingGeometry = false;
mIsPoint = false;
+ //signal handling change of layer structure
connect( canvas, SIGNAL( layersChanged() ), this, SLOT( layersChanged() ) );
+ //signal when destination srs changed to repaint coordinates
connect( canvas->mapRenderer(), SIGNAL( destinationSrsChanged() ), this, SLOT( coordinatesChanged() ) );
+ //signal changing of coordinate renderer changed to repaint markers
+ connect( canvas->mapRenderer(), SIGNAL( hasCrsTransformEnabled( bool ) ), this, SLOT( coordinatesChanged( ) ) );
}
QgsMapToolNodeTool::~QgsMapToolNodeTool()
@@ -69,6 +76,7 @@
void QgsMapToolNodeTool::layersChanged()
{
+ //deselection of feature when layer has changed
QgsVectorLayer* vlayer = dynamic_cast<QgsVectorLayer*>( mCanvas->currentLayer() );
if ( mSelectionFeature != NULL && mSelectionFeature->vlayer() != vlayer )
{
@@ -79,6 +87,7 @@
void QgsMapToolNodeTool::currentLayerChanged( QgsMapLayer* layer )
{
+ //deselection of feature when current layer has changed
QgsVectorLayer* vlayer = dynamic_cast<QgsVectorLayer*>( layer );
if ( mSelectionFeature != NULL && mSelectionFeature->vlayer() != vlayer )
{
@@ -90,8 +99,10 @@
void QgsMapToolNodeTool::featureDeleted( int featureId )
{
+ //check if deleted feature is the one selected
if ( mSelectionFeature != NULL && featureId == mSelectionFeature->featureId() )
{
+ //if it's delete selection and disconnect signals since tool is not used anymore
delete mSelectionFeature;
mSelectionFeature = NULL;
disconnect( mCanvas->currentLayer(), SIGNAL( featureDeleted( int ) ) );
@@ -101,21 +112,34 @@
void QgsMapToolNodeTool::layerModified( bool onlyGeometry )
{
+ //handling modification of
QgsFeature feat;
QgsVectorLayer* vlayer = dynamic_cast<QgsVectorLayer*>( mCanvas->currentLayer() );
if ( mSelectionFeature != NULL && !mChangingGeometry && ( vlayer->featureAtId( mSelectionFeature->featureId(), feat, true, false ) ) )
{
- if ( !GEOSEquals( feat.geometry()->asGeos(), mSelectionFeature->feature()->geometry()->asGeos() ) )
+ try
{
- qDebug( "update from feature" );
+ if ( !GEOSEquals( feat.geometry()->asGeos(), mSelectionFeature->feature()->geometry()->asGeos() ) )
+ {
+ mSelectionFeature->updateFromFeature();
+ //throw error
+ }
+ }
+ 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
mSelectionFeature->updateFromFeature();
- //throw error
+ //if it does update markers just to be sure of correctness
}
}
}
void QgsMapToolNodeTool::createMovingRubberBands()
{
+ int topologicalEditing = QgsProject::instance()->readNumEntry( "Digitizing", "/TopologicalEditing", 0 );
+
+ QgsVectorLayer* vlayer = dynamic_cast<QgsVectorLayer*>( mCanvas->currentLayer() );
QList<VertexEntry> vertexMap = mSelectionFeature->vertexMap();
QgsGeometry* geometry = mSelectionFeature->feature()->geometry();
int beforeVertex, afterVertex;
@@ -136,11 +160,12 @@
geometry->adjacentVertices( vertex, beforeVertex, afterVertex );
}
else
- { //break
+ { //break if cycle is found
break;
}
}
//we have first vertex of moving part
+ //create rubber band and set default paramaters
QgsRubberBand* rb = new QgsRubberBand( mCanvas, false );
rb->setWidth( 2 );
rb->setColor( Qt::blue );
@@ -154,13 +179,20 @@
}
while ( vertex != -1 && vertexMap[vertex].selected && !vertexMap[vertex].inRubberBand )
{
+ //topology rubber band creation if needed
+ if ( topologicalEditing )
+ {
+ createTopologyRubbedBands( vlayer, vertexMap, vertex );
+ }
+ //adding point which will be moved
rb->addPoint( toMapCoordinates( mCanvas->currentLayer(), vertexMap[vertex].point ), false );
+ //setting values about added vertex
mSelectionFeature->setRubberBandValues( vertex, true, lastRubberBand, index );
vertexMap[vertex].inRubberBand = true;
index ++;
geometry->adjacentVertices( vertex, beforeVertex, vertex );
}
- if ( vertex != -1 && !vertexMap[vertex].selected ) //add last point if exists
+ if ( vertex != -1 && !vertexMap[vertex].selected ) //add last point not moving if exists
{
rb->addPoint( toMapCoordinates( mCanvas->currentLayer(), vertexMap[vertex].point ), true );
mSelectionFeature->setRubberBandValues( vertex, true, lastRubberBand, index );
@@ -173,17 +205,121 @@
}
}
+void QgsMapToolNodeTool::createTopologyRubbedBands(QgsVectorLayer* vlayer, QList<VertexEntry> vertexMap, int vertex)
+{
+ QMultiMap<double, QgsSnappingResult> currentResultList;
+ QgsGeometry* geometry = mSelectionFeature->feature()->geometry();
+ //snapp from current vertex
+ currentResultList.clear();
+ vlayer->snapWithContext( vertexMap[vertex].point, ZERO_TOLERANCE, currentResultList, QgsSnapper::SnapToVertex );
+ QMultiMap<double, QgsSnappingResult>::iterator resultIt = currentResultList.begin();
+
+ for ( ; resultIt != currentResultList.end(); ++resultIt )
+ {
+ //move all other
+ if (mSelectionFeature->featureId() != resultIt.value().snappedAtGeometry)
+ {
+ if ( mTopologyMovingVertexes.contains( resultIt.value().snappedAtGeometry) )
+ {
+ if ( mTopologyMovingVertexes[resultIt.value().snappedAtGeometry]->contains( resultIt.value().snappedVertexNr ) )
+ {
+ //skip vertex already exists in some rubberband
+ continue;
+ }
+ }
+ QgsRubberBand* trb = new QgsRubberBand( mCanvas, false );
+ mTopologyRubberBand.append( trb );
+ int rbId = mTopologyRubberBand.size() - 1;
+ trb->setWidth( 1 );
+ trb->setColor( Qt::red );
+
+ int tVertex = resultIt.value().snappedVertexNr;
+ int tVertexBackup, tVertexAfter;
+ int tVertexFirst = tVertex;//vertex number to check for cycling
+ QgsFeature topolFeature;
+
+ vlayer->featureAtId( resultIt.value().snappedAtGeometry, topolFeature, true, false );
+ QgsGeometry* topolGeometry = topolFeature.geometry();
+
+ while (tVertex != -1) //looking for first vertex to rubber band
+ {
+ tVertexBackup = tVertex;
+ topolGeometry->adjacentVertices( tVertex, tVertex, tVertexAfter );
+ if ( tVertex == -1 || tVertex == tVertexFirst )
+ break;//chceck if this is not first vertex of the feature or cycling error
+ //if closest vertex is not from selected feature or is not selected end
+ double dist;
+ QgsPoint point = topolGeometry->vertexAt(tVertex);
+ int at, before, after;
+ geometry->closestVertex( point, at, before, after, dist );
+ if ( dist > ZERO_TOLERANCE || !vertexMap[at].selected) //problem with double precision
+ {
+ break; //found first vertex
+ }
+ }
+
+ int movingPointIndex = 0;
+ Vertexes* movingPoints = new Vertexes();
+ Vertexes* addedPoints = new Vertexes();
+ if ( mTopologyMovingVertexes.contains( resultIt.value().snappedAtGeometry) )
+ {
+ addedPoints = mTopologyMovingVertexes[ resultIt.value().snappedAtGeometry ];
+ }
+ if (tVertex == -1) //adding first point if needed
+ {
+ tVertex = tVertexBackup;
+ }
+ else
+ {
+ trb->addPoint( topolGeometry->vertexAt( tVertex ) );
+ if (tVertex == tVertexFirst) //cycle first vertex need to be added also
+ {
+ movingPoints->insert( movingPointIndex );
+ }
+ movingPointIndex = 1;
+ topolGeometry->adjacentVertices( tVertex, tVertexAfter, tVertex );
+ }
+
+ while (tVertex != -1)
+ {
+ //if closest vertex is not from selected feature or is not selected end
+ double dist;
+ QgsPoint point = topolGeometry->vertexAt(tVertex);
+ int at, before, after;
+ geometry->closestVertex( point, at, before, after, dist );
+ // find first no matching vertex
+ if ( dist > ZERO_TOLERANCE || !vertexMap[at].selected ) //problem with double precision
+ {
+ trb->addPoint( topolGeometry->vertexAt( tVertex ) );
+ break; //found first vertex
+ }
+ else //add moving point to rubber band
+ {
+ if ( addedPoints->contains( tVertex ) )
+ break; //just preventing to circle
+ trb->addPoint( topolGeometry->vertexAt( tVertex ) );
+ movingPoints->insert( movingPointIndex );
+ movingPointIndex++;
+ addedPoints->insert( tVertex );
+ }
+ topolGeometry->adjacentVertices( tVertex, tVertexAfter, tVertex );
+ }
+ mTopologyMovingVertexes.insert ( resultIt.value().snappedAtGeometry, addedPoints );
+ mTopologyRubberBandVertexes.insert ( rbId, movingPoints );
+ }
+ }
+}
+
void QgsMapToolNodeTool::coordinatesChanged()
{
+ //need to update vertex markers since coordinate systems have changed
if ( mSelectionFeature != NULL )
{
mSelectionFeature->updateVertexMarkersPosition( mCanvas );
}
}
-
-
void QgsMapToolNodeTool::canvasMoveEvent( QMouseEvent * e )
{
QgsMapLayer* currentLayer = mCanvas->currentLayer();
@@ -202,8 +338,7 @@
mSelectAnother = false;
if ( mMoving )
{
-
- //create rubberband
+ //create rubberband if none exists
if ( mQgsRubberBands.empty() )
{
if ( mIsPoint )
@@ -219,14 +354,19 @@
}
}
createMovingRubberBands();
+ QList<QgsSnappingResult> snapResults;
+ QgsPoint posMapCoord = snapPointFromResults( snapResults, e->pos() );
+ mPosMapCoordBackup = posMapCoord;
}
else
{
+ //move rubber band
QList<QgsSnappingResult> snapResults;
QgsPoint firstCoords = mCanvas->getCoordinateTransform()->toMapPoint( mLastCoordinates->x(), mLastCoordinates->y() );
QList<QgsPoint> excludePoints;
excludePoints.append( mClosestVertex );
mSnapper.snapToBackgroundLayers( e->pos(), snapResults, excludePoints );
+ //get correct coordinates to move
QgsPoint posMapCoord = snapPointFromResults( snapResults, e->pos() );
if ( snapResults.size() > 0 )
{
@@ -255,7 +395,7 @@
QgsPoint mapCoords = toMapCoordinates( vlayer, vertexMap[i].point );
double x = mapCoords.x() + posMapCoord.x() - firstCoords.x();
double y = mapCoords.y() + posMapCoord.y() - firstCoords.y();
- //QgsPoint pom = toLayerCoordinates(
+
mQgsRubberBands[vertexMap[i].rubberBandNr]->movePoint( vertexMap[i].index + 1, QgsPoint( x, y ) );
if ( vertexMap[i].index == 0 )
{
@@ -263,6 +403,30 @@
}
}
}
+
+ //topological editing
+ double offsetX = posMapCoord.x() - mPosMapCoordBackup.x();
+ double offsetY = posMapCoord.y() - mPosMapCoordBackup.y();
+ for (int i = 0; i < mTopologyRubberBand.size(); i++)
+ {
+ for (int pointIndex = 0; pointIndex < mTopologyRubberBand[i]->numberOfVertices() -1; pointIndex ++ )
+ {
+ if (mTopologyRubberBandVertexes[i]->contains( pointIndex ))
+ {
+ const QgsPoint* point = mTopologyRubberBand[i]->getPoint( 0, pointIndex +1 );
+ if (point == 0)
+ {
+ break;
+ }
+ mTopologyRubberBand[i]->movePoint( pointIndex +1, QgsPoint( point->x() + offsetX, point->y() + offsetY ) );
+ if ( pointIndex == 0 )
+ {
+ mTopologyRubberBand[i]->movePoint( pointIndex , QgsPoint( point->x() + offsetX, point->y() + offsetY ) );
+ }
+ }
+ }
+ }
+ mPosMapCoordBackup = posMapCoord;
}
}
else
@@ -280,6 +444,7 @@
mQRubberBand->show();
}
}
+
}
void QgsMapToolNodeTool::connectSignals( QgsVectorLayer* vlayer )
@@ -303,11 +468,19 @@
mSelectionFeature = NULL;
return false;
}
- if ( !GEOSEquals( feat.geometry()->asGeos(), mSelectionFeature->feature()->geometry()->asGeos() ) )
+ try
{
- //update markers
- mSelectionFeature->updateFromFeature();
+ if ( !GEOSEquals( feat.geometry()->asGeos(), mSelectionFeature->feature()->geometry()->asGeos() ) )
+ {
+ //update markers when geometries are not valid
+ mSelectionFeature->updateFromFeature();
+ }
}
+ catch (...)
+ {
+ // for cases when geos throws an exception for example for invalid polygon
+ return true;
+ }
return true;
}
@@ -419,7 +592,6 @@
{
if ( mCtrl )
{
- //mSelectionFeature->invertVertexSelection( snapResult.snappedVertexNr);
mSelectionFeature->invertVertexSelection( atVertex );
}
else
@@ -520,9 +692,14 @@
mSnapper.snapToBackgroundLayers( e->pos(), snapResults, excludePoints );
coords = snapPointFromResults( snapResults, e->pos() );
//coords = mCanvas->getCoordinateTransform()->toMapPoint( e->pos().x(), e->pos().y() );
+ int topologicalEditing = QgsProject::instance()->readNumEntry( "Digitizing", "/TopologicalEditing", 0 );
if ( snapResults.size() > 0 )
{
firstCoords = toMapCoordinates( vlayer, mClosestVertex );
+ if ( topologicalEditing )
+ {
+ insertSegmentVerticesForSnap( snapResults, vlayer );
+ }
}
QgsPoint layerCoords = toLayerCoordinates( vlayer, coords );
QgsPoint layerFirstCoords = toLayerCoordinates( vlayer, firstCoords );
@@ -586,6 +763,16 @@
}
mQgsRubberBands.clear();
+ rb_it = mTopologyRubberBand.begin();
+ for ( ;rb_it != mTopologyRubberBand.end(); ++rb_it )
+ {
+ delete *rb_it;
+ }
+ mTopologyRubberBand.clear();
+
+ mTopologyMovingVertexes.clear();
+ mTopologyRubberBandVertexes.clear();
+
//remove all data from selected feature (no change to rubber bands itself
if ( mSelectionFeature != NULL )
mSelectionFeature->cleanRubberBandsData();
@@ -729,25 +916,64 @@
void SelectionFeature::deleteSelectedVertexes()
{
+ int topologicalEditing = QgsProject::instance()->readNumEntry( "Digitizing", "/TopologicalEditing", 0 );
+ QMultiMap<double, QgsSnappingResult> currentResultList;
mVlayer->beginEditCommand( QObject::tr( "Deleted vertices" ) );
int count = 0;
for ( int i = mVertexMap.size() - 1; i > -1 ; i-- )
{
if ( mVertexMap[i].selected )
{
- mVlayer->deleteVertex( mFeatureId, i );
+ if ( mVertexMap[i].equals != -1 )
+ { //to avoid try to delete some vertex twice
+ mVertexMap[mVertexMap[i].equals].selected = false;
+ }
+ if ( topologicalEditing )
+ {
+ //snapp from current vertex
+ currentResultList.clear();
+ mVlayer->snapWithContext( mVertexMap[i].point, ZERO_TOLERANCE, currentResultList, QgsSnapper::SnapToVertex );
+ }
+ if (!mVlayer->deleteVertex( mFeatureId, i ))
+ {
+ count = 0;
+ qDebug("Setting count 0 and calling break;");
+ break;
+ };
count++;
- if ( mVertexMap[i].equals != -1 && !mVertexMap[mVertexMap[i].equals].selected )
+ if ( topologicalEditing )
{
- //for polygon delete both
+ QMultiMap<double, QgsSnappingResult>::iterator resultIt = currentResultList.begin();
+
+ for ( ; resultIt != currentResultList.end(); ++resultIt )
+ {
+ //move all other
+ if (mFeatureId != resultIt.value().snappedAtGeometry)
+ mVlayer->deleteVertex( resultIt.value().snappedAtGeometry, resultIt.value().snappedVertexNr );
+ }
}
}
}
- if ( count )
+ QgsFeature f;
+ mVlayer->featureAtId( mFeatureId, f, true, false);
+ if ( !GEOSisValid( f.geometry()->asGeos() ) )
+ {
+ QMessageBox::warning( NULL,
+ tr( "Node tool" ),
+ tr( "Result geometry is invalid. Reverting last changes.\n" ),
+ QMessageBox::Ok ,
+ QMessageBox::Ok );
+ }
+
+ if ( count != 0 && GEOSisValid( f.geometry()->asGeos() ))
+ {
mVlayer->endEditCommand();
+ }
else
- mVlayer->destroyEditCommand(); // no changes...
+ {
+ mVlayer->destroyEditCommand(); // no changes... or invalid changes
+ }
updateFromFeature();
}
@@ -756,13 +982,36 @@
void SelectionFeature::moveSelectedVertexes( double changeX, double changeY )
{
mVlayer->beginEditCommand( QObject::tr( "Moved vertices" ) );
+ int topologicalEditing = QgsProject::instance()->readNumEntry( "Digitizing", "/TopologicalEditing", 0 );
+ QMultiMap<double, QgsSnappingResult> currentResultList;
for ( int i = mVertexMap.size() - 1; i > -1 ; i-- )
{
if ( mVertexMap[i].selected )
{
+ if ( topologicalEditing )
+ {
+ //snapp from current vertex
+ currentResultList.clear();
+ mVlayer->snapWithContext( mVertexMap[i].point, ZERO_TOLERANCE, currentResultList, QgsSnapper::SnapToVertex );
+ }
+
mVlayer->moveVertex( mVertexMap[i].point.x() + changeX, mVertexMap[i].point.y() + changeY, mFeatureId, i );
mVertexMap[i].point = QgsPoint( mVertexMap[i].point.x() + changeX, mVertexMap[i].point.y() + changeY );
QgsPoint point = mVertexMap[i].point;
+
+ if ( topologicalEditing )
+ {
+ QMultiMap<double, QgsSnappingResult>::iterator resultIt = currentResultList.begin();
+
+ for ( ; resultIt != currentResultList.end(); ++resultIt )
+ {
+ //move all other
+ if (mFeatureId != resultIt.value().snappedAtGeometry)
+ mVlayer->moveVertex( mVertexMap[i].point.x(), mVertexMap[i].point.y(),
+ resultIt.value().snappedAtGeometry, resultIt.value().snappedVertexNr );
+ }
+
+ }
point = mCanvas->mapRenderer()->layerToMapCoordinates( mVlayer, mVertexMap[i].point );
mVertexMap[i].vertexMarker->setCenter( point );
@@ -777,7 +1026,23 @@
}
}
}
- mVlayer->endEditCommand();
+ QgsFeature f;
+ mVlayer->featureAtId( mFeatureId, f, true, false);
+ if ( !GEOSisValid( f.geometry()->asGeos() ) )
+ {
+ QMessageBox::warning( NULL,
+ tr( "Node tool" ),
+ tr( "Result geometry is invalid. Reverting last changes.\n" ),
+ QMessageBox::Ok ,
+ QMessageBox::Ok );
+ //redo last operations
+ mVlayer->destroyEditCommand();
+ updateFromFeature();
+ }
+ else
+ {
+ mVlayer->endEditCommand();
+ }
updateFeature();
}
@@ -853,15 +1118,13 @@
}
else //multipolygon
{
- //print("Number of polygons: " + str(len(feature.geometry().asMultiPolygon())))
for ( int i2 = 0 ; i2 < mFeature->geometry()->asMultiPolygon().size(); i2++ )
- {
+ { //iterating through polygons
QgsPolygon poly2 = mFeature->geometry()->asMultiPolygon()[i2];
for ( int i3 = 0; i3 < poly2.size(); i3++ )
- {
+ { //iterating through polygon rings
QgsPolyline poly = poly2[i3];
int i;
- //print("Number of vertexes:" + str(len(poly)))
for ( i = 0; i < poly.size(); i++ )
{
VertexEntry entry;
@@ -892,6 +1155,7 @@
QgsMultiPolyline mLine = mFeature->geometry()->asMultiPolyline();
for ( int i2 = 0; i2 < mLine.size(); i2++ )
{
+ //iterating through polylines
QgsPolyline poly = mLine[i2];
int i;
for ( i = 0; i < poly.size(); i++ )
@@ -969,7 +1233,7 @@
void SelectionFeature::createVertexMap()
{
mVlayer->featureAtId( mFeatureId, *mFeature );
- //createvertexmap
+ //createvertexmap for correct geometry type
if ( mFeature->geometry()->type() == QGis::Polygon )
{
createVertexMapPolygon();
@@ -997,7 +1261,7 @@
mVertexMap[vertexNr].vertexMarker->setColor( Qt::blue );
mVertexMap[vertexNr].vertexMarker->update();
if ( mVertexMap[vertexNr].equals != -1 )
- {
+ { // select both vertexes if this is first/last vertex
mVertexMap[mVertexMap[vertexNr].equals].selected = true;
mVertexMap[mVertexMap[vertexNr].equals].vertexMarker->setColor( Qt::blue );
mVertexMap[mVertexMap[vertexNr].equals].vertexMarker->update();
@@ -1027,8 +1291,10 @@
void SelectionFeature::invertVertexSelection( int vertexNr, bool invert )
{
+ //inverting of selection of vertex
if ( mVertexMap[vertexNr].selected == false )
{
+ //case vertex is not selected
mVertexMap[vertexNr].selected = true;
mVertexMap[vertexNr].vertexMarker->setColor( Qt::blue );
mVertexMap[vertexNr].vertexMarker->update();
@@ -1056,6 +1322,7 @@
void SelectionFeature::updateVertexMarkersPosition( QgsMapCanvas* canvas )
{
+ //function for on-line updating vertex markers without refresh of canvas
for ( int i = 0; i < mVertexMap.size() ;i++ )
{
mVertexMap[i].vertexMarker->setCenter( mCanvas->mapRenderer()->layerToMapCoordinates( mVlayer, mVertexMap[i].point ) );
@@ -1080,5 +1347,3 @@
return mVlayer;
}
-
-
Modified: trunk/qgis/src/app/qgsmaptoolnodetool.h
===================================================================
--- trunk/qgis/src/app/qgsmaptoolnodetool.h 2009-07-21 22:58:36 UTC (rev 11140)
+++ trunk/qgis/src/app/qgsmaptoolnodetool.h 2009-07-22 11:31:25 UTC (rev 11141)
@@ -32,7 +32,6 @@
bool selected;
QgsPoint point;
int equals;
- //QgsRubberBand *vertexMarker;
QgsVertexMarker* vertexMarker;
bool inRubberBand;
int rubberBandNr;
@@ -41,10 +40,21 @@
};
/**
+ * Set representing set of vertex numbers
+ */
+typedef QSet<int> Vertexes;
+
+/**
+ * Constant representing zero value for distance. It's 0 because of error in double counting.
+ */
+const static double ZERO_TOLERANCE = 0.000000001;
+
+/**
* Class that supports feature which is selected/
*/
-class SelectionFeature
+class SelectionFeature: public QObject
{
+ Q_OBJECT
public:
SelectionFeature();
@@ -92,6 +102,7 @@
/**
* Inverts selection of vertex with number
* @param vertexNr number of vertex which is to be inverted
+ * @param invert flag if vertex selection should be inverted or not
*/
void invertVertexSelection( int vertexNr, bool invert = true );
@@ -200,7 +211,7 @@
QgsMapCanvas* mCanvas;
};
-/**A maptool to move/deletes/adds vertices of line or polygon fetures*/
+/**A maptool to move/deletes/adds vertices of line or polygon features*/
class QgsMapToolNodeTool: public QgsMapToolVertexEdit
{
Q_OBJECT
@@ -260,22 +271,30 @@
private:
+ /**
+ * Connects signal which are required for correct work with bakground changes
+ * @param vlayer vector layer which is emiting these signals
+ */
void connectSignals( QgsVectorLayer* vlayer );
- /** Deletes the rubber band pointers
- and clears mRubberBands*/
+ /**
+ * Deletes the rubber band pointers and clears mRubberBands
+ */
void removeRubberBands();
/**
* Creating rubber band marker for movin of point
* @param center coordinates of point to be moved
* @param vlayer vector layer on which we are working
+ * @return rubber band marker
*/
QgsRubberBand* createRubberBandMarker( QgsPoint center, QgsVectorLayer* vlayer );
/**
* Function to check if selected feature exists and is same with original one
+ * stored in internal structures
* @param vlayer vector layer for checking
+ * @return if feature is same as one in internal structures
*/
bool checkCorrectnessOfFeature( QgsVectorLayer* vlayer );
@@ -284,12 +303,29 @@
*/
void createMovingRubberBands();
+ /**
+ * Creates rubber bands for ther features when topology editing is enabled
+ * @param vlayer vector layer for ehich rubber bands are created
+ * @param vertexMap map of vertexes
+ * @param vertex currently processed vertex
+ */
+ void createTopologyRubbedBands(QgsVectorLayer* vlayer, QList<VertexEntry> vertexMap, int vertex);
+
/** The position of the vertex to move (in map coordinates) to exclude later from snapping*/
QList<QgsPoint> mExcludePoint;
/** rubber bands */
QList<QgsRubberBand*> mQgsRubberBands;
+ /** list of topology rubber bands */
+ QList<QgsRubberBand*> mTopologyRubberBand;
+
+ /** vertexes of rubberbands which are to be moved */
+ QMap<int, Vertexes*> mTopologyMovingVertexes;
+
+ /** vertexes of features with int id which were already added tu rubber bands */
+ QMap<int, Vertexes*> mTopologyRubberBandVertexes;
+
/** object containing selected feature and it's vertexes */
SelectionFeature* mSelectionFeature;
@@ -317,6 +353,9 @@
/** closest vertex to click */
QgsPoint mClosestVertex;
+ /** backup of map coordinates to be able to count change between moves */
+ QgsPoint mPosMapCoordBackup;
+
/** active rubberband for selecting vertexes */
QRubberBand* mQRubberBand;
More information about the QGIS-commit
mailing list