[QGIS Commit] r13505 - in trunk/qgis: python/gui src/app src/gui

svn_qgis at osgeo.org svn_qgis at osgeo.org
Sun May 16 14:36:21 EDT 2010


Author: jef
Date: 2010-05-16 14:36:20 -0400 (Sun, 16 May 2010)
New Revision: 13505

Modified:
   trunk/qgis/python/gui/qgsrubberband.sip
   trunk/qgis/src/app/qgisapp.cpp
   trunk/qgis/src/app/qgsmaptoolmovefeature.cpp
   trunk/qgis/src/app/qgsmaptoolmovefeature.h
   trunk/qgis/src/gui/qgsrubberband.cpp
   trunk/qgis/src/gui/qgsrubberband.h
Log:
[FEATURE] add multiple features at once (implements #2710)


Modified: trunk/qgis/python/gui/qgsrubberband.sip
===================================================================
--- trunk/qgis/python/gui/qgsrubberband.sip	2010-05-16 16:45:48 UTC (rev 13504)
+++ trunk/qgis/python/gui/qgsrubberband.sip	2010-05-16 18:36:20 UTC (rev 13505)
@@ -34,9 +34,24 @@
     @param render the maprender object (used for coord transformation)*/
     void setToGeometry(QgsGeometry* geom, QgsVectorLayer* layer);
 
+    /**Add the geometry of an existing feature to the rubberband.
+     This is useful for multi feature highlighting.
+    @param geom the geometry object
+    @param layer the layer containing the feature, used for coord transformation to map 
+    crs. In case of 0 pointer, the coordinates are not going to be transformed.
+    @param render the maprender object (used for coord transformation)
+    @added in 1.5
+    */
+    void addGeometry(QgsGeometry* geom, QgsVectorLayer* layer);
+
     /**Adds translation to original coordinates (all in map coordinates)*/
     void setTranslationOffset(double dx, double dy);
 
+    /**Return number of geometries 
+     @added in 1.5
+     */
+    int size();
+
     /**Returns count of vertices in all lists of mPoint*/
     int numberOfVertices() const;
 

Modified: trunk/qgis/src/app/qgisapp.cpp
===================================================================
--- trunk/qgis/src/app/qgisapp.cpp	2010-05-16 16:45:48 UTC (rev 13504)
+++ trunk/qgis/src/app/qgisapp.cpp	2010-05-16 18:36:20 UTC (rev 13505)
@@ -754,9 +754,9 @@
   connect( mActionCapturePolygon, SIGNAL( triggered() ), this, SLOT( capturePolygon() ) );
   mActionCapturePolygon->setEnabled( false );
 
-  mActionMoveFeature = new QAction( getThemeIcon( "mActionMoveFeature.png" ), tr( "Move Feature" ), this );
+  mActionMoveFeature = new QAction( getThemeIcon( "mActionMoveFeature.png" ), tr( "Move Feature(s)" ), this );
   shortcuts->registerAction( mActionMoveFeature );
-  mActionMoveFeature->setStatusTip( tr( "Move Feature" ) );
+  mActionMoveFeature->setStatusTip( tr( "Move Feature(s)" ) );
   connect( mActionMoveFeature, SIGNAL( triggered() ), this, SLOT( moveFeature() ) );
   mActionMoveFeature->setEnabled( false );
 
@@ -4645,24 +4645,21 @@
 
 bool QgisApp::toggleEditing( QgsMapLayer *layer, bool allowCancel )
 {
-  if ( !layer )
-  {
-    return false;
-  }
-
   QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( layer );
   if ( !vlayer )
   {
     return false;
   }
 
+  bool res = true;
+
   if ( !vlayer->isEditable() )
   {
     vlayer->startEditing();
     if ( !( vlayer->dataProvider()->capabilities() & QgsVectorDataProvider::EditingCapabilities ) )
     {
       QMessageBox::information( 0, tr( "Start editing failed" ), tr( "Provider cannot be opened for editing" ) );
-      return false;
+      res = false;
     }
   }
   else if ( vlayer->isModified() )
@@ -4677,8 +4674,8 @@
                                        buttons ) )
     {
       case QMessageBox::Cancel:
-        mActionToggleEditing->setChecked( vlayer->isEditable() );
-        return false;
+        res = false;
+        break;
 
       case QMessageBox::Save:
         if ( !vlayer->commitChanges() )
@@ -4691,7 +4688,7 @@
           // Leave the in-memory editing state alone,
           // to give the user a chance to enter different values
           // and try the commit again later
-          return false;
+          res = false;
         }
         break;
 
