[QGIS Commit] r11839 - in trunk/qgis/src: app ui

svn_qgis at osgeo.org svn_qgis at osgeo.org
Sun Oct 25 11:18:30 EDT 2009


Author: mhugent
Date: 2009-10-25 11:18:29 -0400 (Sun, 25 Oct 2009)
New Revision: 11839

Added:
   trunk/qgis/src/app/qgsavoidintersectionsdialog.cpp
   trunk/qgis/src/app/qgsavoidintersectionsdialog.h
   trunk/qgis/src/ui/qgsavoidintersectionsdialogbase.ui
Modified:
   trunk/qgis/src/app/CMakeLists.txt
   trunk/qgis/src/app/qgsmaptooladdfeature.cpp
   trunk/qgis/src/app/qgsmaptooladdfeature.h
   trunk/qgis/src/app/qgsprojectproperties.cpp
   trunk/qgis/src/app/qgsprojectproperties.h
   trunk/qgis/src/ui/qgsprojectpropertiesbase.ui
Log:
[FEATURE]: Avoid intersections for polygons is now also possible to background layers

Modified: trunk/qgis/src/app/CMakeLists.txt
===================================================================
--- trunk/qgis/src/app/CMakeLists.txt	2009-10-24 22:33:56 UTC (rev 11838)
+++ trunk/qgis/src/app/CMakeLists.txt	2009-10-25 15:18:29 UTC (rev 11839)
@@ -9,6 +9,7 @@
   qgsattributeeditor.cpp
   qgsattributetypedialog.cpp
   qgsattributetypeloaddialog.cpp
+  qgsavoidintersectionsdialog.cpp
   qgsbookmarkitem.cpp
   qgsbookmarks.cpp
   qgsclipboard.cpp
@@ -119,6 +120,7 @@
   qgsattributeeditor.h
   qgsattributetypedialog.h
   qgsattributetypeloaddialog.h
+  qgsavoidintersectionsdialog.h
   qgsbookmarks.h
   qgscontinuouscolordialog.h
   qgsconfigureshortcutsdialog.h

Added: trunk/qgis/src/app/qgsavoidintersectionsdialog.cpp
===================================================================
--- trunk/qgis/src/app/qgsavoidintersectionsdialog.cpp	                        (rev 0)
+++ trunk/qgis/src/app/qgsavoidintersectionsdialog.cpp	2009-10-25 15:18:29 UTC (rev 11839)
@@ -0,0 +1,60 @@
+#include "qgsavoidintersectionsdialog.h"
+#include "qgsmapcanvas.h"
+#include "qgsvectorlayer.h"
+
+QgsAvoidIntersectionsDialog::QgsAvoidIntersectionsDialog( QgsMapCanvas* canvas, const QSet<QString>& enabledLayers, QWidget * parent, Qt::WindowFlags f ): \
+    QDialog( parent, f ), mMapCanvas( canvas )
+{
+  setupUi( this );
+
+  int nLayers = mMapCanvas->layerCount();
+  QgsVectorLayer* currentLayer = 0;
+  QListWidgetItem* newItem = 0;
+
+  for ( int i = 0; i < nLayers; ++i )
+  {
+    currentLayer = dynamic_cast<QgsVectorLayer*>( mMapCanvas->layer( i ) );
+    if ( currentLayer )
+    {
+      //only consider polygon or multipolygon layers
+      if ( currentLayer->geometryType() == QGis::Polygon )
+      {
+        newItem = new QListWidgetItem( mLayersListWidget );
+        newItem->setText( currentLayer->name() );
+        newItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsUserCheckable );
+        newItem->setData( Qt::UserRole, currentLayer->getLayerID() );
+        if ( enabledLayers.contains( currentLayer->getLayerID() ) )
+        {
+          newItem->setCheckState( Qt::Checked );
+        }
+        else
+        {
+          newItem->setCheckState( Qt::Unchecked );
+        }
+      }
+    }
+  }
+}
+
+QgsAvoidIntersectionsDialog::~QgsAvoidIntersectionsDialog()
+{
+
+}
+
+void QgsAvoidIntersectionsDialog::enabledLayers( QSet<QString>& enabledLayers )
+{
+  enabledLayers.clear();
+
+  int itemCount = mLayersListWidget->count();
+  QListWidgetItem* currentItem = 0;
+
+  for ( int i = 0; i < itemCount; ++i )
+  {
+    currentItem = mLayersListWidget->item( i );
+    if ( currentItem->checkState() == Qt::Checked )
+    {
+      enabledLayers.insert( currentItem->data( Qt::UserRole ).toString() );
+    }
+  }
+}
+

