Navigation Menu

Skip to content

Commit

Permalink
Fix for vertex editing bug where already changed geometries have not …
Browse files Browse the repository at this point in the history
…been examined for point snapping

git-svn-id: http://svn.osgeo.org/qgis/trunk/qgis@5410 c8812cc2-4d05-0410-92ff-de0c093fc19c
  • Loading branch information
mhugent committed May 1, 2006
1 parent b09f135 commit 3d58d3d
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 19 deletions.
48 changes: 39 additions & 9 deletions src/gui/qgsmaptoolvertexedit.cpp
Expand Up @@ -76,9 +76,13 @@ void QgsMapToolVertexEdit::canvasPressEvent(QMouseEvent * e)
std::cout << "QgsMapCanvas::mousePressEvent: QGis::AddVertex." << std::endl;
#endif

// TODO: Find nearest segment of the selected line, move that node to the mouse location
//Find nearest segment of the selected line, move that node to the mouse location
if (!snapSegmentWithContext(point))
return;
{
QMessageBox::warning(0, "Error", "Could not snap vertex. Have you set the tolerance?",
QMessageBox::Ok, Qt::NoButton);
return;
}

index = mSnappedBeforeVertex;

Expand Down Expand Up @@ -108,9 +112,13 @@ void QgsMapToolVertexEdit::canvasPressEvent(QMouseEvent * e)
// Find the closest line segment to the mouse position
// Then set up the rubber band to its endpoints

// TODO: Find nearest segment of the selected line, move that node to the mouse location
//Find nearest segment of the selected line, move that node to the mouse location
if (!snapVertexWithContext(point))
return;
{
QMessageBox::warning(0, "Error", "Could not snap vertex. Have you set the tolerance?",
QMessageBox::Ok, Qt::NoButton);
return;
}

#ifdef QGISDEBUG
qWarning("Creating rubber band for moveVertex");
Expand Down Expand Up @@ -150,7 +158,11 @@ void QgsMapToolVertexEdit::canvasPressEvent(QMouseEvent * e)

// TODO: Find nearest segment of the selected line, move that node to the mouse location
if (!snapVertexWithContext(point))
return;
{
QMessageBox::warning(0, "Error", "Could not snap vertex. Have you set the tolerance?",
QMessageBox::Ok, Qt::NoButton);
return;
}

// Get the point of the snapped-to vertex
mSnappedAtGeometry.vertexAt(x1, y1, mSnappedAtVertex);
Expand Down Expand Up @@ -219,8 +231,6 @@ bool QgsMapToolVertexEdit::snapVertexWithContext(QgsPoint& point)
if (!vlayer->snapVertexWithContext(point, atVertex, atFeatureId, atGeometry, tolerance()))
{
mSnappedAtFeatureId = -1;
QMessageBox::warning(0, "Error", "Could not snap vertex. Have you set the tolerance?",
QMessageBox::Ok, Qt::NoButton);
return FALSE;
}
else
Expand All @@ -237,6 +247,24 @@ bool QgsMapToolVertexEdit::snapVertexWithContext(QgsPoint& point)
}
}

bool QgsMapToolVertexEdit::snapVertex(QgsPoint& point, int exclFeatureId, int exclVertexNr)
{
QgsVectorLayer* vlayer = dynamic_cast<QgsVectorLayer*>(mCanvas->currentLayer());
if(vlayer)
{
QgsGeometryVertexIndex vIndex;
int snappedFeatureId;
QgsGeometry snappedGeometry;
//do the snapping to a copy point first
QgsPoint cpyPoint = point;
vlayer->snapVertexWithContext(cpyPoint, vIndex, snappedFeatureId, snappedGeometry, tolerance());
if(snappedFeatureId != exclFeatureId || vIndex.back() != exclVertexNr)
{
point = cpyPoint;
}
}
}


