Skip to content

Commit fc4c0e8

Browse files
author
jef
committedNov 13, 2010
[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/qgis@14599 c8812cc2-4d05-0410-92ff-de0c093fc19c

11 files changed

+628
-516
lines changed
 

‎images/images.qrc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
<file>themes/newgis/mActionMeasure.png</file>
4545
<file>themes/newgis/mActionMeasureArea.png</file>
4646
<file>themes/newgis/mActionMergeFeatures.png</file>
47+
<file>themes/newgis/mActionMergeFeatureAttributes.png</file>
4748
<file>themes/newgis/mActionMoveFeature.png</file>
4849
<file>themes/newgis/mActionMoveItemContent.png</file>
4950
<file>themes/newgis/mActionMoveVertex.png</file>
@@ -165,6 +166,7 @@
165166
<file>themes/default/mActionMeasureAngle.png</file>
166167
<file>themes/default/mActionMeasureArea.png</file>
167168
<file>themes/default/mActionMergeFeatures.png</file>
169+
<file>themes/default/mActionMergeFeatureAttributes.png</file>
168170
<file>themes/default/mActionMoveFeature.png</file>
169171
<file>themes/default/mActionMoveItemContent.png</file>
170172
<file>themes/default/mActionMoveItemsToBottom.png</file>
@@ -332,6 +334,7 @@
332334
<file>themes/gis/mActionMeasureAngle.png</file>
333335
<file>themes/gis/mActionMeasureArea.png</file>
334336
<file>themes/gis/mActionMergeFeatures.png</file>
337+
<file>themes/gis/mActionMergeFeatureAttributes.png</file>
335338
<file>themes/gis/mActionMoveFeature.png</file>
336339
<file>themes/gis/mActionMoveItemContent.png</file>
337340
<file>themes/gis/mActionMoveItemsToBottom.png</file>
Loading
923 Bytes
Loading
Loading

‎src/app/qgisapp.cpp

Lines changed: 514 additions & 439 deletions
Large diffs are not rendered by default.

‎src/app/qgisapp.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -612,6 +612,8 @@ class QgisApp : public QMainWindow
612612
void deletePart();
613613
//! merges the selected features together
614614
void mergeSelectedFeatures();
615+
//! merges the attributes of selected features
616+
void mergeAttributesOfSelectedFeatures();
615617
//! provides operations with nodes
616618
void nodeTool();
617619
//! activates the rotate points tool
@@ -894,6 +896,7 @@ class QgisApp : public QMainWindow
894896
QAction *mActionDeleteRing;
895897
QAction *mActionDeletePart;
896898
QAction *mActionMergeFeatures;
899+
QAction *mActionMergeFeatureAttributes;
897900
QAction *mActionNodeTool;
898901
QAction *mActionRotatePointSymbols;
899902
QAction *mActionEditSeparator3;

‎src/app/qgsmaptooladdfeature.cpp

Lines changed: 84 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,6 @@
3131
#include <QMouseEvent>
3232
#include <QSettings>
3333

34-
#ifdef Q_OS_WIN
35-
#include <qgisapp.h>
36-
#endif
37-
3834
QgsMapToolAddFeature::QgsMapToolAddFeature( QgsMapCanvas* canvas, CaptureMode tool ): QgsMapToolCapture( canvas, tool )
3935
{
4036

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

4642
}
4743

44+
bool QgsMapToolAddFeature::addFeature( QgsVectorLayer *vlayer, QgsFeature *f )
45+
{
46+
bool res = false;
47+
QgsVectorDataProvider* provider = vlayer->dataProvider();
48+
49+
QSettings settings;
50+
bool reuseLastValues = settings.value( "/qgis/digitizing/reuseLastValues", false ).toBool();
51+
QgsDebugMsg( QString( "reuseLastValues: %1" ).arg( reuseLastValues ) );
52+
53+
// add the fields to the QgsFeature
54+
const QgsFieldMap fields = vlayer->pendingFields();
55+
for ( QgsFieldMap::const_iterator it = fields.constBegin(); it != fields.constEnd(); ++it )
56+
{
57+
if ( reuseLastValues && mLastUsedValues.contains( vlayer ) && mLastUsedValues[ vlayer ].contains( it.key() ) )
58+
{
59+
QgsDebugMsg( QString( "reusing %1 for %2" ).arg( mLastUsedValues[ vlayer ][ it.key()].toString() ).arg( it.key() ) );
60+
f->addAttribute( it.key(), mLastUsedValues[ vlayer ][ it.key()] );
61+
}
62+
else
63+
{
64+
f->addAttribute( it.key(), provider->defaultValue( it.key() ) );
65+
}
66+
}
67+
68+
// show the dialog to enter attribute values
69+
bool isDisabledAttributeValuesDlg = settings.value( "/qgis/digitizing/disable_enter_attribute_values_dialog", true ).toBool();
70+
if ( isDisabledAttributeValuesDlg )
71+
{
72+
res = vlayer->addFeature( *f );
73+
}
74+
else
75+
{
76+
QgsAttributeDialog *mypDialog = new QgsAttributeDialog( vlayer, f );
77+
78+
QgsAttributeMap origValues;
79+
if ( reuseLastValues )
80+
origValues = f->attributeMap();
81+
82+
if ( mypDialog->exec() )
83+
{
84+
if ( reuseLastValues )
85+
{
86+
for ( QgsFieldMap::const_iterator it = fields.constBegin(); it != fields.constEnd(); ++it )
87+
{
88+
const QgsAttributeMap &newValues = f->attributeMap();
89+
if ( newValues.contains( it.key() )
90+
&& origValues.contains( it.key() )
91+
&& origValues[ it.key()] != newValues[ it.key()] )
92+
{
93+
QgsDebugMsg( QString( "saving %1 for %2" ).arg( mLastUsedValues[ vlayer ][ it.key()].toString() ).arg( it.key() ) );
94+
mLastUsedValues[ vlayer ][ it.key()] = newValues[ it.key()];
95+
}
96+
}
97+
}
98+
99+
res = vlayer->addFeature( *f );
100+
}
101+
else
102+
{
103+
QgsDebugMsg( "Adding feature to layer failed" );
104+
res = false;
105+
}
106+
107+
mypDialog->deleteLater();
108+
}
109+
110+
return res;
111+
}
112+
48113
void QgsMapToolAddFeature::canvasReleaseEvent( QMouseEvent * e )
49114
{
115+
QgsDebugMsg( "entered." );
116+
50117
QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( mCanvas->currentLayer() );
51118

52119
if ( !vlayer )
@@ -160,45 +227,21 @@ void QgsMapToolAddFeature::canvasReleaseEvent( QMouseEvent * e )
160227
}
161228

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

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

172-
// show the dialog to enter attribute values
173-
QSettings settings;
174-
bool isDisabledAttributeValuesDlg = settings.value( "/qgis/digitizing/disable_enter_attribute_values_dialog", false ).toBool();
175-
if ( isDisabledAttributeValuesDlg )
233+
if ( addFeature( vlayer, f ) )
176234
{
177-
QgsDebugMsg( "Adding feature to layer" );
178-
vlayer->addFeature( *f );
179235
vlayer->endEditCommand();
180236
}
181237
else
182238
{
183-
QgsAttributeDialog *mypDialog = new QgsAttributeDialog( vlayer, f );
184-
if ( mypDialog->exec() )
185-
{
186-
QgsDebugMsg( "Adding feature to layer" );
187-
vlayer->addFeature( *f );
188-
vlayer->endEditCommand();
189-
}
190-
else
191-
{
192-
vlayer->destroyEditCommand();
193-
QgsDebugMsg( "Adding feature to layer failed" );
194-
delete f;
195-
}
196-
delete mypDialog;
239+
delete f;
240+
vlayer->destroyEditCommand();
197241
}
198242

199243
mCanvas->refresh();
200244
}
201-
202245
}
203246
else if ( mode() == CaptureLine || mode() == CapturePolygon )
204247
{
@@ -395,7 +438,7 @@ void QgsMapToolAddFeature::canvasReleaseEvent( QMouseEvent * e )
395438
position += sizeof( int );
396439
double x, y;
397440
QList<QgsPoint>::iterator it;
398-
for ( it = begin(); it != end(); ++it )//add the captured points to the polygon
441+
for ( it = begin(); it != end(); ++it ) //add the captured points to the polygon
399442
{
400443
QgsPoint savePoint = *it;
401444
x = savePoint.x();
@@ -441,53 +484,26 @@ void QgsMapToolAddFeature::canvasReleaseEvent( QMouseEvent * e )
441484
{
442485
QMessageBox::critical( 0, tr( "Error" ), tr( "An error was reported during intersection removal" ) );
443486
}
444-
445-
446487
}
447488

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

455-
QSettings settings;
456-
bool isDisabledAttributeValuesDlg = settings.value( "/qgis/digitizing/disable_enter_attribute_values_dialog", false ).toBool();
457-
if ( isDisabledAttributeValuesDlg )
491+
if ( addFeature( vlayer, f ) )
458492
{
459-
vlayer->beginEditCommand( tr( "Feature added" ) );
460-
if ( vlayer->addFeature( *f ) )
493+
//add points to other features to keep topology up-to-date
494+
int topologicalEditing = QgsProject::instance()->readNumEntry( "Digitizing", "/TopologicalEditing", 0 );
495+
if ( topologicalEditing )
461496
{
462-
//add points to other features to keep topology up-to-date
463-
int topologicalEditing = QgsProject::instance()->readNumEntry( "Digitizing", "/TopologicalEditing", 0 );
464-
if ( topologicalEditing )
465-
{
466-
vlayer->addTopologicalPoints( f->geometry() );
467-
}
497+
vlayer->addTopologicalPoints( f->geometry() );
468498
}
499+
469500
vlayer->endEditCommand();
470501
}
471502
else
472503
{
473-
QgsAttributeDialog * mypDialog = new QgsAttributeDialog( vlayer, f );
474-
if ( mypDialog->exec() )
475-
{
476-
vlayer->beginEditCommand( tr( "Feature added" ) );
477-
if ( vlayer->addFeature( *f ) )
478-
{
479-
//add points to other features to keep topology up-to-date
480-
int topologicalEditing = QgsProject::instance()->readNumEntry( "Digitizing", "/TopologicalEditing", 0 );
481-
if ( topologicalEditing )
482-
{
483-
vlayer->addTopologicalPoints( f->geometry() );
484-
}
485-
}
486-
vlayer->endEditCommand();
487-
}
488-
mypDialog->deleteLater();
504+
delete f;
505+
vlayer->destroyEditCommand();
489506
}
490-
delete f;
491507

492508
stopCapturing();
493509
}