@@ -4699,7 +4696,7 @@
         if ( !vlayer->rollBack() )
         {
           QMessageBox::information( 0, tr( "Error" ), tr( "Problems during roll back" ) );
-          return false;
+          res = false;
         }
         break;
 
@@ -4710,6 +4707,7 @@
   else //layer not modified
   {
     vlayer->rollBack();
+    res = true;
   }
 
   if ( layer == activeLayer() )
@@ -4717,10 +4715,9 @@
     activateDeactivateLayerRelatedActions( layer );
   }
 
-  //ensure the toolbar icon state is consistent with the layer editing state
-  mActionToggleEditing->setChecked( vlayer->isEditable() );
   vlayer->triggerRepaint();
-  return true;
+
+  return res;
 }
 
 void QgisApp::showMouseCoordinate( const QgsPoint & p )

Modified: trunk/qgis/src/app/qgsmaptoolmovefeature.cpp
===================================================================
--- trunk/qgis/src/app/qgsmaptoolmovefeature.cpp	2010-05-16 16:45:48 UTC (rev 13504)
+++ trunk/qgis/src/app/qgsmaptoolmovefeature.cpp	2010-05-16 18:36:20 UTC (rev 13505)
@@ -44,7 +44,6 @@
     double offsetX = pointCanvasCoords.x() - mStartPointMapCoords.x();
     double offsetY = pointCanvasCoords.y() - mStartPointMapCoords.y();
     mRubberBand->setTranslationOffset( offsetX, offsetY );
-    //QgsDebugMsg("move Rubber band by: " + QString::number(e->x() - mLastPointPixelCoords.x()) + " // " + QString::number(e->y() - mLastPointPixelCoords.y()));
     mRubberBand->updatePosition();
     mRubberBand->update();
   }
@@ -76,46 +75,64 @@
   QgsRectangle selectRect( layerCoords.x() - searchRadius, layerCoords.y() - searchRadius,
                            layerCoords.x() + searchRadius, layerCoords.y() + searchRadius );
 
-  vlayer->select( QgsAttributeList(), selectRect, true );
-
-  //find the closest feature
-  QgsGeometry* pointGeometry = QgsGeometry::fromPoint( layerCoords );
-  if ( !pointGeometry )
+  if ( vlayer->selectedFeatureCount() == 0 )
   {
-    return;
-  }
+    vlayer->select( QgsAttributeList(), selectRect, true );
 
-  double minDistance = std::numeric_limits<double>::max();
+    //find the closest feature
+    QgsGeometry* pointGeometry = QgsGeometry::fromPoint( layerCoords );
+    if ( !pointGeometry )
+    {
+      return;
+    }
 
-  QgsFeature cf;
-  QgsFeature f;
-  while ( vlayer->nextFeature( f ) )
-  {
-    if ( f.geometry() )
+    double minDistance = std::numeric_limits<double>::max();
+
+    QgsFeature cf;
+    QgsFeature f;
+    while ( vlayer->nextFeature( f ) )
     {
-      double currentDistance = pointGeometry->distance( *f.geometry() );
-      if ( currentDistance < minDistance )
+      if ( f.geometry() )
       {
-        minDistance = currentDistance;
-        cf = f;
+        double currentDistance = pointGeometry->distance( *f.geometry() );
+        if ( currentDistance < minDistance )
+        {
+          minDistance = currentDistance;
+          cf = f;
+        }
       }
+
     }
+
+    delete pointGeometry;
+
+    if ( minDistance == std::numeric_limits<double>::max() )
+    {
+      return;
+    }
+
+    mMovedFeatures.clear();
+    mMovedFeatures << cf.id(); //todo: take the closest feature, not the first one...
+
+    mRubberBand = createRubberBand();
+    mRubberBand->setToGeometry( cf.geometry(), vlayer );
   }
