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
This commit is contained in:
mhugent 2008-05-21 05:59:04 +00:00
parent 61e3fe93a3
commit b849af0745
7 changed files with 63 additions and 13 deletions

View File

@ -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<QgsSnappingResult>& snappingResult);
int snapPoint(const QPoint& startPoint, QList<QgsSnappingResult>& snappingResult, const QList<QgsPoint>& excludeList);
//setters
void setLayersToSnap(const QList<QgsVectorLayer*>& layerList);

View File

@ -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<QgsRubberBand*>::iterator rb_it = mRubberBands.begin();
QList<QgsSnappingResult> 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<QgsSnappingResult> 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();
}

View File

@ -46,6 +46,9 @@ class QgsMapToolMoveVertex: public QgsMapToolVertexEdit
that no point should be moved*/
QList<int> mRubberBandMovingPoints;
/**The position of the vertex to move (in map coordinates) to exclude later from snapping*/
QList<QgsPoint> mExcludePoint;
/**Deletes the rubber band pointers
and clears mRubberBands*/
void removeRubberBands();

View File

@ -39,7 +39,7 @@ QgsSnapper::~QgsSnapper()
}
int QgsSnapper::snapPoint(const QPoint& startPoint, QList<QgsSnappingResult>& snappingResult)
int QgsSnapper::snapPoint(const QPoint& startPoint, QList<QgsSnappingResult>& snappingResult, const QList<QgsPoint>& excludePoints)
{
snappingResult.clear();
@ -84,6 +84,9 @@ int QgsSnapper::snapPoint(const QPoint& startPoint, QList<QgsSnappingResult>& sn
snappingResultList.insert(sqrt(newResult.snappedVertex.sqrDist(mapCoordPoint)), newResult);
}
}
//excluded specific points from result
cleanResultList(snappingResultList, excludePoints);
//evaluate results according to snap mode
QMultiMap<double, QgsSnappingResult>::iterator evalIt = snappingResultList.begin();
@ -137,3 +140,30 @@ void QgsSnapper::setSnapMode(QgsSnapper::SNAP_MODE snapMode)
{
mSnapMode = snapMode;
}
void QgsSnapper::cleanResultList(QMultiMap<double, QgsSnappingResult>& list, const QList<QgsPoint>& excludeList) const
{
QgsPoint currentResultPoint;
QgsSnappingResult currentSnappingResult;
QList<double> keysToRemove;
QMultiMap<double, QgsSnappingResult>::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<double>::const_iterator remove_it = keysToRemove.constBegin();
for(; remove_it != keysToRemove.constEnd(); ++remove_it)
{
list.remove(*remove_it);
}
}

View File

@ -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<QgsSnappingResult>& snappingResult);
int snapPoint(const QPoint& startPoint, QList<QgsSnappingResult>& snappingResult, const QList<QgsPoint>& excludePoints = QList<QgsPoint>());
//setters
void setLayersToSnap(const QList<QgsVectorLayer*>& 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<double, QgsSnappingResult>& list, const QList<QgsPoint>& 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;

View File

@ -58,7 +58,7 @@ void QgsMapCanvasSnapper::setMapCanvas(QgsMapCanvas* canvas)
}
}
int QgsMapCanvasSnapper::snapToCurrentLayer(const QPoint& p, QList<QgsSnappingResult>& results, QgsSnapper::SNAP_TO snap_to, double snappingTol)
int QgsMapCanvasSnapper::snapToCurrentLayer(const QPoint& p, QList<QgsSnappingResult>& results, QgsSnapper::SNAP_TO snap_to, double snappingTol, const QList<QgsPoint>& excludePoints)
{
results.clear();
@ -112,7 +112,7 @@ int QgsMapCanvasSnapper::snapToCurrentLayer(const QPoint& p, QList<QgsSnappingRe
mSnapper->setTolerances(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<QgsSnappingRe
}
}
int QgsMapCanvasSnapper::snapToBackgroundLayers(const QPoint& p, QList<QgsSnappingResult>& results)
int QgsMapCanvasSnapper::snapToBackgroundLayers(const QPoint& p, QList<QgsSnappingResult>& results, const QList<QgsPoint>& excludePoints)
{
results.clear();
@ -252,7 +252,7 @@ int QgsMapCanvasSnapper::snapToBackgroundLayers(const QPoint& p, QList<QgsSnappi
mSnapper->setTolerances(toleranceDoubleList);
mSnapper->setSnapToList(snapTo);
if(mSnapper->snapPoint(p, results) != 0)
if(mSnapper->snapPoint(p, results, excludePoints) != 0)
{
return 4;
}

View File

@ -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<QgsSnappingResult>& 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<QgsSnappingResult>& results, QgsSnapper::SNAP_TO snap_to, double snappingTol = -1, const QList<QgsPoint>& excludePoints = QList<QgsPoint>());
/**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<QgsSnappingResult>& results);
int snapToBackgroundLayers(const QPoint& p, QList<QgsSnappingResult>& results, const QList<QgsPoint>& excludePoints = QList<QgsPoint>());
void setMapCanvas(QgsMapCanvas* canvas);