Added: trunk/qgis/src/app/qgsavoidintersectionsdialog.h
===================================================================
--- trunk/qgis/src/app/qgsavoidintersectionsdialog.h	                        (rev 0)
+++ trunk/qgis/src/app/qgsavoidintersectionsdialog.h	2009-10-25 15:18:29 UTC (rev 11839)
@@ -0,0 +1,21 @@
+#ifndef QGSAVOIDINTERSECTIONSDIALOG_H
+#define QGSAVOIDINTERSECTIONSDIALOG_H
+
+#include "ui_qgsavoidintersectionsdialogbase.h"
+
+class QgsMapCanvas;
+
+class QgsAvoidIntersectionsDialog: public QDialog, private Ui::QgsAvoidIntersectionsDialogBase
+{
+    Q_OBJECT
+  public:
+    QgsAvoidIntersectionsDialog( QgsMapCanvas* canvas, const QSet<QString>& enabledLayers, QWidget * parent = 0, Qt::WindowFlags f = 0 );
+    ~QgsAvoidIntersectionsDialog();
+    /**Returns ids of layers that are considered for the avoid intersection function*/
+    void enabledLayers( QSet<QString>& enabledLayers );
+
+  private:
+    QgsMapCanvas* mMapCanvas;
+};
+
+#endif // QGSAVOIDINTERSECTIONSDIALOG_H

Modified: trunk/qgis/src/app/qgsmaptooladdfeature.cpp
===================================================================
--- trunk/qgis/src/app/qgsmaptooladdfeature.cpp	2009-10-24 22:33:56 UTC (rev 11838)
+++ trunk/qgis/src/app/qgsmaptooladdfeature.cpp	2009-10-25 15:18:29 UTC (rev 11839)
@@ -21,6 +21,7 @@
 #include "qgsfield.h"
 #include "qgsgeometry.h"
 #include "qgsmapcanvas.h"
+#include "qgsmaplayerregistry.h"
 #include "qgsproject.h"
 #include "qgsrubberband.h"
 #include "qgsvectordataprovider.h"
@@ -442,16 +443,27 @@
         }
         f->setGeometryAndOwnership( &wkb[0], size );
 
-        //is automatic polygon intersection removal activated?
-        int avoidPolygonIntersections = QgsProject::instance()->readNumEntry( "Digitizing", "/AvoidPolygonIntersections", 0 );
-
-        if ( avoidPolygonIntersections != 0 )
+        int avoidIntersectionsReturn = avoidIntersectons( f->geometry() );
+        if ( avoidIntersectionsReturn == 1 )
         {
-          if ( vlayer->removePolygonIntersections( f->geometry() ) != 0 )
-          {
-            QMessageBox::critical( 0, tr( "Error" ), tr( "Could not remove polygon intersection" ) );
-          }
+          //not a polygon type. Impossible to get there
         }
+        else if ( avoidIntersectionsReturn == 2 )
+        {
+          //bail out...
+          QMessageBox::critical( 0, tr( "Error" ), tr( "The feature could not be added because removing the polygon intersections would change the geometry type" ) );
+          delete f;
+          delete mRubberBand;
+          mRubberBand = 0;
+          mCaptureList.clear();
+          return;
+        }
+        else if ( avoidIntersectionsReturn == 3 )
+        {
+          QMessageBox::critical( 0, tr( "Error" ), tr( "An error was reported during intersection removal" ) );
+        }
+
+
       }
 
       // add the fields to the QgsFeature
@@ -507,3 +519,47 @@
     }
   }
 }