void QgsMapToolVertexEdit::canvasReleaseEvent(QMouseEvent * e)
{
Expand Down Expand Up @@ -274,6 +302,8 @@ void QgsMapToolVertexEdit::canvasReleaseEvent(QMouseEvent * e)
if (mTool == AddVertex)
{

//snap to nearest vertex of vectorlayer
snapVertex(point, mSnappedAtFeatureId, mSnappedBeforeVertex.back());
#ifdef QGISDEBUG
std::cout << "QgsMapToolVertexEdit::canvasReleaseEvent: AddVertex." << std::endl;
#endif
Expand All @@ -282,19 +312,19 @@ void QgsMapToolVertexEdit::canvasReleaseEvent(QMouseEvent * e)
mRubberBand = 0;

// Add the new vertex
//todo: snap to nearest vertex of vectorlayer
vlayer->insertVertexBefore(point.x(), point.y(), mSnappedAtFeatureId, mSnappedBeforeVertex);
mCanvas->refresh();
}
else if (mTool == MoveVertex)
{
//snap to nearest vertex of vectorlayer
snapVertex(point, mSnappedAtFeatureId, mSnappedAtVertex.back());
#ifdef QGISDEBUG
std::cout << "QgsMapToolVertexEdit::canvasReleaseEvent: MoveVertex." << std::endl;
#endif

delete mRubberBand;
mRubberBand = 0;
//todo: snap to nearest vertex of vectorlayer
vlayer->moveVertexAt(point.x(), point.y(), mSnappedAtFeatureId, mSnappedAtVertex);
mCanvas->refresh();
}
Expand Down
5 changes: 5 additions & 0 deletions src/gui/qgsmaptoolvertexedit.h
Expand Up @@ -61,7 +61,12 @@ class QgsMapToolVertexEdit : public QgsMapTool
//! current vertex edit tool
enum Tool mTool;

/**Searches the closest point within the project tolerance and setx mSnappedAtFeatureId and mSnappedAtVertex*/
bool snapVertexWithContext(QgsPoint& point);

/**Snaps a point (without setting mSnappedAtFeatureId and mSnappedAtVertex). Does not snap to the specified vertex,
because during dragging, a vertex should not be snapped to itself*/
bool snapVertex(QgsPoint& point, int exclFeatureId, int exclVertexNr);

bool snapSegmentWithContext(QgsPoint& point);

Expand Down
49 changes: 39 additions & 10 deletions src/gui/qgsvectorlayer.cpp
Expand Up @@ -1679,7 +1679,7 @@ bool QgsVectorLayer::moveVertexAt(double x, double y, int atFeatureId,
if(mChangedGeometries.find(atFeatureId) == mChangedGeometries.end())
{
// first time this geometry has changed since last commit
if(!mCachedGeometries[atFeatureId])
if(mCachedGeometries.find(atFeatureId) == mCachedGeometries.end() || mCachedGeometries[atFeatureId] == 0)
{
return false;
}
Expand Down Expand Up @@ -2802,7 +2802,7 @@ bool QgsVectorLayer::snapVertexWithContext(QgsPoint& point, QgsGeometryVertexInd
}

QgsFeature* feature;
QgsPoint minDistSegPoint; // the closest point on the segment
QgsPoint minDistSegPoint; // the closest point
double testSqrDist; // the squared distance between 'point' and 'snappedFeature'

double minSqrDist = tolerance*tolerance; //current minimum distance
Expand Down Expand Up @@ -2830,6 +2830,8 @@ bool QgsVectorLayer::snapVertexWithContext(QgsPoint& point, QgsGeometryVertexInd
snappedFeatureId = feature->featureId();
snappedGeometry = *(feature->geometry());
vertexFound = true;
delete feature;
return true;
}
delete feature;
}
Expand All @@ -2855,14 +2857,27 @@ bool QgsVectorLayer::snapVertexWithContext(QgsPoint& point, QgsGeometryVertexInd
snappedFeatureId = (*iter)->featureId();
snappedGeometry = *((*iter)->geometry());
vertexFound = true;
return true;
}
}

if(!vertexFound)
//and also go through the changed geometries, because the spatial filter of the provider did not consider feature changes
for(std::map<int, QgsGeometry>::iterator it = mChangedGeometries.begin(); it != mChangedGeometries.end(); ++it)
{
return false;
minDistSegPoint = it->second.closestVertex(origPoint, atVertexTemp, testSqrDist);
if(testSqrDist < minSqrDist)
{
point = minDistSegPoint;
minSqrDist = testSqrDist;
atVertex = atVertexTemp;
snappedFeatureId = it->first;
snappedGeometry = it->second;
vertexFound = true;
return true;
}
}
return true;

return false;
}


Expand Down Expand Up @@ -2909,6 +2924,8 @@ QgsGeometry& snappedGeometry, double tolerance)
snappedFeatureId = feature->featureId();
snappedGeometry = *(feature->geometry());
segmentFound = true;
delete feature;
return true;
}
delete feature;
}
Expand All @@ -2935,14 +2952,26 @@ QgsGeometry& snappedGeometry, double tolerance)
snappedFeatureId = (*iter)->featureId();
snappedGeometry = *((*iter)->geometry());
segmentFound = true;
return true;
}
}

if(!segmentFound)
{
return false;
}
return true;
//and also go through the changed geometries, because the spatial filter of the provider did not consider feature changes
for(std::map<int, QgsGeometry>::iterator it = mChangedGeometries.begin(); it != mChangedGeometries.end(); ++it)
{
minDistSegPoint = it->second.closestSegmentWithContext(origPoint, beforeVertexTemp, testSqrDist);
if(testSqrDist < minSqrDist)
{
point = minDistSegPoint;
minSqrDist = testSqrDist;
beforeVertex = beforeVertexTemp;
snappedFeatureId = it->first;
snappedGeometry = it->second;
segmentFound = true;
return true;
}
}
return false;
}


Expand Down

0 comments on commit 3d58d3d

Please sign in to comment.