‎src/app/qgsmaptooladdfeature.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
/* $Id$ */
1616

1717
#include "qgsmaptoolcapture.h"
18+
#include "qgsfeature.h"
1819

1920
/**This tool adds new point/line/polygon features to already existing vector layers*/
2021
class QgsMapToolAddFeature: public QgsMapToolCapture
@@ -24,4 +25,8 @@ class QgsMapToolAddFeature: public QgsMapToolCapture
2425
QgsMapToolAddFeature( QgsMapCanvas* canvas, CaptureMode mode );
2526
virtual ~QgsMapToolAddFeature();
2627
void canvasReleaseEvent( QMouseEvent * e );
28+
29+
private:
30+
bool addFeature( QgsVectorLayer *vlayer, QgsFeature *f );
31+
QMap<QgsVectorLayer *, QgsAttributeMap> mLastUsedValues;
2732
};

‎src/app/qgsoptions.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,7 @@ QgsOptions::QgsOptions( QWidget *parent, Qt::WFlags fl ) :
352352
}
353353
mMarkerSizeSpinBox->setValue( settings.value( "/qgis/digitizing/marker_size", 3 ).toInt() );
354354

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

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

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

664666
//

‎src/core/qgsvectorlayer.cpp

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1130,7 +1130,7 @@ void QgsVectorLayer::drawVertexMarker( double x, double y, QPainter& p, QgsVecto
11301130
{
11311131
p.setPen( QColor( 50, 100, 120, 200 ) );
11321132
p.setBrush( QColor( 200, 200, 210, 120 ) );
1133-
p.drawEllipse( x - m, y - m, m*2 + 1, m*2 + 1 );
1133+
p.drawEllipse( x - m, y - m, m * 2 + 1, m * 2 + 1 );
11341134
}
11351135
else if ( type == QgsVectorLayer::Cross )
11361136
{
@@ -1358,7 +1358,7 @@ QGis::WkbType QgsVectorLayer::wkbType() const
13581358

13591359
QgsRectangle QgsVectorLayer::boundingBoxOfSelected()
13601360
{
1361-
if ( mSelectedFeatureIds.size() == 0 )//no selected features
1361+
if ( mSelectedFeatureIds.size() == 0 ) //no selected features
13621362
{
13631363
return QgsRectangle( 0, 0, 0, 0 );
13641364
}
@@ -2157,7 +2157,7 @@ int QgsVectorLayer::splitFeatures( const QList<QgsPoint>& splitLine, bool topolo
21572157
QgsFeatureList featureList;
21582158
const QgsFeatureIds selectedIds = selectedFeaturesIds();
21592159

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

38393839
if ( mCachedGeometriesRect.contains( searchRect ) )
38403840
{
3841-
QgsDebugMsg( "Using cached geometries for snapping." );
3842-
38433841
QgsGeometryMap::iterator it = mCachedGeometries.begin();
38443842
for ( ; it != mCachedGeometries.end() ; ++it )
38453843
{
@@ -4046,8 +4044,8 @@ void QgsVectorLayer::drawFeature( QgsRenderContext &renderContext,
40464044
}
40474045

40484046
//QPointF pt(x - (marker->width()/2), y - (marker->height()/2));
4049-
QPointF pt( x*renderContext.rasterScaleFactor() - ( marker->width() / 2 ),
4050-
y*renderContext.rasterScaleFactor() - ( marker->height() / 2 ) );
4047+
QPointF pt( x * renderContext.rasterScaleFactor() - ( marker->width() / 2 ),
4048+
y * renderContext.rasterScaleFactor() - ( marker->height() / 2 ) );
40514049

40524050
p->save();
40534051
//p->scale(markerScaleFactor,markerScaleFactor);
@@ -4082,8 +4080,8 @@ void QgsVectorLayer::drawFeature( QgsRenderContext &renderContext,
40824080
transformPoint( x, y, &renderContext.mapToPixel(), renderContext.coordinateTransform() );
40834081
//QPointF pt(x - (marker->width()/2), y - (marker->height()/2));
40844082
//QPointF pt(x/markerScaleFactor - (marker->width()/2), y/markerScaleFactor - (marker->height()/2));
4085-
QPointF pt( x*renderContext.rasterScaleFactor() - ( marker->width() / 2 ),
4086-
y*renderContext.rasterScaleFactor() - ( marker->height() / 2 ) );
4083+
QPointF pt( x * renderContext.rasterScaleFactor() - ( marker->width() / 2 ),
4084+
y * renderContext.rasterScaleFactor() - ( marker->height() / 2 ) );
40874085
//QPointF pt( x, y );
40884086

40894087
// Work around a +/- 32768 limitation on coordinates

‎src/ui/qgsoptionsbase.ui

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1283,6 +1283,16 @@
12831283
<string>Enter attribute values</string>
12841284
</property>
12851285
<layout class="QHBoxLayout">
1286+
<item>
1287+
<widget class="QCheckBox" name="chkReuseLastValues">
1288+
<property name="text">
1289+
<string>Reuse last entered attribute values</string>
1290+
</property>
1291+
<property name="tristate">
1292+
<bool>false</bool>
1293+
</property>
1294+
</widget>
1295+
</item>
12861296
<item>
12871297
<widget class="QCheckBox" name="chkDisableAttributeValuesDlg">
12881298
<property name="text">

0 commit comments

Comments
 (0)
Please sign in to comment.