+
+int QgsMapToolAddFeature::avoidIntersectons( QgsGeometry* g )
+{
+  int returnValue = 0;
+
+  //check if g has polygon type
+  if ( !g || g->type() != QGis::Polygon )
+  {
+    return 1;
+  }
+
+  QGis::WkbType geomTypeBeforeModification = g->wkbType();
+
+  //read avoid intersections list from project properties
+  bool listReadOk;
+  QStringList avoidIntersectionsList = QgsProject::instance()->readListEntry( "Digitizing", "/AvoidIntersectionsList", &listReadOk );
+  if ( !listReadOk )
+  {
+    return true; //no intersections stored in project does not mean error
+  }
+
+  //go through list, convert each layer to vector layer and call QgsVectorLayer::removePolygonIntersections for each
+  QgsVectorLayer* currentLayer = 0;
+  QStringList::const_iterator aIt = avoidIntersectionsList.constBegin();
+  for ( ; aIt != avoidIntersectionsList.constEnd(); ++aIt )
+  {
+    currentLayer = dynamic_cast<QgsVectorLayer*>( QgsMapLayerRegistry::instance()->mapLayer( *aIt ) );
+    if ( currentLayer )
+    {
+      if ( currentLayer->removePolygonIntersections( g ) != 0 )
+      {
+        returnValue = 3;
+      }
+    }
+  }
+
+  //make sure the geometry still has the same type (e.g. no change from polygon to multipolygon)
+  if ( g->wkbType() != geomTypeBeforeModification )
+  {
+    return 2;
+  }
+
+  return returnValue;
+}

Modified: trunk/qgis/src/app/qgsmaptooladdfeature.h
===================================================================
--- trunk/qgis/src/app/qgsmaptooladdfeature.h	2009-10-24 22:33:56 UTC (rev 11838)
+++ trunk/qgis/src/app/qgsmaptooladdfeature.h	2009-10-25 15:18:29 UTC (rev 11839)
@@ -24,4 +24,9 @@
     QgsMapToolAddFeature( QgsMapCanvas* canvas, enum CaptureTool tool );
     virtual ~QgsMapToolAddFeature();
     void canvasReleaseEvent( QMouseEvent * e );
+  private:
+    /**Modifies geometry to avoid intersections with the layers specified in project properties
+    @return 0 in case of success, 1 if geometry is not of polygon type, 2 if avoid intersection would change the geometry type, \
+    3 other error during intersection removal*/
+    int avoidIntersectons( QgsGeometry* g );
 };

Modified: trunk/qgis/src/app/qgsprojectproperties.cpp
===================================================================
--- trunk/qgis/src/app/qgsprojectproperties.cpp	2009-10-24 22:33:56 UTC (rev 11838)
+++ trunk/qgis/src/app/qgsprojectproperties.cpp	2009-10-25 15:18:29 UTC (rev 11839)
@@ -20,6 +20,7 @@
 #include "qgsprojectproperties.h"
 
 //qgis includes
+#include "qgsavoidintersectionsdialog.h"
 #include "qgscontexthelp.h"
 #include "qgscoordinatetransform.h"
 #include "qgslogger.h"
@@ -113,15 +114,17 @@
     mEnableTopologicalEditingCheckBox->setCheckState( Qt::Unchecked );
   }
 
-  int avoidPolygonIntersections = QgsProject::instance()->readNumEntry( "Digitizing", "/AvoidPolygonIntersections", 0 );
-  if ( avoidPolygonIntersections != 0 )
+  bool avoidIntersectionListOk;
+  mAvoidIntersectionsSettings.clear();
+  QStringList avoidIntersectionsList = QgsProject::instance()->readListEntry( "Digitizing", "/AvoidIntersectionsList", &avoidIntersectionListOk );
+  if ( avoidIntersectionListOk )
   {
-    mAvoidIntersectionsCheckBox->setCheckState( Qt::Checked );
+    QStringList::const_iterator avoidIt = avoidIntersectionsList.constBegin();
+    for ( ; avoidIt != avoidIntersectionsList.constEnd(); ++avoidIt )
+    {
+      mAvoidIntersectionsSettings.insert( *avoidIt );
+    }
   }
-  else
-  {
-    mAvoidIntersectionsCheckBox->setCheckState( Qt::Unchecked );
-  }
 
   bool layerIdListOk, enabledListOk, toleranceListOk, toleranceUnitListOk, snapToListOk;
   QStringList layerIdList = QgsProject::instance()->readListEntry( "Digitizing", "/LayerSnappingList", &layerIdListOk );
@@ -399,9 +402,17 @@
   //write the digitizing settings
   int topologicalEditingEnabled = ( mEnableTopologicalEditingCheckBox->checkState() == Qt::Checked ) ? 1 : 0;
   QgsProject::instance()->writeEntry( "Digitizing", "/TopologicalEditing", topologicalEditingEnabled );
