Skip to content

Commit dd90eed

Browse files
author
jef
committed
[FEATURE] add multiple features at once (implements #2710)
git-svn-id: http://svn.osgeo.org/qgis/trunk/qgis@13505 c8812cc2-4d05-0410-92ff-de0c093fc19c
1 parent f7d7193 commit dd90eed

6 files changed

Lines changed: 140 additions & 77 deletions

File tree

‎python/gui/qgsrubberband.sip‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,24 @@ class QgsRubberBand: QgsMapCanvasItem
3434
@param render the maprender object (used for coord transformation)*/
3535
void setToGeometry(QgsGeometry* geom, QgsVectorLayer* layer);
3636

37+
/**Add the geometry of an existing feature to the rubberband.
38+
This is useful for multi feature highlighting.
39+
@param geom the geometry object
40+
@param layer the layer containing the feature, used for coord transformation to map
41+
crs. In case of 0 pointer, the coordinates are not going to be transformed.
42+
@param render the maprender object (used for coord transformation)
43+
@added in 1.5
44+
*/
45+
void addGeometry(QgsGeometry* geom, QgsVectorLayer* layer);
46+
3747
/**Adds translation to original coordinates (all in map coordinates)*/
3848
void setTranslationOffset(double dx, double dy);
3949

50+
/**Return number of geometries
51+
@added in 1.5
52+
*/
53+
int size();
54+
4055
/**Returns count of vertices in all lists of mPoint*/
4156
int numberOfVertices() const;
4257

‎src/app/qgisapp.cpp‎

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -754,9 +754,9 @@ void QgisApp::createActions()
754754
connect( mActionCapturePolygon, SIGNAL( triggered() ), this, SLOT( capturePolygon() ) );
755755
mActionCapturePolygon->setEnabled( false );
756756

757-
mActionMoveFeature = new QAction( getThemeIcon( "mActionMoveFeature.png" ), tr( "Move Feature" ), this );
757+
mActionMoveFeature = new QAction( getThemeIcon( "mActionMoveFeature.png" ), tr( "Move Feature(s)" ), this );
758758
shortcuts->registerAction( mActionMoveFeature );
759-
mActionMoveFeature->setStatusTip( tr( "Move Feature" ) );
759+
mActionMoveFeature->setStatusTip( tr( "Move Feature(s)" ) );
760760
connect( mActionMoveFeature, SIGNAL( triggered() ), this, SLOT( moveFeature() ) );
761761
mActionMoveFeature->setEnabled( false );
762762

@@ -4645,24 +4645,21 @@ void QgisApp::layerSubsetString()
46454645

46464646
bool QgisApp::toggleEditing( QgsMapLayer *layer, bool allowCancel )
46474647
{
4648-
if ( !layer )
4649-
{
4650-
return false;
4651-
}
4652-
46534648
QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( layer );
46544649
if ( !vlayer )
46554650
{
46564651
return false;
46574652
}
46584653

4654+
bool res = true;
4655+
46594656
if ( !vlayer->isEditable() )
46604657
{
46614658
vlayer->startEditing();
46624659
if ( !( vlayer->dataProvider()->capabilities() & QgsVectorDataProvider::EditingCapabilities ) )
46634660
{
46644661
QMessageBox::information( 0, tr( "Start editing failed" ), tr( "Provider cannot be opened for editing" ) );
4665-
return false;
4662+
res = false;
46664663
}
46674664
}
46684665
else if ( vlayer->isModified() )
@@ -4677,8 +4674,8 @@ bool QgisApp::toggleEditing( QgsMapLayer *layer, bool allowCancel )
46774674
buttons ) )
46784675
{
46794676
case QMessageBox::Cancel:
4680-
mActionToggleEditing->setChecked( vlayer->isEditable() );
4681-
return false;
4677+
res = false;
4678+
break;
46824679

46834680
case QMessageBox::Save:
46844681
if ( !vlayer->commitChanges() )
@@ -4691,15 +4688,15 @@ bool QgisApp::toggleEditing( QgsMapLayer *layer, bool allowCancel )
46914688
// Leave the in-memory editing state alone,
46924689
// to give the user a chance to enter different values
46934690
// and try the commit again later
4694-
return false;
4691+
res = false;
46954692
}
46964693
break;
46974694

46984695
case QMessageBox::Discard:
46994696
if ( !vlayer->rollBack() )
47004697
{
47014698
QMessageBox::information( 0, tr( "Error" ), tr( "Problems during roll back" ) );
4702-
return false;
4699+
res = false;
47034700
}
47044701
break;
47054702

@@ -4710,17 +4707,17 @@ bool QgisApp::toggleEditing( QgsMapLayer *layer, bool allowCancel )
47104707
else //layer not modified
47114708
{
47124709
vlayer->rollBack();
4710+
res = true;
47134711
}
47144712

47154713
if ( layer == activeLayer() )
47164714
{
47174715
activateDeactivateLayerRelatedActions( layer );
47184716
}
47194717

4720-
//ensure the toolbar icon state is consistent with the layer editing state
4721-
mActionToggleEditing->setChecked( vlayer->isEditable() );
47224718
vlayer->triggerRepaint();
4723-
return true;
4719+
4720+
return res;
47244721
}
47254722

47264723
void QgisApp::showMouseCoordinate( const QgsPoint & p )

‎src/app/qgsmaptoolmovefeature.cpp‎