+  else
+  {
+    mMovedFeatures = vlayer->selectedFeaturesIds();
 
-  if ( minDistance == std::numeric_limits<double>::max() )
-  {
-    return;
+    mRubberBand = createRubberBand();
+    for ( int i = 0; i < vlayer->selectedFeatureCount(); i++ )
+    {
+      mRubberBand->addGeometry( vlayer->selectedFeatures()[i].geometry(), vlayer );
+    }
   }
 
   mStartPointMapCoords = toMapCoordinates( e->pos() );
-  mMovedFeature = cf.id(); //todo: take the closest feature, not the first one...
-  mRubberBand = createRubberBand();
-  mRubberBand->setToGeometry( cf.geometry(), vlayer );
   mRubberBand->setColor( Qt::red );
   mRubberBand->setWidth( 2 );
   mRubberBand->show();
 
-  delete pointGeometry;
 }
 
 void QgsMapToolMoveFeature::canvasReleaseEvent( QMouseEvent * e )
@@ -138,7 +155,10 @@
   double dx = stopPointLayerCoords.x() - startPointLayerCoords.x();
   double dy = stopPointLayerCoords.y() - startPointLayerCoords.y();
   vlayer->beginEditCommand( tr( "Feature moved" ) );
-  vlayer->translateFeature( mMovedFeature, dx, dy );
+  foreach( int id, mMovedFeatures )
+  {
+    vlayer->translateFeature( id, dx, dy );
+  }
   delete mRubberBand;
   mRubberBand = 0;
   mCanvas->refresh();

Modified: trunk/qgis/src/app/qgsmaptoolmovefeature.h
===================================================================
--- trunk/qgis/src/app/qgsmaptoolmovefeature.h	2010-05-16 16:45:48 UTC (rev 13504)
+++ trunk/qgis/src/app/qgsmaptoolmovefeature.h	2010-05-16 18:36:20 UTC (rev 13505)
@@ -18,6 +18,7 @@
 #define QGSMAPTOOLMOVEFEATURE_H
 
 #include "qgsmaptooledit.h"
+#include "qgsvectorlayer.h"
 
 /**Map tool for translating feature position by mouse drag*/
 class QgsMapToolMoveFeature: public QgsMapToolEdit
@@ -44,7 +45,7 @@
     QgsRubberBand* mRubberBand;
 
     /**Id of moved feature*/
-    int mMovedFeature;
+    QgsFeatureIds mMovedFeatures;
 };
 
 #endif