-  int avoidPolygonIntersectionsEnabled = ( mAvoidIntersectionsCheckBox->checkState() == Qt::Checked ) ? 1 : 0;
-  QgsProject::instance()->writeEntry( "Digitizing", "/AvoidPolygonIntersections", avoidPolygonIntersectionsEnabled );
 
+  //store avoid intersection layers
+  QStringList avoidIntersectionList;
+  QSet<QString>::const_iterator avoidIt = mAvoidIntersectionsSettings.constBegin();
+  for ( ; avoidIt != mAvoidIntersectionsSettings.constEnd(); ++avoidIt )
+  {
+    avoidIntersectionList.append( *avoidIt );
+  }
+  QgsProject::instance()->writeEntry( "Digitizing", "/AvoidIntersectionsList", avoidIntersectionList );
+
+
   QMap<QString, LayerEntry>::const_iterator layerEntryIt;
 
   //store the layer snapping settings as string lists
@@ -498,6 +509,15 @@
   QgsContextHelp::run( context_id );
 }
 
+void QgsProjectProperties::on_mAvoidIntersectionsPushButton_clicked()
+{
+  QgsAvoidIntersectionsDialog d( mMapCanvas, mAvoidIntersectionsSettings );
+  if ( d.exec() == QDialog::Accepted )
+  {
+    d.enabledLayers( mAvoidIntersectionsSettings );
+  }
+}
+
 void QgsProjectProperties::on_mSnappingOptionsPushButton_clicked()
 {
   QgsSnappingDialog d( mMapCanvas, mSnappingLayerSettings );

Modified: trunk/qgis/src/app/qgsprojectproperties.h
===================================================================
--- trunk/qgis/src/app/qgsprojectproperties.h	2009-10-24 22:33:56 UTC (rev 11838)
+++ trunk/qgis/src/app/qgsprojectproperties.h	2009-10-25 15:18:29 UTC (rev 11839)
@@ -89,7 +89,12 @@
     void on_buttonBox_helpRequested();
 
     /*!
-     * Slot to show dialog for advanced editing options
+      *
+      */
+    void on_mAvoidIntersectionsPushButton_clicked();
+
+    /*!
+     * Slot to show dialog for the layer snapping options
      */
     void on_mSnappingOptionsPushButton_clicked();
 
@@ -114,7 +119,10 @@
     snapping tolerance*/
     QMap<QString, LayerEntry> mSnappingLayerSettings;
 
+    /**Stores ids of layers where intersections of new polygons is considered. Is passed to / read from QgsAvoidIntersectionsDialog*/
+    QSet<QString> mAvoidIntersectionsSettings;
 
+
     /*!
      * Function to save dialog window state
      */

Added: trunk/qgis/src/ui/qgsavoidintersectionsdialogbase.ui
===================================================================
--- trunk/qgis/src/ui/qgsavoidintersectionsdialogbase.ui	                        (rev 0)
+++ trunk/qgis/src/ui/qgsavoidintersectionsdialogbase.ui	2009-10-25 15:18:29 UTC (rev 11839)
@@ -0,0 +1,66 @@
+<ui version="4.0" >
+ <class>QgsAvoidIntersectionsDialogBase</class>
+ <widget class="QDialog" name="QgsAvoidIntersectionsDialogBase" >
+  <property name="geometry" >
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>365</width>
+    <height>300</height>
+   </rect>
+  </property>
+  <property name="windowTitle" >
+   <string>Dialog</string>
+  </property>
+  <layout class="QGridLayout" name="gridLayout" >
+   <item row="0" column="0" >
+    <widget class="QListWidget" name="mLayersListWidget" />
+   </item>
+   <item row="1" column="0" >
+    <widget class="QDialogButtonBox" name="mButtonBox" >
+     <property name="orientation" >
+      <enum>Qt::Horizontal</enum>
+     </property>
+     <property name="standardButtons" >
+      <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+     </property>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>mButtonBox</sender>
+   <signal>accepted()</signal>
+   <receiver>QgsAvoidIntersectionsDialogBase</receiver>
+   <slot>accept()</slot>
+   <hints>
+    <hint type="sourcelabel" >
+     <x>248</x>
+     <y>254</y>
+    </hint>
+    <hint type="destinationlabel" >
+     <x>157</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>mButtonBox</sender>
+   <signal>rejected()</signal>
+   <receiver>QgsAvoidIntersectionsDialogBase</receiver>
+   <slot>reject()</slot>
+   <hints>
+    <hint type="sourcelabel" >
+     <x>316</x>
+     <y>260</y>
+    </hint>
+    <hint type="destinationlabel" >
+     <x>286</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>

Modified: trunk/qgis/src/ui/qgsprojectpropertiesbase.ui
===================================================================
--- trunk/qgis/src/ui/qgsprojectpropertiesbase.ui	2009-10-24 22:33:56 UTC (rev 11838)
+++ trunk/qgis/src/ui/qgsprojectpropertiesbase.ui	2009-10-25 15:18:29 UTC (rev 11839)
@@ -5,7 +5,7 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>492</width>
+    <width>500</width>
     <height>557</height>
    </rect>
   </property>
@@ -18,17 +18,7 @@
   <property name="modal" >
    <bool>true</bool>
   </property>
-  <layout class="QGridLayout" >
-   <item row="2" column="0" >
-    <widget class="QDialogButtonBox" name="buttonBox" >
-     <property name="orientation" >
-      <enum>Qt::Horizontal</enum>
-     </property>
-     <property name="standardButtons" >
-      <set>QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Help|QDialogButtonBox::NoButton|QDialogButtonBox::Ok</set>
-     </property>
-    </widget>
-   </item>
+  <layout class="QGridLayout" name="gridLayout_2" >
    <item row="0" column="0" >
     <widget class="QTabWidget" name="tabWidget" >
      <property name="currentIndex" >
@@ -80,7 +70,7 @@
             <property name="sizeType" >
              <enum>QSizePolicy::Expanding</enum>
             </property>
-            <property name="sizeHint" >
+            <property name="sizeHint" stdset="0" >
              <size>
               <width>40</width>
               <height>20</height>
@@ -116,7 +106,7 @@
             <property name="orientation" >
              <enum>Qt::Horizontal</enum>
             </property>
-            <property name="sizeHint" >
+            <property name="sizeHint" stdset="0" >
              <size>
               <width>40</width>
               <height>20</height>
@@ -163,7 +153,7 @@
             <property name="orientation" >
              <enum>Qt::Horizontal</enum>
             </property>
-            <property name="sizeHint" >
+            <property name="sizeHint" stdset="0" >
              <size>
               <width>40</width>
               <height>20</height>
@@ -286,7 +276,7 @@
          <property name="title" >
           <string>Digitizing</string>
          </property>
-         <layout class="QGridLayout" >
+         <layout class="QGridLayout" name="gridLayout" >
           <item row="0" column="0" >
            <widget class="QCheckBox" name="mEnableTopologicalEditingCheckBox" >
             <property name="text" >
@@ -295,9 +285,9 @@
            </widget>
           </item>
           <item row="1" column="0" >
-           <widget class="QCheckBox" name="mAvoidIntersectionsCheckBox" >
+           <widget class="QPushButton" name="mAvoidIntersectionsPushButton" >
             <property name="text" >
-             <string>Avoid intersections of new polygons</string>
+             <string>Avoid intersections of new polygons...</string>
             </property>
            </widget>
           </item>
@@ -373,6 +363,16 @@
      </widget>
     </widget>
    </item>
+   <item row="1" column="0" >
+    <widget class="QDialogButtonBox" name="buttonBox" >
+     <property name="orientation" >
+      <enum>Qt::Horizontal</enum>
+     </property>
+     <property name="standardButtons" >
+      <set>QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Help|QDialogButtonBox::Ok</set>
+     </property>
+    </widget>
+   </item>
   </layout>
  </widget>
  <layoutdefault spacing="6" margin="11" />
@@ -402,7 +402,6 @@
   <tabstop>radManual</tabstop>
   <tabstop>spinBoxDP</tabstop>
   <tabstop>mEnableTopologicalEditingCheckBox</tabstop>
-  <tabstop>mAvoidIntersectionsCheckBox</tabstop>
   <tabstop>mSnappingOptionsPushButton</tabstop>
   <tabstop>buttonBox</tabstop>
   <tabstop>cbxProjectionEnabled</tabstop>



More information about the QGIS-commit mailing list