[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