Skip to content
Permalink
Browse files
Improved rubber banding for vertex editing. Still buggy for multipoly…
…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.
@@ -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)
{
@@ -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:
@@ -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);
}
@@ -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;
@@ -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;
}
@@ -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;
@@ -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:
{
@@ -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:
{
@@ -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;
@@ -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:
{
@@ -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;
@@ -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);
@@ -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
{
@@ -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)
@@ -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);
@@ -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);
}

}
@@ -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)
{
@@ -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)
{
@@ -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)
{
@@ -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;
@@ -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;
@@ -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;

0 comments on commit 02d951a

Please sign in to comment.