Skip to content

Commit daa89f3

Browse files
author
wonder
committed
[UPDATE] support polygon features for simplification.
git-svn-id: http://svn.osgeo.org/qgis/trunk/qgis@10793 c8812cc2-4d05-0410-92ff-de0c093fc19c
1 parent 783b8cb commit daa89f3

File tree

2 files changed

+102
-37
lines changed

2 files changed

+102
-37
lines changed

src/app/qgsmaptoolsimplify.cpp

Lines changed: 78 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "qgstolerance.h"
2323

2424
#include <QMouseEvent>
25+
#include <QMessageBox>
2526

2627
#include <math.h>
2728

@@ -81,15 +82,29 @@ void QgsMapToolSimplify::toleranceChanged(int tolerance)
8182

8283
// create a copy of selected feature and do the simplification
8384
QgsFeature f = mSelectedFeature;
84-
QgsSimplifyFeature::simplifyLine(f, mTolerance);
85+
if ( mSelectedFeature.geometry()->type() == QGis::Line )
86+
{
87+
QgsSimplifyFeature::simplifyLine(f, mTolerance);
88+
}
89+
else
90+
{
91+
QgsSimplifyFeature::simplifyPolygon(f, mTolerance);
92+
}
8593
mRubberBand->setToGeometry(f.geometry(), false);
8694
}
8795

8896

8997
void QgsMapToolSimplify::storeSimplified()
9098
{
9199
QgsVectorLayer * vlayer = currentVectorLayer();
92-
QgsSimplifyFeature::simplifyLine(mSelectedFeature, mTolerance);
100+
if ( mSelectedFeature.geometry()->type() == QGis::Line )
101+
{
102+
QgsSimplifyFeature::simplifyLine(mSelectedFeature, mTolerance);
103+
}
104+
else
105+
{
106+
QgsSimplifyFeature::simplifyPolygon(mSelectedFeature, mTolerance);
107+
}
93108

94109
vlayer->changeGeometry( mSelectedFeature.id(), mSelectedFeature.geometry() );
95110

@@ -99,7 +114,7 @@ void QgsMapToolSimplify::storeSimplified()
99114
int QgsMapToolSimplify::calculateDivider(double num)
100115
{
101116
double tmp = num;
102-
int i = 1;
117+
long i = 1;
103118
while (tmp < 1)
104119
{
105120
tmp = tmp*10;
@@ -108,7 +123,7 @@ int QgsMapToolSimplify::calculateDivider(double num)
108123
return i;
109124
}
110125

111-
void QgsMapToolSimplify::calculateSliderBoudaries()
126+
bool QgsMapToolSimplify::calculateSliderBoudaries()
112127
{
113128
double minTolerance, maxTolerance;
114129

@@ -117,9 +132,9 @@ void QgsMapToolSimplify::calculateSliderBoudaries()
117132
bool isLine = mSelectedFeature.geometry()->type() == QGis::Line;
118133
QVector<QgsPoint> pts = getPointList(mSelectedFeature);
119134
int size = pts.size();
120-
if (size == 0 || (isLine && size < 2) || (!isLine && size < 3) )
135+
if (size == 0 || (isLine && size < 2) || (!isLine && size < 4) )
121136
{
122-
return;
137+
return false;
123138
}
124139

125140
// calculate min
@@ -128,30 +143,61 @@ void QgsMapToolSimplify::calculateSliderBoudaries()
128143
if (QgsSimplifyFeature::simplifyPoints(pts, tol).size() < size)
129144
{
130145
found = true;
131-
minTolerance = tol/2;
146+
minTolerance = tol/ 2;
132147
} else {
133148
tol = tol * 2;
134149
}
135150
}
136-
137151
found = false;
138-
int requiredCnt = (isLine ? 2 : 3);
152+
int requiredCnt = (isLine ? 2 : 4); //4 for polygon is correct because first and last points are the same
153+
bool bottomFound = false;
154+
double highTol, lowTol;// two boundaries to be used when no directly correct solution is found
139155
// calculate max
140156
while (!found)
141157
{
142-
if (QgsSimplifyFeature::simplifyPoints(pts, tol).size() < requiredCnt + 1)
158+
159+
int foundVertexes = QgsSimplifyFeature::simplifyPoints(pts, tol).size();
160+
if (foundVertexes < requiredCnt + 1)
143161
{
144-
//TODO: fix for polygon
145-
found = true;
146-
maxTolerance = tol;
162+
if (foundVertexes == requiredCnt)
163+
{
164+
found = true;
165+
maxTolerance = tol;
166+
}
167+
else
168+
{
169+
bottomFound = true;
170+
highTol = tol;
171+
tol = (highTol + lowTol) /2;
172+
if (highTol/lowTol < 1.00000001)
173+
{
174+
found = true;
175+
maxTolerance = lowTol;
176+
}
177+
}
147178
} else {
148-
tol = tol * 2;
179+
if (bottomFound)
180+
{
181+
lowTol = tol;
182+
tol = (highTol + lowTol) /2;
183+
if (highTol/lowTol < 1.00000001)
184+
{
185+
found = true;
186+
maxTolerance = lowTol;
187+
}
188+
}
189+
else
190+
{
191+
lowTol = tol;
192+
tol = tol * 2;
193+
}
149194
}
150195
}
151196
toleranceDivider = calculateDivider(minTolerance);
152197
// set min and max
153198
mSimplifyDialog->setRange( int(minTolerance * toleranceDivider),
154199
int(maxTolerance * toleranceDivider) );
200+
return true;
155201
}
156202

157203

@@ -181,7 +227,11 @@ void QgsMapToolSimplify::canvasPressEvent( QMouseEvent * e )
181227
mSelectedFeature = f;
182228
}
183229
}
184-
230+
if (mSelectedFeature.geometry()->isMultipart())
231+
{
232+
QMessageBox::critical( 0, tr( "Unsupported operation" ), tr( "Multipart features are not supported for simplification." ) );
233+
return;
234+
}
185235
// delete previous rubberband (if any)
186236
removeRubberBand();
187237

