Skip to content

Commit 02d951a

Browse files
author
mhugent
committedJun 20, 2006
Improved rubber banding for vertex editing. Still buggy for multipolygons
git-svn-id: http://svn.osgeo.org/qgis/trunk/qgis@5535 c8812cc2-4d05-0410-92ff-de0c093fc19c
1 parent 2b4fef5 commit 02d951a

File tree

6 files changed

+155
-58
lines changed

6 files changed

+155
-58
lines changed
 

‎src/core/qgsgeometry.cpp

Lines changed: 76 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ void QgsGeometry::setGeos(geos::Geometry* geos)
214214

215215
}
216216

217-
QgsPoint QgsGeometry::closestVertex(const QgsPoint& point, QgsGeometryVertexIndex& atVertex, double& sqrDist) const
217+
QgsPoint QgsGeometry::closestVertex(const QgsPoint& point, QgsGeometryVertexIndex& atVertex, int& beforeVertex, int& afterVertex, double& sqrDist) const
218218
{
219219
if(mDirtyWkb)
220220
{
@@ -230,6 +230,9 @@ QgsPoint QgsGeometry::closestVertex(const QgsPoint& point, QgsGeometryVertexInde
230230
double x,y;
231231
double *tempx,*tempy;
232232
memcpy(&wkbType, (mGeometry+1), sizeof(int));
233+
beforeVertex = -1;
234+
afterVertex = -1;
235+
233236
switch (wkbType)
234237
{
235238
case QGis::WKBPoint:
@@ -255,6 +258,22 @@ QgsPoint QgsGeometry::closestVertex(const QgsPoint& point, QgsGeometryVertexInde
255258
y=*tempy;
256259
actdist=point.sqrDist(*tempx,*tempy);
257260
vertexnr = index;
261+
if(index == 0)//assign the rubber band indices
262+
{
263+
beforeVertex = -1;
264+
}
265+
else
266+
{
267+
beforeVertex = index-1;
268+
}
269+
if(index == (*npoints - 1))
270+
{
271+
afterVertex = -1;
272+
}
273+
else
274+
{
275+
afterVertex = index+1;
276+
}
258277
}
259278
ptr+=sizeof(double);
260279
}
@@ -280,6 +299,22 @@ QgsPoint QgsGeometry::closestVertex(const QgsPoint& point, QgsGeometryVertexInde
280299
y=*tempy;
281300
actdist=point.sqrDist(*tempx,*tempy);
282301
vertexnr = vertexcounter;
302+
//assign the rubber band indices
303+
if(index2 == 0)
304+
{
305+
beforeVertex = vertexcounter+(*npoints-2);
306+
afterVertex = vertexcounter+1;
307+
}
308+
else if(index2 == (*npoints-1))
309+
{
310+
beforeVertex = vertexcounter-1;
311+
afterVertex = vertexcounter - (*npoints-2);
312+
}
313+
else
314+
{
315+
beforeVertex = vertexcounter-1;
316+
afterVertex = vertexcounter+1;
317+
}
283318
}
284319
ptr+=sizeof(double);
285320
++vertexcounter;
@@ -333,6 +368,23 @@ QgsPoint QgsGeometry::closestVertex(const QgsPoint& point, QgsGeometryVertexInde
333368
y=*tempy;
334369
actdist=point.sqrDist(*tempx,*tempy);
335370
vertexnr = vertexcounter;
371+
372+
if(index2 == 0)//assign the rubber band indices
373+
{
374+
beforeVertex = -1;
375+
}
376+
else
377+
{
378+
beforeVertex = vertexnr-1;
379+
}
380+
if(index2 == (*npoints)-1)
381+
{
382+
afterVertex = -1;
383+
}
384+
else
385+
{
386+
afterVertex = vertexnr+1;
387+
}
336388
}
337389
++vertexcounter;
338390
}
@@ -367,6 +419,23 @@ QgsPoint QgsGeometry::closestVertex(const QgsPoint& point, QgsGeometryVertexInde
367419
y=*tempy;
368420
actdist=point.sqrDist(*tempx,*tempy);
369421
vertexnr = vertexcounter;
422+
423+
//assign the rubber band indices
424+
if(index3 == 0)
425+
{
426+
beforeVertex = vertexcounter+(*npoints-2);
427+
afterVertex = vertexcounter+1;
428+
}
429+
else if(index3 == (*npoints-1))
430+
{
431+
beforeVertex = vertexcounter-1;
432+
afterVertex = vertexcounter - (*npoints-2);
433+
}
434+
else
435+
{
436+
beforeVertex = vertexcounter-1;
437+
afterVertex = vertexcounter+1;
438+
}
370439
}
371440
ptr+=sizeof(double);
372441
++vertexcounter;
@@ -1101,12 +1170,12 @@ bool QgsGeometry::vertexAt(double &x, double &y,
11011170
memcpy(&x, ptr, sizeof(double));
11021171
ptr += sizeof(double);
11031172
memcpy(&y, ptr, sizeof(double));
1173+
return true;
11041174
}
11051175
else
11061176
{
11071177
return FALSE;
11081178
}
1109-
break;
11101179
}
11111180
case QGis::WKBLineString:
11121181
{
@@ -1125,7 +1194,7 @@ bool QgsGeometry::vertexAt(double &x, double &y,
11251194
memcpy(&x, ptr, sizeof(double));
11261195
ptr += sizeof(double);
11271196
memcpy(&y, ptr, sizeof(double));
1128-
break;
1197+
return true;
11291198
}
11301199
case QGis::WKBPolygon:
11311200
{
@@ -1146,7 +1215,7 @@ bool QgsGeometry::vertexAt(double &x, double &y,
11461215
memcpy(&x, ptr, sizeof(double));
11471216
ptr += sizeof(double);
11481217
memcpy(&y, ptr, sizeof(double));
1149-
break;
1218+
return true;
11501219
}
11511220
ptr += 2*sizeof(double);
11521221
++pointindex;
@@ -1167,7 +1236,7 @@ bool QgsGeometry::vertexAt(double &x, double &y,
11671236
memcpy(&x, ptr, sizeof(double));
11681237
ptr += sizeof(double);
11691238
memcpy(&y, ptr, sizeof(double));
1170-
break;
1239+
return true;
11711240
}
11721241
case QGis::WKBMultiLineString:
11731242
{
@@ -1188,7 +1257,7 @@ bool QgsGeometry::vertexAt(double &x, double &y,
11881257
memcpy(&x, ptr, sizeof(double));
11891258
ptr += sizeof(double);
11901259
memcpy(&y, ptr, sizeof(double));
1191-
break;
1260+
return true;
11921261
}
11931262
ptr += 2*sizeof(double);
11941263
++pointindex;
@@ -1219,7 +1288,7 @@ bool QgsGeometry::vertexAt(double &x, double &y,
12191288
memcpy(&x, ptr, sizeof(double));
12201289
ptr += sizeof(double);
12211290
memcpy(&y, ptr, sizeof(double));
1222-
break;
1291+
return true;
12231292
}
12241293
++pointindex;
12251294
ptr += 2*sizeof(double);
@@ -1235,13 +1304,6 @@ bool QgsGeometry::vertexAt(double &x, double &y,
12351304
return false;
12361305
break;
12371306
}
1238-
1239-
#ifdef QGISDEBUG
1240-
std::cout << "QgsGeometry::vertexAt: Exiting TRUE." << std::endl;
1241-
#endif
1242-
1243-
return true;
1244-
12451307
}
12461308
else
12471309
{

‎src/core/qgsgeometry.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,9 +83,9 @@ class QgsGeometry {
8383
void setGeos(geos::Geometry* geos);
8484

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

9090
/** Insert a new vertex before the given vertex index,
9191
* ring and item (first number is index 0)

‎src/gui/qgsmaptoolvertexedit.cpp

Lines changed: 45 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929

3030

3131
QgsMapToolVertexEdit::QgsMapToolVertexEdit(QgsMapCanvas* canvas, enum Tool tool)
32-
: QgsMapTool(canvas), mTool(tool), mRubberBand(0)
32+
: QgsMapTool(canvas), mTool(tool), mRubberBandIndex1(-1), mRubberBandIndex2(-1), mRubberBand(0)
3333
{
3434
// TODO - select a real cursor
3535
QPixmap mySelectQPixmap = QPixmap((const char **) capture_point_cursor);
@@ -47,19 +47,35 @@ void QgsMapToolVertexEdit::canvasMoveEvent(QMouseEvent * e)
4747
{
4848
if (e->buttons() == Qt::LeftButton && (mTool == AddVertex || mTool == MoveVertex))
4949
{
50-
int index = (mStartPointValid ? 1 : 0);
50+
//int index = (mStartPointValid ? 1 : 0);
51+
int index;
52+
if(mTool == MoveVertex)
53+
{
54+
if(mRubberBandIndex1 == -1)
55+
{
56+
index = 0;
57+
}
58+
else
59+
{
60+
index = 1;
61+
}
62+
}
63+
else
64+
{
65+
index = 1;
66+
}
67+
5168
//snap to nearest vertex of vectorlayer
5269
QgsPoint rbpoint = toMapCoords(e->pos());
5370
if(mTool == AddVertex)
5471
{
5572
snapVertex(rbpoint, mSnappedAtFeatureId, mSnappedBeforeVertex.back());
56-
mRubberBand->movePoint(index, rbpoint);
5773
}
5874
else if(mTool == MoveVertex)
5975
{
6076
snapVertex(rbpoint, mSnappedAtFeatureId, mSnappedAtVertex.back());
61-
mRubberBand->movePoint(index, rbpoint);
6277
}
78+
mRubberBand->movePoint(index, rbpoint);
6379
}
6480

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

7288
double x1, y1;
7389
double x2, y2;
74-
QgsGeometryVertexIndex index;
90+
QgsGeometryVertexIndex index, rb1Index, rb2Index; //rb1Index/rb2Index is for rubberbanding
7591

7692
if (mTool == AddVertex)
7793
{
@@ -89,25 +105,23 @@ void QgsMapToolVertexEdit::canvasPressEvent(QMouseEvent * e)
89105
QMessageBox::Ok, Qt::NoButton);
90106
return;
91107
}
92-
93-
index = mSnappedBeforeVertex;
94108

109+
index = mSnappedBeforeVertex;
95110
// Get the endpoint of the snapped-to segment
96111
mSnappedAtGeometry.vertexAt(x2, y2, index);
97-
112+
98113
// Get the startpoint of the snapped-to segment
99114
index.decrement_back();
100115
mStartPointValid = mSnappedAtGeometry.vertexAt(x1, y1, index);
101116

102117
createRubberBand();
103-
118+
104119
if (mStartPointValid)
105120
{
106121
mRubberBand->addPoint(QgsPoint(x1,y1));
107122
}
108123
mRubberBand->addPoint(toMapCoords(e->pos()));
109124
mRubberBand->addPoint(QgsPoint(x2,y2));
110-
111125
}
112126
else if (mTool == MoveVertex)
113127
{
@@ -126,33 +140,32 @@ void QgsMapToolVertexEdit::canvasPressEvent(QMouseEvent * e)
126140
return;
127141
}
128142

129-
#ifdef QGISDEBUG
130-
qWarning("Creating rubber band for moveVertex");
131-
#endif
132-
133143
index = mSnappedAtVertex;
134-
135-
// Get the startpoint of the rubber band, as the previous vertex to the snapped-to one.
136-
index.decrement_back();
137-
mStartPointValid = mSnappedAtGeometry.vertexAt(x1, y1, index);
138-
139-
// Get the endpoint of the rubber band, as the following vertex to the snapped-to one.
140-
index.increment_back();
141-
index.increment_back();
142-
mStopPointValid = mSnappedAtGeometry.vertexAt(x2, y2, index);
143-
144144
createRubberBand();
145-
146-
if (mStartPointValid)
145+
if(mRubberBandIndex1 != -1)
147146
{
147+
rb1Index.push_back(mRubberBandIndex1);
148+
mSnappedAtGeometry.vertexAt(x1, y1, rb1Index);
148149
mRubberBand->addPoint(QgsPoint(x1,y1));
150+
mStartPointValid = true;
149151
}
150-
mRubberBand->addPoint(toMapCoords(e->pos()));
151-
if (mStopPointValid)
152+
else
153+
{
154+
mStartPointValid = false;
155+
}
156+
if(mRubberBandIndex1 != -1 && mRubberBandIndex2 != -1)
157+
{
158+
mRubberBand->addPoint(toMapCoords(e->pos()));
159+
}
160+
if(mRubberBandIndex2 != -1)
152161
{
162+
rb2Index.push_back(mRubberBandIndex2);
163+
mSnappedAtGeometry.vertexAt(x2, y2, rb2Index);
153164
mRubberBand->addPoint(QgsPoint(x2,y2));
154165
}
155-
166+
#ifdef QGISDEBUG
167+
qWarning("Creating rubber band for moveVertex");
168+
#endif
156169
}
157170
else if (mTool == DeleteVertex)
158171
{
@@ -234,7 +247,7 @@ bool QgsMapToolVertexEdit::snapVertexWithContext(QgsPoint& point)
234247
if (!vlayer)
235248
return FALSE;
236249

237-
if (!vlayer->snapVertexWithContext(point, atVertex, atFeatureId, atGeometry, tolerance()))
250+
if (!vlayer->snapVertexWithContext(point, atVertex, mRubberBandIndex1, mRubberBandIndex2, atFeatureId, atGeometry, tolerance()))
238251
{
239252
mSnappedAtFeatureId = -1;
240253
return FALSE;
@@ -260,10 +273,11 @@ bool QgsMapToolVertexEdit::snapVertex(QgsPoint& point, int exclFeatureId, int ex
260273
{
261274
QgsGeometryVertexIndex vIndex;
262275
int snappedFeatureId;
276+
int rbPoint1, rbPoint2;
263277
QgsGeometry snappedGeometry;
264278
//do the snapping to a copy point first
265279
QgsPoint cpyPoint = point;
266-
vlayer->snapVertexWithContext(cpyPoint, vIndex, snappedFeatureId, snappedGeometry, tolerance());
280+
vlayer->snapVertexWithContext(cpyPoint, vIndex, rbPoint1, rbPoint2, snappedFeatureId, snappedGeometry, tolerance());
267281
if(snappedFeatureId != exclFeatureId || vIndex.back() != exclVertexNr)
268282
{
269283
point = cpyPoint;

‎src/gui/qgsmaptoolvertexedit.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,12 @@ class QgsMapToolVertexEdit : public QgsMapTool
7878
//! The snapped-to segment before this vertex number (identifying the vertex that is being moved)
7979
QgsGeometryVertexIndex mSnappedAtVertex;
8080

81+
/**The index of the first rubber band point (to connect to mSnappedatVertex). -1 if no such point exists*/
82+
int mRubberBandIndex1;
83+
84+
/**The index of the second rubber band point (to connect to mSnappedatVertex). -1 if no such point exists*/
85+
int mRubberBandIndex2;
86+
8187
//! The snapped-to segment before this vertex number (identifying the segment that a new vertex is being added to)
8288
QgsGeometryVertexIndex mSnappedBeforeVertex;
8389

0 commit comments

Comments
 (0)