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
8997void 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()
99114int 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-
244292bool 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-
274321QVector<QgsPoint> QgsSimplifyFeature::simplifyPoints (const QVector<QgsPoint>& pts, double tolerance)
275322{
276323 // Douglas-Peucker simplification algorithm
0 commit comments