[QGIS Commit] r10793 - trunk/qgis/src/app
svn_qgis at osgeo.org
svn_qgis at osgeo.org
Thu May 14 12:53:54 EDT 2009
Author: wonder
Date: 2009-05-14 12:53:54 -0400 (Thu, 14 May 2009)
New Revision: 10793
Modified:
trunk/qgis/src/app/qgsmaptoolsimplify.cpp
trunk/qgis/src/app/qgsmaptoolsimplify.h
Log:
[UPDATE] support polygon features for simplification.
Modified: trunk/qgis/src/app/qgsmaptoolsimplify.cpp
===================================================================
--- trunk/qgis/src/app/qgsmaptoolsimplify.cpp 2009-05-14 16:40:06 UTC (rev 10792)
+++ trunk/qgis/src/app/qgsmaptoolsimplify.cpp 2009-05-14 16:53:54 UTC (rev 10793)
@@ -22,6 +22,7 @@
#include "qgstolerance.h"
#include <QMouseEvent>
+#include <QMessageBox>
#include <math.h>
@@ -81,7 +82,14 @@
// create a copy of selected feature and do the simplification
QgsFeature f = mSelectedFeature;
- QgsSimplifyFeature::simplifyLine(f, mTolerance);
+ if ( mSelectedFeature.geometry()->type() == QGis::Line )
+ {
+ QgsSimplifyFeature::simplifyLine(f, mTolerance);
+ }
+ else
+ {
+ QgsSimplifyFeature::simplifyPolygon(f, mTolerance);
+ }
mRubberBand->setToGeometry(f.geometry(), false);
}
@@ -89,7 +97,14 @@
void QgsMapToolSimplify::storeSimplified()
{
QgsVectorLayer * vlayer = currentVectorLayer();
- QgsSimplifyFeature::simplifyLine(mSelectedFeature, mTolerance);
+ if ( mSelectedFeature.geometry()->type() == QGis::Line )
+ {
+ QgsSimplifyFeature::simplifyLine(mSelectedFeature, mTolerance);
+ }
+ else
+ {
+ QgsSimplifyFeature::simplifyPolygon(mSelectedFeature, mTolerance);
+ }
vlayer->changeGeometry( mSelectedFeature.id(), mSelectedFeature.geometry() );
@@ -99,7 +114,7 @@
int QgsMapToolSimplify::calculateDivider(double num)
{
double tmp = num;
- int i = 1;
+ long i = 1;
while (tmp < 1)
{
tmp = tmp*10;
@@ -108,7 +123,7 @@
return i;
}
-void QgsMapToolSimplify::calculateSliderBoudaries()
+bool QgsMapToolSimplify::calculateSliderBoudaries()
{
double minTolerance, maxTolerance;
@@ -117,9 +132,9 @@
bool isLine = mSelectedFeature.geometry()->type() == QGis::Line;
QVector<QgsPoint> pts = getPointList(mSelectedFeature);
int size = pts.size();
- if (size == 0 || (isLine && size < 2) || (!isLine && size < 3) )
+ if (size == 0 || (isLine && size < 2) || (!isLine && size < 4) )
{
- return;
+ return false;
}
// calculate min
@@ -128,30 +143,61 @@
if (QgsSimplifyFeature::simplifyPoints(pts, tol).size() < size)
{
found = true;
- minTolerance = tol/2;
+ minTolerance = tol/ 2;
} else {
tol = tol * 2;
}
}
-
found = false;
- int requiredCnt = (isLine ? 2 : 3);
+ int requiredCnt = (isLine ? 2 : 4); //4 for polygon is correct because first and last points are the same
+ bool bottomFound = false;
+ double highTol, lowTol;// two boundaries to be used when no directly correct solution is found
// calculate max
while (!found)
{
- if (QgsSimplifyFeature::simplifyPoints(pts, tol).size() < requiredCnt + 1)
+
+ int foundVertexes = QgsSimplifyFeature::simplifyPoints(pts, tol).size();
+ if (foundVertexes < requiredCnt + 1)
{
-//TODO: fix for polygon
- found = true;
- maxTolerance = tol;
+ if (foundVertexes == requiredCnt)
+ {
+ found = true;
+ maxTolerance = tol;
+ }
+ else
+ {
+ bottomFound = true;
+ highTol = tol;
+ tol = (highTol + lowTol) /2;
+ if (highTol/lowTol < 1.00000001)
+ {
+ found = true;
+ maxTolerance = lowTol;
+ }
+ }
} else {
- tol = tol * 2;
+ if (bottomFound)
+ {
+ lowTol = tol;
+ tol = (highTol + lowTol) /2;
+ if (highTol/lowTol < 1.00000001)
+ {
+ found = true;
+ maxTolerance = lowTol;
+ }
+ }
+ else
+ {
+ lowTol = tol;
+ tol = tol * 2;
+ }
}
}
toleranceDivider = calculateDivider(minTolerance);
// set min and max
mSimplifyDialog->setRange( int(minTolerance * toleranceDivider),
int(maxTolerance * toleranceDivider) );
+ return true;
}
@@ -181,7 +227,11 @@
mSelectedFeature = f;
}
}
-
+ if (mSelectedFeature.geometry()->isMultipart())
+ {
+ QMessageBox::critical( 0, tr( "Unsupported operation" ), tr( "Multipart features are not supported for simplification." ) );
+ return;
+ }
// delete previous rubberband (if any)
removeRubberBand();
@@ -193,10 +243,11 @@
mRubberBand->setWidth(2);
mRubberBand->show();
//calculate boudaries for slidebar
- calculateSliderBoudaries();
-
- // show dialog as a non-modal window
- mSimplifyDialog->show();
+ if (calculateSliderBoudaries())
+ {
+ // show dialog as a non-modal window
+ mSimplifyDialog->show();
+ }
}
}
@@ -234,13 +285,10 @@
}
return line->asPolygon()[0];
}
-
}
-
-
bool QgsSimplifyFeature::simplifyLine(QgsFeature& lineFeature, double tolerance)
{
QgsGeometry* line = lineFeature.geometry();
@@ -254,23 +302,22 @@
return TRUE;
}
-
-//TODO: change to correct structure after
-bool QgsSimplifyFeature::simplifyPartOfLine(QgsFeature& lineFeature, int fromVertexNr, int toVertexNr, double tolerance)
+bool QgsSimplifyFeature::simplifyPolygon(QgsFeature& polygonFeature, double tolerance)
{
- QgsGeometry* line = lineFeature.geometry();
- if (line->type() != QGis::Line)
+ QgsGeometry* polygon = polygonFeature.geometry();
+ if (polygon->type() != QGis::Polygon)
{
return FALSE;
}
-
- QVector<QgsPoint> resultPoints = simplifyPoints(line->asPolyline(), tolerance);
- lineFeature.setGeometry( QgsGeometry::fromPolyline( resultPoints ) );
+ QVector<QgsPoint> resultPoints = simplifyPoints(polygon->asPolygon()[0], tolerance);
+ //resultPoints.push_back(resultPoints[0]);
+ QVector<QgsPolyline> poly;
+ poly.append(resultPoints);
+ polygonFeature.setGeometry( QgsGeometry::fromPolygon( poly ) );
return TRUE;
}
-
QVector<QgsPoint> QgsSimplifyFeature::simplifyPoints (const QVector<QgsPoint>& pts, double tolerance)
{
// Douglas-Peucker simplification algorithm
Modified: trunk/qgis/src/app/qgsmaptoolsimplify.h
===================================================================
--- trunk/qgis/src/app/qgsmaptoolsimplify.h 2009-05-14 16:40:06 UTC (rev 10792)
+++ trunk/qgis/src/app/qgsmaptoolsimplify.h 2009-05-14 16:53:54 UTC (rev 10793)
@@ -12,6 +12,7 @@
* (at your option) any later version. *
* *
***************************************************************************/
+/* $Id$ */
#ifndef QGSMAPTOOLSIMPLIFY_H
#define QGSMAPTOOLSIMPLIFY_H
@@ -30,21 +31,28 @@
Q_OBJECT
public:
+
QgsSimplifyDialog( QWidget* parent = NULL );
+ /** Setting range of slide bar */
void setRange(int minValue, int maxValue);
signals:
+ /** Signal when slidebar is moved */
void toleranceChanged( int tol );
+
+ /** Signal to accept changes */
void storeSimplified();
private slots:
+ /** Internal signal when value is changed */
void valueChanged( int value );
+ /** Internal signal to store simplified feature */
void simplify();
};
-/**Map tool to add vertices to line/polygon features*/
+/** Map tool to simplify line/polygon features */
class QgsMapToolSimplify: public QgsMapToolEdit
{
Q_OBJECT
@@ -62,27 +70,36 @@
void removeRubberBand();
private:
-
+ /** Divider calculation, because slider can go only by whole numbers */
int calculateDivider(double num);
- void calculateSliderBoudaries();
+ /** Function to calculate tolerance boudaries for simplifying */
+ bool calculateSliderBoudaries();
+ /** Function to get list of vertexes from feature */
QVector<QgsPoint> getPointList(QgsFeature& f);
// data
-
+ /** Dialog with slider to set correct tolerance value */
QgsSimplifyDialog* mSimplifyDialog;
+ /** Rubber band to draw current state of simplification */
QgsRubberBand* mRubberBand;
+ /** Feature with which we are working */
QgsFeature mSelectedFeature;
+ /** tolerance divider is value which tells with which delete value from sidebar */
int toleranceDivider;
+ /** real value of tolerance */
double mTolerance;
private slots:
+ /** slot to change display when slidebar is moved */
void toleranceChanged(int tolerance);
+
+ /** slot to store feture after simplification */
void storeSimplified();
};
@@ -92,6 +109,7 @@
*/
class QgsSimplifyFeature
{
+ /** structure for one entry in stack for simplification algorithm */
struct StackEntry {
int anchor;
int floater;
@@ -100,8 +118,8 @@
public:
/** simplify line feature with specified tolerance. Returns TRUE on success */
static bool simplifyLine(QgsFeature &lineFeature, double tolerance);
- /** simplify a part of line feature specified by range of vertices with given tolerance. Returns TRUE on success */
- static bool simplifyPartOfLine(QgsFeature &lineFeature, int fromVertexNr, int toVertexNr, double tolerance);
+ /** simplify polygon feature with specified tolerance. Returns TRUE on success */
+ static bool simplifyPolygon(QgsFeature &polygonFeature, double tolerance);
/** simplify a line given by a vector of points and tolerance. Returns simplified vector of points */
static QVector<QgsPoint> simplifyPoints (const QVector<QgsPoint>& pts, double tolerance);
More information about the QGIS-commit
mailing list