Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[FEATURE] improve attribute handling
- optionally reuse entered attribute values for next digitized feature
- allow merging/assigning attribute values to a set of features


git-svn-id: http://svn.osgeo.org/qgis/trunk@14599 c8812cc2-4d05-0410-92ff-de0c093fc19c
  • Loading branch information
jef committed Nov 13, 2010
1 parent ee82cf4 commit b1bf738
Show file tree
Hide file tree
Showing 11 changed files with 628 additions and 516 deletions.
3 changes: 3 additions & 0 deletions images/images.qrc
Expand Up @@ -44,6 +44,7 @@
<file>themes/newgis/mActionMeasure.png</file>
<file>themes/newgis/mActionMeasureArea.png</file>
<file>themes/newgis/mActionMergeFeatures.png</file>
<file>themes/newgis/mActionMergeFeatureAttributes.png</file>
<file>themes/newgis/mActionMoveFeature.png</file>
<file>themes/newgis/mActionMoveItemContent.png</file>
<file>themes/newgis/mActionMoveVertex.png</file>
Expand Down Expand Up @@ -165,6 +166,7 @@
<file>themes/default/mActionMeasureAngle.png</file>
<file>themes/default/mActionMeasureArea.png</file>
<file>themes/default/mActionMergeFeatures.png</file>
<file>themes/default/mActionMergeFeatureAttributes.png</file>
<file>themes/default/mActionMoveFeature.png</file>
<file>themes/default/mActionMoveItemContent.png</file>
<file>themes/default/mActionMoveItemsToBottom.png</file>
Expand Down Expand Up @@ -332,6 +334,7 @@
<file>themes/gis/mActionMeasureAngle.png</file>
<file>themes/gis/mActionMeasureArea.png</file>
<file>themes/gis/mActionMergeFeatures.png</file>
<file>themes/gis/mActionMergeFeatureAttributes.png</file>
<file>themes/gis/mActionMoveFeature.png</file>
<file>themes/gis/mActionMoveItemContent.png</file>
<file>themes/gis/mActionMoveItemsToBottom.png</file>
Expand Down
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/themes/gis/mActionMergeFeatureAttributes.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
953 changes: 514 additions & 439 deletions src/app/qgisapp.cpp

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions src/app/qgisapp.h
Expand Up @@ -612,6 +612,8 @@ class QgisApp : public QMainWindow
void deletePart();
//! merges the selected features together
void mergeSelectedFeatures();
//! merges the attributes of selected features
void mergeAttributesOfSelectedFeatures();
//! provides operations with nodes
void nodeTool();
//! activates the rotate points tool
Expand Down Expand Up @@ -894,6 +896,7 @@ class QgisApp : public QMainWindow
QAction *mActionDeleteRing;
QAction *mActionDeletePart;
QAction *mActionMergeFeatures;
QAction *mActionMergeFeatureAttributes;
QAction *mActionNodeTool;
QAction *mActionRotatePointSymbols;
QAction *mActionEditSeparator3;
Expand Down
152 changes: 84 additions & 68 deletions src/app/qgsmaptooladdfeature.cpp
Expand Up @@ -31,10 +31,6 @@
#include <QMouseEvent>
#include <QSettings>

#ifdef Q_OS_WIN
#include <qgisapp.h>
#endif

QgsMapToolAddFeature::QgsMapToolAddFeature( QgsMapCanvas* canvas, CaptureMode tool ): QgsMapToolCapture( canvas, tool )
{

Expand All @@ -45,8 +41,79 @@ QgsMapToolAddFeature::~QgsMapToolAddFeature()

}