@@ -193,10 +243,11 @@ void QgsMapToolSimplify::canvasPressEvent( QMouseEvent * e )
193243
mRubberBand->setWidth(2);
194244
mRubberBand->show();
195245
//calculate boudaries for slidebar
196-
calculateSliderBoudaries();
197-
198-
// show dialog as a non-modal window
199-
mSimplifyDialog->show();
246+
if (calculateSliderBoudaries())
247+
{
248+
// show dialog as a non-modal window
249+
mSimplifyDialog->show();
250+
}
200251
}
201252
}
202253

@@ -234,13 +285,10 @@ QVector<QgsPoint> QgsMapToolSimplify::getPointList(QgsFeature& f)
234285
}
235286
return line->asPolygon()[0];
236287
}
237-
238288
}
239289

240290

241291

242-
243-
244292
bool QgsSimplifyFeature::simplifyLine(QgsFeature& lineFeature, double tolerance)
245293
{
246294
QgsGeometry* line = lineFeature.geometry();
@@ -254,23 +302,22 @@ bool QgsSimplifyFeature::simplifyLine(QgsFeature& lineFeature, double tolerance
254302
return TRUE;
255303
}
256304

257-
258-
//TODO: change to correct structure after
259-
bool QgsSimplifyFeature::simplifyPartOfLine(QgsFeature& lineFeature, int fromVertexNr, int toVertexNr, double tolerance)
305+
bool QgsSimplifyFeature::simplifyPolygon(QgsFeature& polygonFeature, double tolerance)
260306
{
261-
QgsGeometry* line = lineFeature.geometry();
262-
if (line->type() != QGis::Line)
307+
QgsGeometry* polygon = polygonFeature.geometry();
308+
if (polygon->type() != QGis::Polygon)
263309
{
264310
return FALSE;
265311
}
266-
267-
QVector<QgsPoint> resultPoints = simplifyPoints(line->asPolyline(), tolerance);
268-
lineFeature.setGeometry( QgsGeometry::fromPolyline( resultPoints ) );
312+
QVector<QgsPoint> resultPoints = simplifyPoints(polygon->asPolygon()[0], tolerance);
313+
//resultPoints.push_back(resultPoints[0]);
314+
QVector<QgsPolyline> poly;
315+
poly.append(resultPoints);
316+
polygonFeature.setGeometry( QgsGeometry::fromPolygon( poly ) );
269317
return TRUE;
270318
}
271319

272320

273-
274321
QVector<QgsPoint> QgsSimplifyFeature::simplifyPoints (const QVector<QgsPoint>& pts, double tolerance)
275322
{
276323
// Douglas-Peucker simplification algorithm

src/app/qgsmaptoolsimplify.h

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
* (at your option) any later version. *
1313
* *
1414
***************************************************************************/
15+
/* $Id$ */
1516

1617
#ifndef QGSMAPTOOLSIMPLIFY_H
1718
#define QGSMAPTOOLSIMPLIFY_H
@@ -30,21 +31,28 @@ class QgsSimplifyDialog : public QDialog, private Ui::SimplifyLineDialog
3031
Q_OBJECT
3132

3233
public:
34+
3335
QgsSimplifyDialog( QWidget* parent = NULL );
3436

37+
/** Setting range of slide bar */
3538
void setRange(int minValue, int maxValue);
3639

3740
signals:
41+
/** Signal when slidebar is moved */
3842
void toleranceChanged( int tol );
43+
44+
/** Signal to accept changes */
3945
void storeSimplified();
4046

4147
private slots:
48+
/** Internal signal when value is changed */
4249
void valueChanged( int value );
50+
/** Internal signal to store simplified feature */
4351
void simplify();
4452
};
4553

4654

47-
/**Map tool to add vertices to line/polygon features*/
55+
/** Map tool to simplify line/polygon features */
4856
class QgsMapToolSimplify: public QgsMapToolEdit
4957
{
5058
Q_OBJECT
@@ -62,27 +70,36 @@ public slots:
6270
void removeRubberBand();
6371

6472
private:
65-
73+
/** Divider calculation, because slider can go only by whole numbers */
6674
int calculateDivider(double num);
6775

68-
void calculateSliderBoudaries();
76+
/** Function to calculate tolerance boudaries for simplifying */
77+
bool calculateSliderBoudaries();
6978

79+
/** Function to get list of vertexes from feature */
7080
QVector<QgsPoint> getPointList(QgsFeature& f);
7181

7282
// data
73-
83+
/** Dialog with slider to set correct tolerance value */
7484
QgsSimplifyDialog* mSimplifyDialog;
7585

86+
/** Rubber band to draw current state of simplification */
7687
QgsRubberBand* mRubberBand;
7788

89+
/** Feature with which we are working */
7890
QgsFeature mSelectedFeature;
7991

92+
/** tolerance divider is value which tells with which delete value from sidebar */
8093
int toleranceDivider;
8194

95+
/** real value of tolerance */
8296
double mTolerance;
8397

8498
private slots:
99+
/** slot to change display when slidebar is moved */
85100
void toleranceChanged(int tolerance);
101+
102+
/** slot to store feture after simplification */
86103
void storeSimplified();
87104

88105
};
@@ -92,6 +109,7 @@ private slots:
92109
*/
93110
class QgsSimplifyFeature
94111
{
112+
/** structure for one entry in stack for simplification algorithm */
95113
struct StackEntry {
96114
int anchor;
97115
int floater;
@@ -100,8 +118,8 @@ class QgsSimplifyFeature
100118
public:
101119
/** simplify line feature with specified tolerance. Returns TRUE on success */
102120
static bool simplifyLine(QgsFeature &lineFeature, double tolerance);
103-
/** simplify a part of line feature specified by range of vertices with given tolerance. Returns TRUE on success */
104-
static bool simplifyPartOfLine(QgsFeature &lineFeature, int fromVertexNr, int toVertexNr, double tolerance);
121+
/** simplify polygon feature with specified tolerance. Returns TRUE on success */
122+
static bool simplifyPolygon(QgsFeature &polygonFeature, double tolerance);
105123
/** simplify a line given by a vector of points and tolerance. Returns simplified vector of points */
106124
static QVector<QgsPoint> simplifyPoints (const QVector<QgsPoint>& pts, double tolerance);
107125

0 commit comments

Comments
 (0)