Skip to content
Permalink
Browse files
[FEATURE] add multiple features at once (implements #2710)
git-svn-id: http://svn.osgeo.org/qgis/trunk@13505 c8812cc2-4d05-0410-92ff-de0c093fc19c
  • Loading branch information
jef committed May 16, 2010
1 parent bd021cc commit e03e5a146a422939bfbbfab863454e9d9890cca2
@@ -34,9 +34,24 @@ class QgsRubberBand: QgsMapCanvasItem
@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;

@@ -754,9 +754,9 @@ void QgisApp::createActions()
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 @@ void QgisApp::layerSubsetString()

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 @@ bool QgisApp::toggleEditing( QgsMapLayer *layer, bool allowCancel )
buttons ) )
{
case QMessageBox::Cancel:
mActionToggleEditing->setChecked( vlayer->isEditable() );
return false;
res = false;
break;

case QMessageBox::Save:
if ( !vlayer->commitChanges() )
@@ -4691,15 +4688,15 @@ bool QgisApp::toggleEditing( QgsMapLayer *layer, bool allowCancel )
// 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;

case QMessageBox::Discard:
if ( !vlayer->rollBack() )
{
QMessageBox::information( 0, tr( "Error" ), tr( "Problems during roll back" ) );
return false;
res = false;
}
break;

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

if ( layer == activeLayer() )
{
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 )
@@ -44,7 +44,6 @@ void QgsMapToolMoveFeature::canvasMoveEvent( QMouseEvent * e )
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 @@ void QgsMapToolMoveFeature::canvasPressEvent( QMouseEvent * e )
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;
}
}

}
}

if ( minDistance == std::numeric_limits<double>::max() )
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
{
return;
mMovedFeatures = vlayer->selectedFeaturesIds();

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 @@ void QgsMapToolMoveFeature::canvasReleaseEvent( QMouseEvent * e )
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();
@@ -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 @@ class QgsMapToolMoveFeature: public QgsMapToolEdit
QgsRubberBand* mRubberBand;

/**Id of moved feature*/
int mMovedFeature;
QgsFeatureIds mMovedFeatures;
};

#endif

0 comments on commit e03e5a1

Please sign in to comment.