bool QgsMapToolAddFeature::addFeature( QgsVectorLayer *vlayer, QgsFeature *f )
{
bool res = false;
QgsVectorDataProvider* provider = vlayer->dataProvider();

QSettings settings;
bool reuseLastValues = settings.value( "/qgis/digitizing/reuseLastValues", false ).toBool();
QgsDebugMsg( QString( "reuseLastValues: %1" ).arg( reuseLastValues ) );

// add the fields to the QgsFeature
const QgsFieldMap fields = vlayer->pendingFields();
for ( QgsFieldMap::const_iterator it = fields.constBegin(); it != fields.constEnd(); ++it )
{
if ( reuseLastValues && mLastUsedValues.contains( vlayer ) && mLastUsedValues[ vlayer ].contains( it.key() ) )
{
QgsDebugMsg( QString( "reusing %1 for %2" ).arg( mLastUsedValues[ vlayer ][ it.key()].toString() ).arg( it.key() ) );
f->addAttribute( it.key(), mLastUsedValues[ vlayer ][ it.key()] );
}
else
{
f->addAttribute( it.key(), provider->defaultValue( it.key() ) );
}
}

// show the dialog to enter attribute values
bool isDisabledAttributeValuesDlg = settings.value( "/qgis/digitizing/disable_enter_attribute_values_dialog", true ).toBool();
if ( isDisabledAttributeValuesDlg )
{
res = vlayer->addFeature( *f );
}
else
{
QgsAttributeDialog *mypDialog = new QgsAttributeDialog( vlayer, f );

QgsAttributeMap origValues;
if ( reuseLastValues )
origValues = f->attributeMap();

if ( mypDialog->exec() )
{
if ( reuseLastValues )
{
for ( QgsFieldMap::const_iterator it = fields.constBegin(); it != fields.constEnd(); ++it )
{
const QgsAttributeMap &newValues = f->attributeMap();
if ( newValues.contains( it.key() )
&& origValues.contains( it.key() )
&& origValues[ it.key()] != newValues[ it.key()] )
{
QgsDebugMsg( QString( "saving %1 for %2" ).arg( mLastUsedValues[ vlayer ][ it.key()].toString() ).arg( it.key() ) );
mLastUsedValues[ vlayer ][ it.key()] = newValues[ it.key()];
}
}
}

res = vlayer->addFeature( *f );
}
else
{
QgsDebugMsg( "Adding feature to layer failed" );
res = false;
}

mypDialog->deleteLater();
}

return res;
}

void QgsMapToolAddFeature::canvasReleaseEvent( QMouseEvent * e )
{
QgsDebugMsg( "entered." );

QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( mCanvas->currentLayer() );

if ( !vlayer )
Expand Down Expand Up @@ -160,45 +227,21 @@ void QgsMapToolAddFeature::canvasReleaseEvent( QMouseEvent * e )
}

f->setGeometryAndOwnership( &wkb[0], size );
// add the fields to the QgsFeature
const QgsFieldMap fields = vlayer->pendingFields();
for ( QgsFieldMap::const_iterator it = fields.constBegin(); it != fields.constEnd(); ++it )
{
f->addAttribute( it.key(), provider->defaultValue( it.key() ) );
}

vlayer->beginEditCommand( tr( "Feature added" ) );

// show the dialog to enter attribute values
QSettings settings;
bool isDisabledAttributeValuesDlg = settings.value( "/qgis/digitizing/disable_enter_attribute_values_dialog", false ).toBool();
if ( isDisabledAttributeValuesDlg )
if ( addFeature( vlayer, f ) )
{
QgsDebugMsg( "Adding feature to layer" );
vlayer->addFeature( *f );
vlayer->endEditCommand();
}
else
{
QgsAttributeDialog *mypDialog = new QgsAttributeDialog( vlayer, f );
if ( mypDialog->exec() )
{
QgsDebugMsg( "Adding feature to layer" );
vlayer->addFeature( *f );
vlayer->endEditCommand();
}
else
{
vlayer->destroyEditCommand();
QgsDebugMsg( "Adding feature to layer failed" );
delete f;
}
delete mypDialog;
delete f;
vlayer->destroyEditCommand();
}

