Skip to content

Commit

Permalink
Improved rubber banding for vertex editing. Still buggy for multipoly…
Browse files Browse the repository at this point in the history
…gons

git-svn-id: http://svn.osgeo.org/qgis/trunk/qgis@5535 c8812cc2-4d05-0410-92ff-de0c093fc19c
  • Loading branch information
mhugent committed Jun 20, 2006
1 parent 2b4fef5 commit 02d951a
Show file tree
Hide file tree
Showing 6 changed files with 155 additions and 58 deletions.
90 changes: 76 additions & 14 deletions src/core/qgsgeometry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ void QgsGeometry::setGeos(geos::Geometry* geos)

}

QgsPoint QgsGeometry::closestVertex(const QgsPoint& point, QgsGeometryVertexIndex& atVertex, double& sqrDist) const
QgsPoint QgsGeometry::closestVertex(const QgsPoint& point, QgsGeometryVertexIndex& atVertex, int& beforeVertex, int& afterVertex, double& sqrDist) const
{
if(mDirtyWkb)
{
Expand All @@ -230,6 +230,9 @@ QgsPoint QgsGeometry::closestVertex(const QgsPoint& point, QgsGeometryVertexInde
double x,y;
double *tempx,*tempy;
memcpy(&wkbType, (mGeometry+1), sizeof(int));
beforeVertex = -1;
afterVertex = -1;

switch (wkbType)
{
case QGis::WKBPoint:
Expand All @@ -255,6 +258,22 @@ QgsPoint QgsGeometry::closestVertex(const QgsPoint& point, QgsGeometryVertexInde
y=*tempy;
actdist=point.sqrDist(*tempx,*tempy);
vertexnr = index;
if(index == 0)//assign the rubber band indices
{
beforeVertex = -1;
}
else
{
beforeVertex = index-1;
}
if(index == (*npoints - 1))
{
afterVertex = -1;
}
else
{
afterVertex = index+1;
}
}
ptr+=sizeof(double);
}
Expand All @@ -280,6 +299,22 @@ QgsPoint QgsGeometry::closestVertex(const QgsPoint& point, QgsGeometryVertexInde
y=*tempy;
actdist=point.sqrDist(*tempx,*tempy);
vertexnr = vertexcounter;
//assign the rubber band indices
if(index2 == 0)
{
beforeVertex = vertexcounter+(*npoints-2);
afterVertex = vertexcounter+1;
}
else if(index2 == (*npoints-1))
{
beforeVertex = vertexcounter-1;
afterVertex = vertexcounter - (*npoints-2);
}
else
{
beforeVertex = vertexcounter-1;
afterVertex = vertexcounter+1;
}
}
ptr+=sizeof(double);
++vertexcounter;
Expand Down Expand Up @@ -333,6 +368,23 @@ QgsPoint QgsGeometry::closestVertex(const QgsPoint& point, QgsGeometryVertexInde
y=*tempy;
actdist=point.sqrDist(*tempx,*tempy);
vertexnr = vertexcounter;

if(index2 == 0)//assign the rubber band indices
{
beforeVertex = -1;
}
else
{
beforeVertex = vertexnr-1;
}
if(index2 == (*npoints)-1)
{
afterVertex = -1;
}
else
{
afterVertex = vertexnr+1;
}
}
++vertexcounter;
}
Expand Down Expand Up @@ -367,6 +419,23 @@ QgsPoint QgsGeometry::closestVertex(const QgsPoint& point, QgsGeometryVertexInde
y=*tempy;
actdist=point.sqrDist(*tempx,*tempy);
vertexnr = vertexcounter;

//assign the rubber band indices
if(index3 == 0)
{
beforeVertex = vertexcounter+(*npoints-2);
afterVertex = vertexcounter+1;
}
else if(index3 == (*npoints-1))
{
beforeVertex = vertexcounter-1;
afterVertex = vertexcounter - (*npoints-2);
}
else
{
beforeVertex = vertexcounter-1;
afterVertex = vertexcounter+1;
}
}
ptr+=sizeof(double);
++vertexcounter;
Expand Down Expand Up @@ -1101,12 +1170,12 @@ bool QgsGeometry::vertexAt(double &x, double &y,
memcpy(&x, ptr, sizeof(double));
ptr += sizeof(double);
memcpy(&y, ptr, sizeof(double));
return true;
}
else
{
return FALSE;
}
break;
}
case QGis::WKBLineString:
{
Expand All @@ -1125,7 +1194,7 @@ bool QgsGeometry::vertexAt(double &x, double &y,
memcpy(&x, ptr, sizeof(double));
ptr += sizeof(double);
memcpy(&y, ptr, sizeof(double));
break;
return true;
}
case QGis::WKBPolygon:
{
Expand All @@ -1146,7 +1215,7 @@ bool QgsGeometry::vertexAt(double &x, double &y,
memcpy(&x, ptr, sizeof(double));
ptr += sizeof(double);
memcpy(&y, ptr, sizeof(double));
break;
return true;
}
ptr += 2*sizeof(double);
++pointindex;
Expand All @@ -1167,7 +1236,7 @@ bool QgsGeometry::vertexAt(double &x, double &y,
memcpy(&x, ptr, sizeof(double));
ptr += sizeof(double);
memcpy(&y, ptr, sizeof(double));
break;
return true;
}
case QGis::WKBMultiLineString:
{
Expand All @@ -1188,7 +1257,7 @@ bool QgsGeometry::vertexAt(double &x, double &y,
memcpy(&x, ptr, sizeof(double));
ptr += sizeof(double);
memcpy(&y, ptr, sizeof(double));
break;
return true;
}
ptr += 2*sizeof(double);
++pointindex;
Expand Down Expand Up @@ -1219,7 +1288,7 @@ bool QgsGeometry::vertexAt(double &x, double &y,
memcpy(&x, ptr, sizeof(double));
ptr += sizeof(double);
memcpy(&y, ptr, sizeof(double));
break;
return true;
}
++pointindex;
ptr += 2*sizeof(double);
Expand All @@ -1235,13 +1304,6 @@ bool QgsGeometry::vertexAt(double &x, double &y,
return false;
break;
}

#ifdef QGISDEBUG
std::cout << "QgsGeometry::vertexAt: Exiting TRUE." << std::endl;
#endif

return true;

}
else
{
Expand Down
4 changes: 2 additions & 2 deletions src/core/qgsgeometry.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,9 @@ class QgsGeometry {
void setGeos(geos::Geometry* geos);

/**
Returns the vertex closest to the given point (and also vertex index and squared distance)
Returns the vertex closest to the given point (and also vertex index, squared distance and indexes of the vertices before/after)
*/
QgsPoint closestVertex(const QgsPoint& point, QgsGeometryVertexIndex& atVertex, double& sqrDist) const;
QgsPoint closestVertex(const QgsPoint& point, QgsGeometryVertexIndex& atVertex, int& beforeVertex, int& afterVertex, double& sqrDist) const;

/** Insert a new vertex before the given vertex index,
* ring and item (first number is index 0)
Expand Down
76 changes: 45 additions & 31 deletions src/gui/qgsmaptoolvertexedit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@


QgsMapToolVertexEdit::QgsMapToolVertexEdit(QgsMapCanvas* canvas, enum Tool tool)
: QgsMapTool(canvas), mTool(tool), mRubberBand(0)
: QgsMapTool(canvas), mTool(tool), mRubberBandIndex1(-1), mRubberBandIndex2(-1), mRubberBand(0)
{
// TODO - select a real cursor
QPixmap mySelectQPixmap = QPixmap((const char **) capture_point_cursor);
Expand All @@ -47,19 +47,35 @@ void QgsMapToolVertexEdit::canvasMoveEvent(QMouseEvent * e)
{
if (e->buttons() == Qt::LeftButton && (mTool == AddVertex || mTool == MoveVertex))
{
int index = (mStartPointValid ? 1 : 0);
//int index = (mStartPointValid ? 1 : 0);
int index;
if(mTool == MoveVertex)
{
if(mRubberBandIndex1 == -1)
{
index = 0;
}
else
{
index = 1;
}
}
else
{
index = 1;
}

//snap to nearest vertex of vectorlayer
QgsPoint rbpoint = toMapCoords(e->pos());
if(mTool == AddVertex)
{
snapVertex(rbpoint, mSnappedAtFeatureId, mSnappedBeforeVertex.back());
mRubberBand->movePoint(index, rbpoint);
}
else if(mTool == MoveVertex)
{
snapVertex(rbpoint, mSnappedAtFeatureId, mSnappedAtVertex.back());
mRubberBand->movePoint(index, rbpoint);
}
mRubberBand->movePoint(index, rbpoint);
}

}
Expand All @@ -71,7 +87,7 @@ void QgsMapToolVertexEdit::canvasPressEvent(QMouseEvent * e)

double x1, y1;
double x2, y2;
QgsGeometryVertexIndex index;
QgsGeometryVertexIndex index, rb1Index, rb2Index; //rb1Index/rb2Index is for rubberbanding

if (mTool == AddVertex)
{
Expand All @@ -89,25 +105,23 @@ void QgsMapToolVertexEdit::canvasPressEvent(QMouseEvent * e)
QMessageBox::Ok, Qt::NoButton);
return;
}

index = mSnappedBeforeVertex;

index = mSnappedBeforeVertex;
// Get the endpoint of the snapped-to segment
mSnappedAtGeometry.vertexAt(x2, y2, index);

// Get the startpoint of the snapped-to segment
index.decrement_back();
mStartPointValid = mSnappedAtGeometry.vertexAt(x1, y1, index);

createRubberBand();

if (mStartPointValid)
{
mRubberBand->addPoint(QgsPoint(x1,y1));
}
mRubberBand->addPoint(toMapCoords(e->pos()));
mRubberBand->addPoint(QgsPoint(x2,y2));

}
else if (mTool == MoveVertex)
{
Expand All @@ -126,33 +140,32 @@ void QgsMapToolVertexEdit::canvasPressEvent(QMouseEvent * e)
return;
}

#ifdef QGISDEBUG
qWarning("Creating rubber band for moveVertex");
#endif

index = mSnappedAtVertex;

// Get the startpoint of the rubber band, as the previous vertex to the snapped-to one.
index.decrement_back();
mStartPointValid = mSnappedAtGeometry.vertexAt(x1, y1, index);

// Get the endpoint of the rubber band, as the following vertex to the snapped-to one.
index.increment_back();
index.increment_back();
mStopPointValid = mSnappedAtGeometry.vertexAt(x2, y2, index);

createRubberBand();

if (mStartPointValid)
if(mRubberBandIndex1 != -1)
{
rb1Index.push_back(mRubberBandIndex1);
mSnappedAtGeometry.vertexAt(x1, y1, rb1Index);
mRubberBand->addPoint(QgsPoint(x1,y1));
mStartPointValid = true;
}
mRubberBand->addPoint(toMapCoords(e->pos()));
if (mStopPointValid)
else
{
mStartPointValid = false;
}
if(mRubberBandIndex1 != -1 && mRubberBandIndex2 != -1)
{
mRubberBand->addPoint(toMapCoords(e->pos()));
}
if(mRubberBandIndex2 != -1)
{
rb2Index.push_back(mRubberBandIndex2);
mSnappedAtGeometry.vertexAt(x2, y2, rb2Index);
mRubberBand->addPoint(QgsPoint(x2,y2));
}

#ifdef QGISDEBUG
qWarning("Creating rubber band for moveVertex");
#endif
}
else if (mTool == DeleteVertex)
{
Expand Down Expand Up @@ -234,7 +247,7 @@ bool QgsMapToolVertexEdit::snapVertexWithContext(QgsPoint& point)
if (!vlayer)
return FALSE;

if (!vlayer->snapVertexWithContext(point, atVertex, atFeatureId, atGeometry, tolerance()))
if (!vlayer->snapVertexWithContext(point, atVertex, mRubberBandIndex1, mRubberBandIndex2, atFeatureId, atGeometry, tolerance()))
{
mSnappedAtFeatureId = -1;
return FALSE;
Expand All @@ -260,10 +273,11 @@ bool QgsMapToolVertexEdit::snapVertex(QgsPoint& point, int exclFeatureId, int ex
{
QgsGeometryVertexIndex vIndex;
int snappedFeatureId;
int rbPoint1, rbPoint2;
QgsGeometry snappedGeometry;
//do the snapping to a copy point first
QgsPoint cpyPoint = point;
vlayer->snapVertexWithContext(cpyPoint, vIndex, snappedFeatureId, snappedGeometry, tolerance());
vlayer->snapVertexWithContext(cpyPoint, vIndex, rbPoint1, rbPoint2, snappedFeatureId, snappedGeometry, tolerance());
if(snappedFeatureId != exclFeatureId || vIndex.back() != exclVertexNr)
{
point = cpyPoint;
Expand Down
6 changes: 6 additions & 0 deletions src/gui/qgsmaptoolvertexedit.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,12 @@ class QgsMapToolVertexEdit : public QgsMapTool
//! The snapped-to segment before this vertex number (identifying the vertex that is being moved)
QgsGeometryVertexIndex mSnappedAtVertex;

/**The index of the first rubber band point (to connect to mSnappedatVertex). -1 if no such point exists*/
int mRubberBandIndex1;

/**The index of the second rubber band point (to connect to mSnappedatVertex). -1 if no such point exists*/
int mRubberBandIndex2;

//! The snapped-to segment before this vertex number (identifying the segment that a new vertex is being added to)
QgsGeometryVertexIndex mSnappedBeforeVertex;

Expand Down
Loading

0 comments on commit 02d951a

Please sign in to comment.