Lines changed: 46 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@ void QgsMapToolMoveFeature::canvasMoveEvent( QMouseEvent * e )
4444
double offsetX = pointCanvasCoords.x() - mStartPointMapCoords.x();
4545
double offsetY = pointCanvasCoords.y() - mStartPointMapCoords.y();
4646
mRubberBand->setTranslationOffset( offsetX, offsetY );
47-
//QgsDebugMsg("move Rubber band by: " + QString::number(e->x() - mLastPointPixelCoords.x()) + " // " + QString::number(e->y() - mLastPointPixelCoords.y()));
4847
mRubberBand->updatePosition();
4948
mRubberBand->update();
5049
}
@@ -76,46 +75,64 @@ void QgsMapToolMoveFeature::canvasPressEvent( QMouseEvent * e )
7675
QgsRectangle selectRect( layerCoords.x() - searchRadius, layerCoords.y() - searchRadius,
7776
layerCoords.x() + searchRadius, layerCoords.y() + searchRadius );
7877

79-
vlayer->select( QgsAttributeList(), selectRect, true );
80-
81-
//find the closest feature
82-
QgsGeometry* pointGeometry = QgsGeometry::fromPoint( layerCoords );
83-
if ( !pointGeometry )
78+
if ( vlayer->selectedFeatureCount() == 0 )
8479
{
85-
return;
86-
}
80+
vlayer->select( QgsAttributeList(), selectRect, true );
8781

88-
double minDistance = std::numeric_limits<double>::max();
82+
//find the closest feature
83+
QgsGeometry* pointGeometry = QgsGeometry::fromPoint( layerCoords );
84+
if ( !pointGeometry )
85+
{
86+
return;
87+
}
8988

90-
QgsFeature cf;
91-
QgsFeature f;
92-
while ( vlayer->nextFeature( f ) )
93-
{
94-
if ( f.geometry() )
89+
double minDistance = std::numeric_limits<double>::max();
90+
91+
QgsFeature cf;
92+
QgsFeature f;
93+
while ( vlayer->nextFeature( f ) )
9594
{
96-
double currentDistance = pointGeometry->distance( *f.geometry() );
97-
if ( currentDistance < minDistance )
95+
if ( f.geometry() )
9896
{
99-
minDistance = currentDistance;
100-
cf = f;
97+
double currentDistance = pointGeometry->distance( *f.geometry() );
98+
if ( currentDistance < minDistance )
99+
{
100+
minDistance = currentDistance;
101+
cf = f;
102+
}
101103
}
104+
102105
}
103-
}
104106

105-
if ( minDistance == std::numeric_limits<double>::max() )
107+
delete pointGeometry;
108+
109+
if ( minDistance == std::numeric_limits<double>::max() )
110+
{
111+
return;
112+
}
113+
114+
mMovedFeatures.clear();
115+
mMovedFeatures << cf.id(); //todo: take the closest feature, not the first one...
116+
117+
mRubberBand = createRubberBand();
118+
mRubberBand->setToGeometry( cf.geometry(), vlayer );
119+
}
120+
else
106121
{
107-
return;
122+
mMovedFeatures = vlayer->selectedFeaturesIds();
123+
124+
mRubberBand = createRubberBand();
125+
for ( int i = 0; i < vlayer->selectedFeatureCount(); i++ )
126+
{
127+
mRubberBand->addGeometry( vlayer->selectedFeatures()[i].geometry(), vlayer );
128+
}
108129
}
109130

110131
mStartPointMapCoords = toMapCoordinates( e->pos() );
111-
mMovedFeature = cf.id(); //todo: take the closest feature, not the first one...
112-
mRubberBand = createRubberBand();
113-
mRubberBand->setToGeometry( cf.geometry(), vlayer );
114132
mRubberBand->setColor( Qt::red );
115133
mRubberBand->setWidth( 2 );
116134
mRubberBand->show();
117135

118-
delete pointGeometry;
119136
}
120137

121138
void QgsMapToolMoveFeature::canvasReleaseEvent( QMouseEvent * e )
@@ -138,7 +155,10 @@ void QgsMapToolMoveFeature::canvasReleaseEvent( QMouseEvent * e )
138155
double dx = stopPointLayerCoords.x() - startPointLayerCoords.x();
139156
double dy = stopPointLayerCoords.y() - startPointLayerCoords.y();
140157
vlayer->beginEditCommand( tr( "Feature moved" ) );
141-
vlayer->translateFeature( mMovedFeature, dx, dy );
158+
foreach( int id, mMovedFeatures )
159+
{
160+
vlayer->translateFeature( id, dx, dy );
161+
}
142162
delete mRubberBand;
143163
mRubberBand = 0;
144164
mCanvas->refresh();

‎src/app/qgsmaptoolmovefeature.h‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#define QGSMAPTOOLMOVEFEATURE_H
1919

2020
#include "qgsmaptooledit.h"
21+
#include "qgsvectorlayer.h"
2122

2223
/**Map tool for translating feature position by mouse drag*/
2324
class QgsMapToolMoveFeature: public QgsMapToolEdit
@@ -44,7 +45,7 @@ class QgsMapToolMoveFeature: public QgsMapToolEdit
4445
QgsRubberBand* mRubberBand;
4546

4647
/**Id of moved feature*/
47-
int mMovedFeature;
48+
QgsFeatureIds mMovedFeatures;
4849
};
4950

5051
#endif

0 commit comments

Comments
 (0)