From b849af0745cc8c4a77e71984da260aef7df27a82 Mon Sep 17 00:00:00 2001 From: mhugent Date: Wed, 21 May 2008 05:59:04 +0000 Subject: [PATCH] Fix for bug #1096 Snapping to currently moved vertex should be suppressed git-svn-id: http://svn.osgeo.org/qgis/trunk@8477 c8812cc2-4d05-0410-92ff-de0c093fc19c --- python/core/qgssnapper.sip | 2 +- src/app/qgsmaptoolmovevertex.cpp | 16 +++++++++++++--- src/app/qgsmaptoolmovevertex.h | 3 +++ src/core/qgssnapper.cpp | 32 +++++++++++++++++++++++++++++++- src/core/qgssnapper.h | 7 ++++++- src/gui/qgsmapcanvassnapper.cpp | 8 ++++---- src/gui/qgsmapcanvassnapper.h | 8 +++++--- 7 files changed, 63 insertions(+), 13 deletions(-) diff --git a/python/core/qgssnapper.sip b/python/core/qgssnapper.sip index 721458c5ac6..f3345982631 100644 --- a/python/core/qgssnapper.sip +++ b/python/core/qgssnapper.sip @@ -63,7 +63,7 @@ public: @param startPoint the start point for snapping (in pixel coordinates) @param snappingResult the list where the results are inserted (everything in map coordinate system) @return 0 in case of success*/ - int snapPoint(const QPoint& startPoint, QList& snappingResult); + int snapPoint(const QPoint& startPoint, QList& snappingResult, const QList& excludeList); //setters void setLayersToSnap(const QList& layerList); diff --git a/src/app/qgsmaptoolmovevertex.cpp b/src/app/qgsmaptoolmovevertex.cpp index 435bf634cbb..208db451b1b 100644 --- a/src/app/qgsmaptoolmovevertex.cpp +++ b/src/app/qgsmaptoolmovevertex.cpp @@ -34,6 +34,11 @@ QgsMapToolMoveVertex::~QgsMapToolMoveVertex() void QgsMapToolMoveVertex::canvasMoveEvent(QMouseEvent * e) { + if(mRecentSnappingResults.size() < 1) + { + return ; //snapping not necessary + } + //list of rubber bands, snapping results and point index to move //must have equal size int rbSize = mRubberBands.size(); @@ -51,7 +56,8 @@ void QgsMapToolMoveVertex::canvasMoveEvent(QMouseEvent * e) QList::iterator rb_it = mRubberBands.begin(); QList snapResults; - if(mSnapper.snapToBackgroundLayers(e->pos(), snapResults) != 0) + + if(mSnapper.snapToBackgroundLayers(e->pos(), snapResults, mExcludePoint) != 0) { return; //error, bail out } @@ -119,7 +125,10 @@ void QgsMapToolMoveVertex::canvasPressEvent(QMouseEvent * e) mRubberBands.push_back(rb); } - //create rubber band list for snapping results + if(mRecentSnappingResults.size() > 0) + { + mExcludePoint.push_back(mRecentSnappingResults.first().snappedVertex); + } } void QgsMapToolMoveVertex::canvasReleaseEvent(QMouseEvent * e) @@ -138,7 +147,7 @@ void QgsMapToolMoveVertex::canvasReleaseEvent(QMouseEvent * e) QgsPoint snappedPointLayerCoord; QList snapResults; - if(mSnapper.snapToBackgroundLayers(e->pos(), snapResults) != 0) + if(mSnapper.snapToBackgroundLayers(e->pos(), snapResults, mExcludePoint) != 0) { //error } @@ -171,6 +180,7 @@ void QgsMapToolMoveVertex::canvasReleaseEvent(QMouseEvent * e) mRecentSnappingResults.clear(); mRubberBandMovingPoints.clear(); + mExcludePoint.clear(); mCanvas->refresh(); } diff --git a/src/app/qgsmaptoolmovevertex.h b/src/app/qgsmaptoolmovevertex.h index 755a5a5acdb..4c251bb1df6 100644 --- a/src/app/qgsmaptoolmovevertex.h +++ b/src/app/qgsmaptoolmovevertex.h @@ -46,6 +46,9 @@ class QgsMapToolMoveVertex: public QgsMapToolVertexEdit that no point should be moved*/ QList mRubberBandMovingPoints; + /**The position of the vertex to move (in map coordinates) to exclude later from snapping*/ + QList mExcludePoint; + /**Deletes the rubber band pointers and clears mRubberBands*/ void removeRubberBands(); diff --git a/src/core/qgssnapper.cpp b/src/core/qgssnapper.cpp index a75141c6b4a..6d9356b8094 100644 --- a/src/core/qgssnapper.cpp +++ b/src/core/qgssnapper.cpp @@ -39,7 +39,7 @@ QgsSnapper::~QgsSnapper() } -int QgsSnapper::snapPoint(const QPoint& startPoint, QList& snappingResult) +int QgsSnapper::snapPoint(const QPoint& startPoint, QList& snappingResult, const QList& excludePoints) { snappingResult.clear(); @@ -84,6 +84,9 @@ int QgsSnapper::snapPoint(const QPoint& startPoint, QList& sn snappingResultList.insert(sqrt(newResult.snappedVertex.sqrDist(mapCoordPoint)), newResult); } } + + //excluded specific points from result + cleanResultList(snappingResultList, excludePoints); //evaluate results according to snap mode QMultiMap::iterator evalIt = snappingResultList.begin(); @@ -137,3 +140,30 @@ void QgsSnapper::setSnapMode(QgsSnapper::SNAP_MODE snapMode) { mSnapMode = snapMode; } + +void QgsSnapper::cleanResultList(QMultiMap& list, const QList& excludeList) const +{ + QgsPoint currentResultPoint; + QgsSnappingResult currentSnappingResult; + QList keysToRemove; + + QMultiMap::iterator result_it = list.begin(); + for(; result_it != list.end(); ++result_it) + { + currentSnappingResult = result_it.value(); + if(currentSnappingResult.snappedVertexNr != -1) + { + currentResultPoint = currentSnappingResult.snappedVertex; + if(excludeList.contains(currentResultPoint)) + { + keysToRemove.push_back(result_it.key()); + } + } + } + + QList::const_iterator remove_it = keysToRemove.constBegin(); + for(; remove_it != keysToRemove.constEnd(); ++remove_it) + { + list.remove(*remove_it); + } +} diff --git a/src/core/qgssnapper.h b/src/core/qgssnapper.h index 0b759f920cb..519cb9335a7 100644 --- a/src/core/qgssnapper.h +++ b/src/core/qgssnapper.h @@ -81,8 +81,9 @@ class CORE_EXPORT QgsSnapper /**Does the snapping operation @param startPoint the start point for snapping (in pixel coordinates) @param snappingResult the list where the results are inserted (everything in map coordinate system) + @param excludePoints a list with (map coordinate) points that should be excluded in the snapping result. Useful e.g. for vertex moves where a vertex should not be snapped to its original position @return 0 in case of success*/ - int snapPoint(const QPoint& startPoint, QList& snappingResult); + int snapPoint(const QPoint& startPoint, QList& snappingResult, const QList& excludePoints = QList()); //setters void setLayersToSnap(const QList& layerList); @@ -93,6 +94,10 @@ class CORE_EXPORT QgsSnapper private: /**Don't use the default constructor*/ QgsSnapper(); + + /**Removes the snapping results that contains points in exclude list*/ + void cleanResultList(QMultiMap& list, const QList& excludeList) const; + /**The maprender object contains information about the output coordinate system of the map and about the relationship between pixel space and map space*/ QgsMapRender* mMapRender; diff --git a/src/gui/qgsmapcanvassnapper.cpp b/src/gui/qgsmapcanvassnapper.cpp index a27e2bc7c2f..cc43285af59 100644 --- a/src/gui/qgsmapcanvassnapper.cpp +++ b/src/gui/qgsmapcanvassnapper.cpp @@ -58,7 +58,7 @@ void QgsMapCanvasSnapper::setMapCanvas(QgsMapCanvas* canvas) } } -int QgsMapCanvasSnapper::snapToCurrentLayer(const QPoint& p, QList& results, QgsSnapper::SNAP_TO snap_to, double snappingTol) +int QgsMapCanvasSnapper::snapToCurrentLayer(const QPoint& p, QList& results, QgsSnapper::SNAP_TO snap_to, double snappingTol, const QList& excludePoints) { results.clear(); @@ -112,7 +112,7 @@ int QgsMapCanvasSnapper::snapToCurrentLayer(const QPoint& p, QListsetTolerances(toleranceList); mSnapper->setSnapToList(snapToList); - if(mSnapper->snapPoint(p, results) != 0) + if(mSnapper->snapPoint(p, results, excludePoints) != 0) { return 4; } @@ -125,7 +125,7 @@ int QgsMapCanvasSnapper::snapToCurrentLayer(const QPoint& p, QList& results) +int QgsMapCanvasSnapper::snapToBackgroundLayers(const QPoint& p, QList& results, const QList& excludePoints) { results.clear(); @@ -252,7 +252,7 @@ int QgsMapCanvasSnapper::snapToBackgroundLayers(const QPoint& p, QListsetTolerances(toleranceDoubleList); mSnapper->setSnapToList(snapTo); - if(mSnapper->snapPoint(p, results) != 0) + if(mSnapper->snapPoint(p, results, excludePoints) != 0) { return 4; } diff --git a/src/gui/qgsmapcanvassnapper.h b/src/gui/qgsmapcanvassnapper.h index 3def90f08aa..558aba9dd8b 100644 --- a/src/gui/qgsmapcanvassnapper.h +++ b/src/gui/qgsmapcanvassnapper.h @@ -48,16 +48,18 @@ class GUI_EXPORT QgsMapCanvasSnapper @param p start point of the snap (in pixel coordinates) @param results list to which the results are appended @param snap_to snap to vertex or to segment - @param snappingTol snapping tolerance. -1 means that the search radius for vertex edits is taken*/ - int snapToCurrentLayer(const QPoint& p, QList& results, QgsSnapper::SNAP_TO snap_to, double snappingTol = -1); + @param snappingTol snapping tolerance. -1 means that the search radius for vertex edits is taken + @param excludePoints a list with (map coordinate) points that should be excluded in the snapping result. Useful e.g. for vertex moves where a vertex should not be snapped to its original position*/ + int snapToCurrentLayer(const QPoint& p, QList& results, QgsSnapper::SNAP_TO snap_to, double snappingTol = -1, const QList& excludePoints = QList()); /**Snaps to the background layers. This method is usefull to align the features of the edited layers to those of other layers (as described in the project properties). Uses snap mode QgsSnapper::ONE_RESULT. Therefore, only the closest result is returned. @param p start point of the snap (in pixel coordinates) @param result snapped point + @param excludePoints a list with (map coordinate) points that should be excluded in the snapping result. Useful e.g. for vertex moves where a vertex should not be snapped to its original position @return 0 in case of success*/ - int snapToBackgroundLayers(const QPoint& p, QList& results); + int snapToBackgroundLayers(const QPoint& p, QList& results, const QList& excludePoints = QList()); void setMapCanvas(QgsMapCanvas* canvas);