Modified: trunk/qgis/src/gui/qgsrubberband.cpp
===================================================================
--- trunk/qgis/src/gui/qgsrubberband.cpp	2010-05-16 16:45:48 UTC (rev 13504)
+++ trunk/qgis/src/gui/qgsrubberband.cpp	2010-05-16 18:36:20 UTC (rev 13505)
@@ -65,10 +65,7 @@
   */
 void QgsRubberBand::reset( bool isPolygon )
 {
-
   mPoints.clear();
-  QList< QgsPoint > initial_list;
-  mPoints.push_back( initial_list );
   mIsPolygon = isPolygon;
   updateRect();
   update();
@@ -79,12 +76,22 @@
   */
 void QgsRubberBand::addPoint( const QgsPoint & p, bool do_update /* = true */, int geometryIndex )
 {
-  if ( mPoints.size() < ( geometryIndex + 1 ) )
+  if ( geometryIndex < 0 )
   {
+    geometryIndex = mPoints.size() - 1;
+  }
+
+  if ( geometryIndex < 0 || geometryIndex > mPoints.size() )
+  {
     return;
   }
 
-  //we need to set two points at the begin of the ruber band for operations that move the last point
+  if ( geometryIndex == mPoints.size() )
+  {
+    mPoints.push_back( QList<QgsPoint>() );
+  }
+
+  //we need to set two points at the begin of the rubber band for operations that move the last point
   if ( mPoints[geometryIndex].size() == 0 )
   {
     mPoints[geometryIndex].push_back( p );
@@ -100,7 +107,7 @@
 
 void QgsRubberBand::removeLastPoint( int geometryIndex )
 {
-  if ( mPoints.size() < ( geometryIndex + 1 ) )
+  if ( mPoints.size() < geometryIndex + 1 )
   {
     return;
   }
@@ -119,7 +126,7 @@
   */
 void QgsRubberBand::movePoint( const QgsPoint & p, int geometryIndex )
 {
-  if ( mPoints.size() < ( geometryIndex + 1 ) )
+  if ( mPoints.size() < geometryIndex + 1 )
   {
     return;
   }
@@ -137,7 +144,7 @@
 
 void QgsRubberBand::movePoint( int index, const QgsPoint& p, int geometryIndex )
 {
-  if ( mPoints.size() < ( geometryIndex + 1 ) )
+  if ( mPoints.size() < geometryIndex + 1 )
   {
     return;
   }
@@ -155,6 +162,12 @@
 
 void QgsRubberBand::setToGeometry( QgsGeometry* geom, QgsVectorLayer* layer )
 {
+  reset( mIsPolygon );
+  addGeometry( geom, layer );
+}
+
+void QgsRubberBand::addGeometry( QgsGeometry* geom, QgsVectorLayer* layer )
+{
   if ( !geom )
   {
     return;
@@ -167,7 +180,7 @@
     return;
   }
 
-  reset( mIsPolygon );
+  int idx = mPoints.size();
 
   switch ( geom->wkbType() )
   {
@@ -186,10 +199,10 @@
       {
         pt = geom->asPoint();
       }
-      addPoint( QgsPoint( pt.x() - d, pt.y() - d ), false );
-      addPoint( QgsPoint( pt.x() + d, pt.y() - d ), false );
-      addPoint( QgsPoint( pt.x() + d, pt.y() + d ), false );
-      addPoint( QgsPoint( pt.x() - d, pt.y() + d ), false );
+      addPoint( QgsPoint( pt.x() - d, pt.y() - d ), false, idx );
+      addPoint( QgsPoint( pt.x() + d, pt.y() - d ), false, idx );
+      addPoint( QgsPoint( pt.x() + d, pt.y() + d ), false, idx );
+      addPoint( QgsPoint( pt.x() - d, pt.y() + d ), false, idx );
     }
     break;
 
@@ -199,23 +212,22 @@
       mIsPolygon = true;
       double d = mMapCanvas->extent().width() * 0.005;
       QgsMultiPoint mpt = geom->asMultiPoint();
-      for ( int i = 0; i < mpt.size(); ++i )
+      for ( int i = 0; i < mpt.size(); ++i, ++idx )
       {
         QgsPoint pt = mpt[i];
-        mPoints.push_back( QList<QgsPoint>() );
         if ( layer )
         {
-          addPoint( mr->layerToMapCoordinates( layer, QgsPoint( pt.x() - d, pt.y() - d ) ), false, i );
-          addPoint( mr->layerToMapCoordinates( layer, QgsPoint( pt.x() + d, pt.y() - d ) ), false, i );
-          addPoint( mr->layerToMapCoordinates( layer, QgsPoint( pt.x() + d, pt.y() + d ) ), false, i );
-          addPoint( mr->layerToMapCoordinates( layer, QgsPoint( pt.x() - d, pt.y() + d ) ), false, i );
+          addPoint( mr->layerToMapCoordinates( layer, QgsPoint( pt.x() - d, pt.y() - d ) ), false, idx );
+          addPoint( mr->layerToMapCoordinates( layer, QgsPoint( pt.x() + d, pt.y() - d ) ), false, idx );
+          addPoint( mr->layerToMapCoordinates( layer, QgsPoint( pt.x() + d, pt.y() + d ) ), false, idx );
+          addPoint( mr->layerToMapCoordinates( layer, QgsPoint( pt.x() - d, pt.y() + d ) ), false, idx );
         }
         else
         {
-          addPoint( QgsPoint( pt.x() - d, pt.y() - d ), false, i );
-          addPoint( QgsPoint( pt.x() + d, pt.y() - d ), false, i );
-          addPoint( QgsPoint( pt.x() + d, pt.y() + d ), false, i );
-          addPoint( QgsPoint( pt.x() - d, pt.y() + d ), false, i );
+          addPoint( QgsPoint( pt.x() - d, pt.y() - d ), false, idx );
+          addPoint( QgsPoint( pt.x() + d, pt.y() - d ), false, idx );
+          addPoint( QgsPoint( pt.x() + d, pt.y() + d ), false, idx );
+          addPoint( QgsPoint( pt.x() - d, pt.y() + d ), false, idx );
         }
       }
     }
@@ -230,11 +242,11 @@
       {
         if ( layer )
         {
-          addPoint( mr->layerToMapCoordinates( layer, line[i] ), false );
+          addPoint( mr->layerToMapCoordinates( layer, line[i] ), false, idx );
         }
         else
         {
-          addPoint( line[i], false );
+          addPoint( line[i], false, idx );
         }
       }
     }
@@ -247,19 +259,18 @@
       mPoints.clear();
 
       QgsMultiPolyline mline = geom->asMultiPolyline();
-      for ( int i = 0; i < mline.size(); ++i )
+      for ( int i = 0; i < mline.size(); ++i, ++idx )
       {
-        mPoints.push_back( QList<QgsPoint>() );
         QgsPolyline line = mline[i];
         for ( int j = 0; j < line.size(); ++j )
         {
           if ( layer )
           {
-            addPoint( mr->layerToMapCoordinates( layer, line[j] ), false, i );
+            addPoint( mr->layerToMapCoordinates( layer, line[j] ), false, idx );
           }
           else
           {
-            addPoint( line[j], false, i );
+            addPoint( line[j], false, idx );
           }
         }
       }
@@ -276,11 +287,11 @@
       {
         if ( layer )
         {
-          addPoint( mr->layerToMapCoordinates( layer, line[i] ), false );
+          addPoint( mr->layerToMapCoordinates( layer, line[i] ), false, idx );
         }
         else
         {
-          addPoint( line[i], false );
+          addPoint( line[i], false, idx );
         }
       }
     }
@@ -293,20 +304,19 @@
       mPoints.clear();
 
       QgsMultiPolygon multipoly = geom->asMultiPolygon();
-      for ( int i = 0; i < multipoly.size(); ++i )
+      for ( int i = 0; i < multipoly.size(); ++i, ++idx )
       {
-        mPoints.push_back( QList<QgsPoint>() );
         QgsPolygon poly = multipoly[i];
         QgsPolyline line = poly[0];
         for ( int j = 0; j < line.count(); ++j )
         {
           if ( layer )
           {
-            addPoint( mr->layerToMapCoordinates( layer, line[j] ), false, i );
+            addPoint( mr->layerToMapCoordinates( layer, line[j] ), false, idx );
           }
           else
           {
-            addPoint( line[j], false, i );
+            addPoint( line[j], false, idx );
           }
         }
       }
@@ -317,6 +327,7 @@
     default:
       return;
   }
+
   updateRect();
   update();
 }
@@ -393,6 +404,11 @@
   updateRect();
 }
 
+int QgsRubberBand::size() const
+{
+  return mPoints.size();
+}
+
 int QgsRubberBand::numberOfVertices() const
 {
   int count = 0;

Modified: trunk/qgis/src/gui/qgsrubberband.h
===================================================================
--- trunk/qgis/src/gui/qgsrubberband.h	2010-05-16 16:45:48 UTC (rev 13504)
+++ trunk/qgis/src/gui/qgsrubberband.h	2010-05-16 18:36:20 UTC (rev 13505)
@@ -61,9 +61,23 @@
     @param render the maprender object (used for coord transformation)*/
     void setToGeometry( QgsGeometry* geom, QgsVectorLayer* layer );
 
+    /**Add the geometry of an existing feature to a rubberband
+     This is useful for multi feature highlighting.
+    @param geom the geometry object
+    @param layer the layer containing the feature, used for coord transformation to map
+    crs. In case of 0 pointer, the coordinates are not going to be transformed.
+    @param render the maprender object (used for coord transformation)
+    @noted added in 1.5
+    */
+    void addGeometry( QgsGeometry* geom, QgsVectorLayer* layer );
+
     /**Adds translation to original coordinates (all in map coordinates)*/
     void setTranslationOffset( double dx, double dy );
 
+    /**Returns number of geometries
+     * added in 1.5 */
+    int size() const;
+
     /**Returns count of vertices in all lists of mPoint*/
     int numberOfVertices() const;
 



More information about the QGIS-commit mailing list