mCanvas->refresh();
}

}
else if ( mode() == CaptureLine || mode() == CapturePolygon )
{
Expand Down Expand Up @@ -395,7 +438,7 @@ void QgsMapToolAddFeature::canvasReleaseEvent( QMouseEvent * e )
position += sizeof( int );
double x, y;
QList<QgsPoint>::iterator it;
for ( it = begin(); it != end(); ++it )//add the captured points to the polygon
for ( it = begin(); it != end(); ++it ) //add the captured points to the polygon
{
QgsPoint savePoint = *it;
x = savePoint.x();
Expand Down Expand Up @@ -441,53 +484,26 @@ void QgsMapToolAddFeature::canvasReleaseEvent( QMouseEvent * e )
{
QMessageBox::critical( 0, tr( "Error" ), tr( "An error was reported during intersection removal" ) );
}


}

// add the fields to the QgsFeature
const QgsFieldMap fields = vlayer->pendingFields();
for ( QgsFieldMap::const_iterator it = fields.begin(); it != fields.end(); ++it )
{
f->addAttribute( it.key(), provider->defaultValue( it.key() ) );
}
vlayer->beginEditCommand( tr( "Feature added" ) );

QSettings settings;
bool isDisabledAttributeValuesDlg = settings.value( "/qgis/digitizing/disable_enter_attribute_values_dialog", false ).toBool();
if ( isDisabledAttributeValuesDlg )
if ( addFeature( vlayer, f ) )
{
vlayer->beginEditCommand( tr( "Feature added" ) );
if ( vlayer->addFeature( *f ) )
//add points to other features to keep topology up-to-date
int topologicalEditing = QgsProject::instance()->readNumEntry( "Digitizing", "/TopologicalEditing", 0 );
if ( topologicalEditing )
{
//add points to other features to keep topology up-to-date
int topologicalEditing = QgsProject::instance()->readNumEntry( "Digitizing", "/TopologicalEditing", 0 );
if ( topologicalEditing )
{
vlayer->addTopologicalPoints( f->geometry() );
}
vlayer->addTopologicalPoints( f->geometry() );
}

vlayer->endEditCommand();
}
else
{
QgsAttributeDialog * mypDialog = new QgsAttributeDialog( vlayer, f );
if ( mypDialog->exec() )
{
vlayer->beginEditCommand( tr( "Feature added" ) );
if ( vlayer->addFeature( *f ) )
{
//add points to other features to keep topology up-to-date
int topologicalEditing = QgsProject::instance()->readNumEntry( "Digitizing", "/TopologicalEditing", 0 );
if ( topologicalEditing )
{
vlayer->addTopologicalPoints( f->geometry() );
}
}
vlayer->endEditCommand();
}
mypDialog->deleteLater();
delete f;
vlayer->destroyEditCommand();
}
delete f;

stopCapturing();
}
Expand Down
5 changes: 5 additions & 0 deletions src/app/qgsmaptooladdfeature.h
Expand Up @@ -15,6 +15,7 @@
/* $Id$ */

#include "qgsmaptoolcapture.h"
#include "qgsfeature.h"

/**This tool adds new point/line/polygon features to already existing vector layers*/
class QgsMapToolAddFeature: public QgsMapToolCapture
Expand All @@ -24,4 +25,8 @@ class QgsMapToolAddFeature: public QgsMapToolCapture
QgsMapToolAddFeature( QgsMapCanvas* canvas, CaptureMode mode );
virtual ~QgsMapToolAddFeature();
void canvasReleaseEvent( QMouseEvent * e );

private:
bool addFeature( QgsVectorLayer *vlayer, QgsFeature *f );
QMap<QgsVectorLayer *, QgsAttributeMap> mLastUsedValues;
};
2 changes: 2 additions & 0 deletions src/app/qgsoptions.cpp
Expand Up @@ -352,6 +352,7 @@ QgsOptions::QgsOptions( QWidget *parent, Qt::WFlags fl ) :
}
mMarkerSizeSpinBox->setValue( settings.value( "/qgis/digitizing/marker_size", 3 ).toInt() );

chkReuseLastValues->setChecked( settings.value( "/qgis/digitizing/reuseLastValues", false ).toBool() );
chkDisableAttributeValuesDlg->setChecked( settings.value( "/qgis/digitizing/disable_enter_attribute_values_dialog", false ).toBool() );

#ifdef Q_WS_MAC //MH: disable incremental update on Mac for now to avoid problems with resizing
Expand Down Expand Up @@ -659,6 +660,7 @@ void QgsOptions::saveOptions()
}
settings.setValue( "/qgis/digitizing/marker_size", ( mMarkerSizeSpinBox->value() ) );

settings.setValue( "/qgis/digitizing/reuseLastValues", chkReuseLastValues->isChecked() );
settings.setValue( "/qgis/digitizing/disable_enter_attribute_values_dialog", chkDisableAttributeValuesDlg->isChecked() );

//
Expand Down
16 changes: 7 additions & 9 deletions src/core/qgsvectorlayer.cpp
Expand Up @@ -1130,7 +1130,7 @@ void QgsVectorLayer::drawVertexMarker( double x, double y, QPainter& p, QgsVecto
{
p.setPen( QColor( 50, 100, 120, 200 ) );
p.setBrush( QColor( 200, 200, 210, 120 ) );
p.drawEllipse( x - m, y - m, m*2 + 1, m*2 + 1 );
p.drawEllipse( x - m, y - m, m * 2 + 1, m * 2 + 1 );
}
else if ( type == QgsVectorLayer::Cross )
{
Expand Down Expand Up @@ -1358,7 +1358,7 @@ QGis::WkbType QgsVectorLayer::wkbType() const

QgsRectangle QgsVectorLayer::boundingBoxOfSelected()
{
if ( mSelectedFeatureIds.size() == 0 )//no selected features
if ( mSelectedFeatureIds.size() == 0 ) //no selected features
{
return QgsRectangle( 0, 0, 0, 0 );
}
Expand Down Expand Up @@ -2157,7 +2157,7 @@ int QgsVectorLayer::splitFeatures( const QList<QgsPoint>& splitLine, bool topolo
QgsFeatureList featureList;
const QgsFeatureIds selectedIds = selectedFeaturesIds();

if ( selectedIds.size() > 0 )//consider only the selected features if there is a selection
if ( selectedIds.size() > 0 ) //consider only the selected features if there is a selection
{
featureList = selectedFeatures();
}
Expand Down Expand Up @@ -3838,8 +3838,6 @@ int QgsVectorLayer::snapWithContext( const QgsPoint& startPoint, double snapping

if ( mCachedGeometriesRect.contains( searchRect ) )
{
QgsDebugMsg( "Using cached geometries for snapping." );

QgsGeometryMap::iterator it = mCachedGeometries.begin();
for ( ; it != mCachedGeometries.end() ; ++it )
{
Expand Down Expand Up @@ -4046,8 +4044,8 @@ void QgsVectorLayer::drawFeature( QgsRenderContext &renderContext,
}

//QPointF pt(x - (marker->width()/2), y - (marker->height()/2));
QPointF pt( x*renderContext.rasterScaleFactor() - ( marker->width() / 2 ),
y*renderContext.rasterScaleFactor() - ( marker->height() / 2 ) );
QPointF pt( x * renderContext.rasterScaleFactor() - ( marker->width() / 2 ),
y * renderContext.rasterScaleFactor() - ( marker->height() / 2 ) );

p->save();
//p->scale(markerScaleFactor,markerScaleFactor);
Expand Down Expand Up @@ -4082,8 +4080,8 @@ void QgsVectorLayer::drawFeature( QgsRenderContext &renderContext,
transformPoint( x, y, &renderContext.mapToPixel(), renderContext.coordinateTransform() );
//QPointF pt(x - (marker->width()/2), y - (marker->height()/2));
//QPointF pt(x/markerScaleFactor - (marker->width()/2), y/markerScaleFactor - (marker->height()/2));
QPointF pt( x*renderContext.rasterScaleFactor() - ( marker->width() / 2 ),
y*renderContext.rasterScaleFactor() - ( marker->height() / 2 ) );
QPointF pt( x * renderContext.rasterScaleFactor() - ( marker->width() / 2 ),
y * renderContext.rasterScaleFactor() - ( marker->height() / 2 ) );
//QPointF pt( x, y );

// Work around a +/- 32768 limitation on coordinates
Expand Down
10 changes: 10 additions & 0 deletions src/ui/qgsoptionsbase.ui
Expand Up @@ -1283,6 +1283,16 @@
<string>Enter attribute values</string>
</property>
<layout class="QHBoxLayout">
<item>
<widget class="QCheckBox" name="chkReuseLastValues">
<property name="text">
<string>Reuse last entered attribute values</string>
</property>
<property name="tristate">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="chkDisableAttributeValuesDlg">
<property name="text">
Expand Down

0 comments on commit b1bf738

Please sign in to comment.