Skip to content

Commit 390b816

Browse files
committedJul 9, 2015
[FEATURE]: Adapt node tool to new geometry types and provide a node editor table
1 parent ce2c402 commit 390b816

21 files changed

+1017
-813
lines changed
 

‎src/app/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ SET(QGIS_APP_SRCS
9292
nodetool/qgsmaptoolnodetool.cpp
9393
nodetool/qgsselectedfeature.cpp
9494
nodetool/qgsvertexentry.cpp
95+
nodetool/qgsnodeeditor.cpp
9596

9697
qgsmeasuredialog.cpp
9798
qgsmeasuretool.cpp
@@ -240,6 +241,7 @@ SET (QGIS_APP_MOC_HDRS
240241

241242
nodetool/qgsmaptoolnodetool.h
242243
nodetool/qgsselectedfeature.h
244+
nodetool/qgsnodeeditor.h
243245

244246
qgsmeasuredialog.h
245247
qgsmeasuretool.h

‎src/app/nodetool/qgsmaptoolnodetool.cpp

Lines changed: 256 additions & 446 deletions
Large diffs are not rendered by default.

‎src/app/nodetool/qgsmaptoolnodetool.h

Lines changed: 43 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -16,43 +16,36 @@
1616
#ifndef QGSMAPTOOLNODETOOL_H
1717
#define QGSMAPTOOLNODETOOL_H
1818

19-
#include "qgsfeature.h"
2019
#include "qgsmaptooledit.h"
21-
#include "qgspoint.h"
20+
#include "qgsmapcanvassnapper.h"
2221

2322
class QRubberBand;
2423

25-
class QgsRubberBand;
24+
class QgsGeometryRubberBand;
2625
class QgsVertexEntry;
2726
class QgsSelectedFeature;
27+
class QgsNodeEditor;
2828

29-
/**
30-
* Set representing set of vertex numbers
31-
*/
32-
typedef QSet<int> Vertexes;
33-
34-
/**A maptool to move/deletes/adds vertices of line or polygon features*/
29+
/** A maptool to move/deletes/adds vertices of line or polygon features*/
3530
class QgsMapToolNodeTool: public QgsMapToolEdit
3631
{
3732
Q_OBJECT
3833
public:
3934
QgsMapToolNodeTool( QgsMapCanvas* canvas );
4035
virtual ~QgsMapToolNodeTool();
4136

42-
void canvasMoveEvent( QMouseEvent * e ) override;
43-
44-
void canvasDoubleClickEvent( QMouseEvent * e ) override;
37+
void canvasMoveEvent( QMouseEvent * e );
4538

46-
void canvasPressEvent( QMouseEvent * e ) override;
39+
void canvasDoubleClickEvent( QMouseEvent * e );
4740

48-
void canvasReleaseEvent( QMouseEvent * e ) override;
41+
void canvasPressEvent( QMouseEvent * e );
4942

50-
void keyPressEvent( QKeyEvent* e ) override;
43+
void canvasReleaseEvent( QMouseEvent * e );
5144

52-
void keyReleaseEvent( QKeyEvent* e ) override;
45+
void keyPressEvent( QKeyEvent* e );
5346

5447
//! called when map tool is being deactivated
55-
void deactivate() override;
48+
void deactivate();
5649

5750
public slots:
5851
void selectedFeatureDestroyed();
@@ -78,14 +71,6 @@ class QgsMapToolNodeTool: public QgsMapToolEdit
7871
*/
7972
void cleanTool( bool deleteSelectedFeature = true );
8073

81-
/**
82-
* Creating rubber band marker for movin of point
83-
* @param center coordinates of point to be moved
84-
* @param vlayer vector layer on which we are working
85-
* @return rubber band marker
86-
*/
87-
QgsRubberBand* createRubberBandMarker( QgsPoint center, QgsVectorLayer* vlayer );
88-
8974
/**
9075
* Function to check if selected feature exists and is same with original one
9176
* stored in internal structures
@@ -94,18 +79,10 @@ class QgsMapToolNodeTool: public QgsMapToolEdit
9479
*/
9580
bool checkCorrectnessOfFeature( QgsVectorLayer* vlayer );
9681

97-
/**
98-
* Creates rubberbands for moving points
99-
*/
100-
void createMovingRubberBands();
101-
10282
/**
10383
* Creates rubber bands for ther features when topology editing is enabled
104-
* @param vlayer vector layer for ehich rubber bands are created
105-
* @param vertexMap map of vertexes
106-
* @param vertex currently processed vertex
10784
*/
108-
void createTopologyRubberBands( QgsVectorLayer* vlayer, const QList<QgsVertexEntry*> &vertexMap, int vertex );
85+
void createTopologyRubberBands();
10986

11087
/**
11188
* Returns the index of first selected vertex, -1 when all unselected
@@ -115,63 +92,63 @@ class QgsMapToolNodeTool: public QgsMapToolEdit
11592
/**
11693
* Select the specified vertex bounded to current index range, returns the valid selected index
11794
*/
118-
int safeSelectVertex( int vertexNr );
95+
void safeSelectVertex( int vertexNr );
11996

120-
/** The position of the vertex to move (in map coordinates) to exclude later from snapping*/
121-
QList<QgsPoint> mExcludePoint;
97+
/** Extracts a single snapping point from a set of snapping results.
98+
This is useful for snapping operations that just require a position to snap to and not all the
99+
snapping results. If the list is empty, the screen coordinates are transformed into map coordinates and returned
100+
@param snapResults results collected from the snapping operation.
101+
@return the snapped point in map coordinates*/
102+
QgsPoint snapPointFromResults( const QList<QgsSnappingResult>& snapResults, const QPoint& screenCoords );
122103

123-
/** rubber bands */
124-
QList<QgsRubberBand*> mRubberBands;
104+
/** Inserts vertices to the snapped segments of the editing layer.
105+
This is useful for topological editing if snap to segment is enabled.
106+
@param snapResults results collected from the snapping operation
107+
@param editedLayer pointer to the editing layer
108+
@return 0 in case of success*/
109+
int insertSegmentVerticesForSnap( const QList<QgsSnappingResult>& snapResults, QgsVectorLayer* editedLayer );
125110

126-
/** list of topology rubber bands */
127-
QList<QgsRubberBand*> mTopologyRubberBand;
111+
/** Snapper object that reads the settings from project and option
112+
and applies it to the map canvas*/
113+
QgsMapCanvasSnapper mSnapper;
128114

129-
/** vertexes of rubberbands which are to be moved */
130-
QMap<QgsFeatureId, Vertexes*> mTopologyMovingVertexes;
115+
/** Rubber bands during node move */
116+
QMap<QgsFeatureId, QgsGeometryRubberBand*> mMoveRubberBands;
131117

132-
/** vertexes of features with int id which were already added tu rubber bands */
133-
QMap<QgsFeatureId, Vertexes*> mTopologyRubberBandVertexes;
118+
/** Vertices of features to move */
119+
QMap<QgsFeatureId, QList< QPair<QgsVertexId, QgsPointV2> > > mMoveVertices;
134120

135-
/** object containing selected feature and it's vertexes */
121+
/** Object containing selected feature and it's vertexes */
136122
QgsSelectedFeature *mSelectedFeature;
137123

138-
/** flag if selection rectangle is active */
139-
bool mSelectionRectangle;
124+
/** Dock widget which allows to edit vertices */
125+
QgsNodeEditor* mNodeEditor;
140126

141-
/** flag if moving of vertexes is occuring */
127+
/** Flag if moving of vertexes is occuring */
142128
bool mMoving;
143129

144-
/** flag if click action is still in queue to be processed */
145-
bool mClicked;
146-
147-
/** flag if crtl is pressed */
148-
bool mCtrl;
149-
150-
/** flag if selection of another feature can occur */
130+
/** Flag if selection of another feature can occur */
151131
bool mSelectAnother;
152132

153-
/** feature id of another feature where user clicked */
133+
/** Feature id of another feature where user clicked */
154134
QgsFeatureId mAnother;
155135

156-
/** stored position of last press down action to count how much vertexes should be moved */
136+
/** Stored position of last press down action to count how much vertexes should be moved */
157137
QPoint mPressCoordinates;
158138

159-
/** closest vertex to click in map coordinates */
139+
/** Closest vertex to click in map coordinates */
160140
QgsPoint mClosestMapVertex;
161141

162-
/** backup of map coordinates to be able to count change between moves */
163-
QgsPoint mPosMapCoordBackup;
164-
165-
/** active rubberband for selecting vertexes */
142+
/** Active rubberband for selecting vertexes */
166143
QRubberBand *mSelectionRubberBand;
167144

168-
/** rectangle defining area for selecting vertexes */
145+
/** Rectangle defining area for selecting vertexes */
169146
QRect* mRect;
170147

171-
/** flag to tell if edition points */
148+
/** Flag to tell if edition points */
172149
bool mIsPoint;
173150

174-
/** vertex to deselect on release */
151+
/** Vertex to deselect on release */
175152
int mDeselectOnRelease;
176153
};
177154

‎src/app/nodetool/qgsnodeeditor.cpp

Lines changed: 236 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,236 @@
1+
/***************************************************************************
2+
qgsnodeeditor.cpp
3+
-----------------
4+
begin : Tue Mar 24 2015
5+
copyright : (C) 2015 Sandro Mani / Sourcepole AG
6+
email : smani@sourcepole.ch
7+
8+
***************************************************************************/
9+
10+
/***************************************************************************
11+
* *
12+
* This program is free software; you can redistribute it and/or modify *
13+
* it under the terms of the GNU General Public License as published by *
14+
* the Free Software Foundation; either version 2 of the License, or *
15+
* (at your option) any later version. *
16+
* *
17+
***************************************************************************/
18+
19+
#include "qgsnodeeditor.h"
20+
#include "qgsmapcanvas.h"
21+
#include "qgsselectedfeature.h"
22+
#include "qgsvertexentry.h"
23+
#include "qgsvectorlayer.h"
24+
#include "qgsgeometryutils.h"
25+
26+
#include <QTableWidget>
27+
#include <QHeaderView>
28+
#include <QVBoxLayout>
29+
#include <QStyledItemDelegate>
30+
#include <QLineEdit>
31+
#include <QVector2D>
32+
33+
static const int MinRadiusRole = Qt::UserRole + 1;
34+
35+
36+
class CoordinateItemDelegate : public QStyledItemDelegate
37+
{
38+
public:
39+
QString displayText( const QVariant & value, const QLocale & locale ) const
40+
{
41+
return locale.toString( value.toDouble(), 'f', 4 );
42+
}
43+
44+
protected:
45+
QWidget* createEditor( QWidget * parent, const QStyleOptionViewItem & /*option*/, const QModelIndex & index ) const
46+
{
47+
QLineEdit* lineEdit = new QLineEdit( parent );
48+
QDoubleValidator* validator = new QDoubleValidator();
49+
if ( !index.data( MinRadiusRole ).isNull() )
50+
validator->setBottom( index.data( MinRadiusRole ).toDouble() );
51+
lineEdit->setValidator( validator );
52+
return lineEdit;
53+
}
54+
void setModelData( QWidget *editor, QAbstractItemModel *model, const QModelIndex &index ) const
55+
{
56+
QLineEdit* lineEdit = qobject_cast<QLineEdit*>( editor );
57+
if ( lineEdit->hasAcceptableInput() )
58+
{
59+
QStyledItemDelegate::setModelData( editor, model, index );
60+
}
61+
}
62+
};
63+
64+
65+
QgsNodeEditor::QgsNodeEditor(
66+
QgsVectorLayer *layer,
67+
QgsSelectedFeature *selectedFeature,
68+
QgsMapCanvas *canvas )
69+
{
70+
setWindowTitle( tr( "Vertex editor" ) );
71+
setFeatures( features() ^ QDockWidget::DockWidgetClosable );
72+
73+
mLayer = layer;
74+
mSelectedFeature = selectedFeature;
75+
mCanvas = canvas;
76+
77+
mTableWidget = new QTableWidget( 0, 6, this );
78+
mTableWidget->setHorizontalHeaderLabels( QStringList() << "id" << "x" << "y" << "z" << "m" << "r" );
79+
mTableWidget->setSelectionMode( QTableWidget::ExtendedSelection );
80+
mTableWidget->setSelectionBehavior( QTableWidget::SelectRows );
81+
mTableWidget->verticalHeader()->hide();
82+
mTableWidget->horizontalHeader()->setResizeMode( 1, QHeaderView::Stretch );
83+
mTableWidget->horizontalHeader()->setResizeMode( 2, QHeaderView::Stretch );
84+
mTableWidget->horizontalHeader()->setResizeMode( 3, QHeaderView::Stretch );
85+
mTableWidget->horizontalHeader()->setResizeMode( 4, QHeaderView::Stretch );
86+
mTableWidget->horizontalHeader()->setResizeMode( 5, QHeaderView::Stretch );
87+
mTableWidget->setItemDelegateForColumn( 1, new CoordinateItemDelegate() );
88+
mTableWidget->setItemDelegateForColumn( 2, new CoordinateItemDelegate() );
89+
mTableWidget->setItemDelegateForColumn( 3, new CoordinateItemDelegate() );
90+
mTableWidget->setItemDelegateForColumn( 4, new CoordinateItemDelegate() );
91+
mTableWidget->setItemDelegateForColumn( 5, new CoordinateItemDelegate() );
92+
93+
setWidget( mTableWidget );
94+
95+
connect( mSelectedFeature, SIGNAL( selectionChanged() ), this, SLOT( updateTableSelection() ) );
96+
connect( mSelectedFeature, SIGNAL( vertexMapChanged() ), this, SLOT( rebuildTable() ) );
97+
connect( mTableWidget, SIGNAL( itemSelectionChanged() ), this, SLOT( updateNodeSelection() ) );
98+
connect( mTableWidget, SIGNAL( cellChanged( int, int ) ), this, SLOT( tableValueChanged( int, int ) ) );
99+
100+
rebuildTable();
101+
}
102+
103+
void QgsNodeEditor::rebuildTable()
104+
{
105+
QFont curvePointFont = mTableWidget->font();
106+
curvePointFont.setItalic( true );
107+
108+
mTableWidget->blockSignals( true );
109+
mTableWidget->setRowCount( 0 );
110+
int row = 0;
111+
bool hasR = false;
112+
foreach ( const QgsVertexEntry* entry, mSelectedFeature->vertexMap() )
113+
{
114+
mTableWidget->insertRow( row );
115+
116+
QTableWidgetItem* idItem = new QTableWidgetItem();
117+
idItem->setData( Qt::DisplayRole, row );
118+
idItem->setFlags( idItem->flags() ^ Qt::ItemIsEditable );
119+
mTableWidget->setItem( row, 0, idItem );
120+
121+
QTableWidgetItem* xItem = new QTableWidgetItem();
122+
xItem->setData( Qt::EditRole, entry->point().x() );
123+
mTableWidget->setItem( row, 1, xItem );
124+
125+
QTableWidgetItem* yItem = new QTableWidgetItem();
126+
yItem->setData( Qt::EditRole, entry->point().y() );
127+
mTableWidget->setItem( row, 2, yItem );
128+
129+
QTableWidgetItem* zItem = new QTableWidgetItem();
130+
zItem->setData( Qt::EditRole, entry->point().z() );
131+
mTableWidget->setItem( row, 3, zItem );
132+
133+
QTableWidgetItem* mItem = new QTableWidgetItem();
134+
mItem->setData( Qt::EditRole, entry->point().m() );
135+
mTableWidget->setItem( row, 4, mItem );
136+
137+
QTableWidgetItem* rItem = new QTableWidgetItem();
138+
mTableWidget->setItem( row, 5, rItem );
139+
140+
bool curvePoint = ( entry->vertexId().type == QgsVertexId::CurveVertex );
141+
if ( curvePoint )
142+
{
143+
idItem->setFont( curvePointFont );
144+
xItem->setFont( curvePointFont );
145+
yItem->setFont( curvePointFont );
146+
zItem->setFont( curvePointFont );
147+
mItem->setFont( curvePointFont );
148+
rItem->setFont( curvePointFont );
149+
150+
const QgsPointV2& p1 = mSelectedFeature->vertexMap()[row - 1]->point();
151+
const QgsPointV2& p2 = mSelectedFeature->vertexMap()[row]->point();
152+
const QgsPointV2& p3 = mSelectedFeature->vertexMap()[row + 1]->point();
153+
154+
double r, cx, cy;
155+
QgsGeometryUtils::circleCenterRadius( p1, p2, p3, r, cx, cy );
156+
rItem->setData( Qt::EditRole, r );
157+
158+
double x13 = p3.x() - p1.x(), y13 = p3.y() - p1.y();
159+
rItem->setData( MinRadiusRole, 0.5 * qSqrt( x13 * x13 + y13 * y13 ) );
160+
161+
hasR = true;
162+
}
163+
else
164+
{
165+
rItem->setFlags( rItem->flags() & ~( Qt::ItemIsSelectable | Qt::ItemIsEnabled ) );
166+
}
167+
168+
++row;
169+
}
170+
mTableWidget->setColumnHidden( 3, !mSelectedFeature->vertexMap()[0]->point().is3D() );
171+
mTableWidget->setColumnHidden( 4, !mSelectedFeature->vertexMap()[0]->point().isMeasure() );
172+
mTableWidget->setColumnHidden( 5, !hasR );
173+
mTableWidget->resizeColumnToContents( 0 );
174+
mTableWidget->blockSignals( false );
175+
}
176+
177+
void QgsNodeEditor::tableValueChanged( int row, int col )
178+
{
179+
int nodeIdx = mTableWidget->item( row, 0 )->data( Qt::DisplayRole ).toInt();
180+
double x, y;
181+
if ( col == 5 ) // radius modified
182+
{
183+
double r = mTableWidget->item( row, 5 )->data( Qt::EditRole ).toDouble();
184+
double x1 = mTableWidget->item( row - 1, 1 )->data( Qt::EditRole ).toDouble();
185+
double y1 = mTableWidget->item( row - 1, 2 )->data( Qt::EditRole ).toDouble();
186+
double x2 = mTableWidget->item( row , 1 )->data( Qt::EditRole ).toDouble();
187+
double y2 = mTableWidget->item( row , 2 )->data( Qt::EditRole ).toDouble();
188+
double x3 = mTableWidget->item( row + 1, 1 )->data( Qt::EditRole ).toDouble();
189+
double y3 = mTableWidget->item( row + 1, 2 )->data( Qt::EditRole ).toDouble();
190+
191+
QgsPointV2 result;
192+
QgsGeometryUtils::segmentMidPoint( QgsPointV2( x1, y1 ), QgsPointV2( x3, y3 ), result, r, QgsPointV2( x2, y2 ) );
193+
x = result.x();
194+
y = result.y();
195+
}
196+
else
197+
{
198+
x = mTableWidget->item( row, 1 )->data( Qt::EditRole ).toDouble();
199+
y = mTableWidget->item( row, 2 )->data( Qt::EditRole ).toDouble();
200+
}
201+
double z = mTableWidget->item( row, 3 )->data( Qt::EditRole ).toDouble();
202+
double m = mTableWidget->item( row, 4 )->data( Qt::EditRole ).toDouble();
203+
QgsPointV2 p( QgsWKBTypes::PointZM, x, y, z, m );
204+
205+
mLayer->beginEditCommand( QObject::tr( "Moved vertices" ) );
206+
mLayer->moveVertex( p, mSelectedFeature->featureId(), nodeIdx );
207+
mLayer->endEditCommand();
208+
mCanvas->refresh();
209+
}
210+
211+
void QgsNodeEditor::updateTableSelection()
212+
{
213+
mTableWidget->blockSignals( true );
214+
mTableWidget->clearSelection();
215+
const QList<QgsVertexEntry*>& vertexMap = mSelectedFeature->vertexMap();
216+
for ( int i = 0, n = vertexMap.size(); i < n; ++i )
217+
{
218+
if ( vertexMap[i]->isSelected() )
219+
{
220+
mTableWidget->selectRow( i );
221+
}
222+
}
223+
mTableWidget->blockSignals( false );
224+
}
225+
226+
void QgsNodeEditor::updateNodeSelection()
227+
{
228+
mSelectedFeature->blockSignals( true );
229+
mSelectedFeature->deselectAllVertexes();
230+
foreach ( const QModelIndex& index, mTableWidget->selectionModel()->selectedRows() )
231+
{
232+
int nodeIdx = mTableWidget->item( index.row(), 0 )->data( Qt::DisplayRole ).toInt();
233+
mSelectedFeature->selectVertex( nodeIdx );
234+
}
235+
mSelectedFeature->blockSignals( false );
236+
}

‎src/app/nodetool/qgsnodeeditor.h

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/***************************************************************************
2+
qgsnodeeditor.h
3+
---------------
4+
begin : Tue Mar 24 2015
5+
copyright : (C) 2015 Sandro Mani / Sourcepole AG
6+
email : smani@sourcepole.ch
7+
8+
***************************************************************************/
9+
10+
/***************************************************************************
11+
* *
12+
* This program is free software; you can redistribute it and/or modify *
13+
* it under the terms of the GNU General Public License as published by *
14+
* the Free Software Foundation; either version 2 of the License, or *
15+
* (at your option) any later version. *
16+
* *
17+
***************************************************************************/
18+
19+
#ifndef QGSNODEEDITOR_H
20+
#define QGSNODEEDITOR_H
21+
22+
#include <QDockWidget>
23+
24+
class QgsMapCanvas;
25+
class QgsRubberBand;
26+
class QgsSelectedFeature;
27+
class QgsVectorLayer;
28+
class QTableWidget;
29+
30+
class QgsNodeEditor : public QDockWidget
31+
{
32+
Q_OBJECT
33+
public:
34+
QgsNodeEditor( QgsVectorLayer* layer,
35+
QgsSelectedFeature* selectedFeature,
36+
QgsMapCanvas* canvas );
37+
38+
public:
39+
QgsVectorLayer* mLayer;
40+
QgsSelectedFeature* mSelectedFeature;
41+
QgsMapCanvas* mCanvas;
42+
QTableWidget* mTableWidget;
43+
44+
private slots:
45+
void rebuildTable();
46+
void tableValueChanged( int row, int col );
47+
void updateTableSelection();
48+
void updateNodeSelection();
49+
};
50+
51+
#endif // QGSNODEEDITOR_H

‎src/app/nodetool/qgsselectedfeature.cpp

Lines changed: 35 additions & 166 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "nodetool/qgsselectedfeature.h"
1717
#include "nodetool/qgsvertexentry.h"
1818

19+
#include "qgspointv2.h"
1920
#include <qgslogger.h>
2021
#include <qgsvertexmarker.h>
2122
#include <qgsgeometryvalidator.h>
@@ -32,7 +33,6 @@ QgsSelectedFeature::QgsSelectedFeature( QgsFeatureId featureId,
3233
: mFeatureId( featureId )
3334
, mGeometry( 0 )
3435
, mChangingGeometry( false )
35-
, mRubberBand( 0 )
3636
, mValidator( 0 )
3737
{
3838
QgsDebugCall;
@@ -78,31 +78,20 @@ void QgsSelectedFeature::updateGeometry( QgsGeometry *geom )
7878
{
7979
QgsFeature f;
8080
mVlayer->getFeatures( QgsFeatureRequest().setFilterFid( mFeatureId ) ).nextFeature( f );
81-
mGeometry = new QgsGeometry( *f.constGeometry() );
81+
mGeometry = new QgsGeometry( *f.geometry() );
8282
}
8383
else
8484
{
8585
mGeometry = new QgsGeometry( *geom );
8686
}
8787
}
8888

89-
void QgsSelectedFeature::cleanRubberBandsData()
90-
{
91-
for ( int i = 0; i < mVertexMap.size(); i++ )
92-
{
93-
mVertexMap[i]->setRubberBandValues( false, 0, 0 );
94-
}
95-
}
96-
9789
void QgsSelectedFeature::setSelectedFeature( QgsFeatureId featureId, QgsVectorLayer* vlayer, QgsMapCanvas* canvas )
9890
{
9991
mFeatureId = featureId;
10092
mVlayer = vlayer;
10193
mCanvas = canvas;
10294

103-
delete mRubberBand;
104-
mRubberBand = 0;
105-
10695
delete mGeometry;
10796
mGeometry = 0;
10897

@@ -262,18 +251,11 @@ void QgsSelectedFeature::deleteSelectedVertexes()
262251
{
263252
if ( mVertexMap[i]->isSelected() )
264253
{
265-
if ( mVertexMap[i]->equals() != -1 )
266-
{
267-
// to avoid try to delete some vertex twice
268-
mVertexMap[ mVertexMap[i]->equals()]->setSelected( false );
269-
nSelected--;
270-
}
271-
272254
if ( topologicalEditing )
273255
{
274256
// snap from current vertex
275257
currentResultList.clear();
276-
mVlayer->snapWithContext( mVertexMap[i]->point(), ZERO_TOLERANCE, currentResultList, QgsSnapper::SnapToVertex );
258+
mVlayer->snapWithContext( mVertexMap[i]->pointV1(), ZERO_TOLERANCE, currentResultList, QgsSnapper::SnapToVertex );
277259
}
278260

279261
// only last update should trigger the geometry update
@@ -319,6 +301,9 @@ void QgsSelectedFeature::deleteSelectedVertexes()
319301

320302
void QgsSelectedFeature::moveSelectedVertexes( const QgsVector &v )
321303
{
304+
//todo...
305+
306+
#if 0
322307
int nUpdates = 0;
323308
foreach ( QgsVertexEntry *entry, mVertexMap )
324309
{
@@ -345,16 +330,18 @@ void QgsSelectedFeature::moveSelectedVertexes( const QgsVector &v )
345330
{
346331
// snap from current vertex
347332
currentResultList.clear();
348-
mVlayer->snapWithContext( entry->point(), ZERO_TOLERANCE, currentResultList, QgsSnapper::SnapToVertex );
333+
mVlayer->snapWithContext( entry->pointV1(), ZERO_TOLERANCE, currentResultList, QgsSnapper::SnapToVertex );
349334
}
350335

351336
// only last update should trigger the geometry update
352337
// as vertex selection gets lost on the update
353338
if ( --nUpdates == 0 )
354339
endGeometryChange();
355340

356-
QgsPoint p = entry->point() + v;
357-
mVlayer->moveVertex( p.x(), p.y(), mFeatureId, i );
341+
QgsPointV2 p = entry->point();
342+
p.setX( p.x() + v.x() );
343+
p.setY( p.y() + v.y() );
344+
mVlayer->moveVertex( p, mFeatureId, i );
358345

359346
if ( topologicalEditing )
360347
{
@@ -364,8 +351,7 @@ void QgsSelectedFeature::moveSelectedVertexes( const QgsVector &v )
364351
{
365352
// move all other
366353
if ( mFeatureId != resultIt.value().snappedAtGeometry )
367-
mVlayer->moveVertex( p.x(), p.y(),
368-
resultIt.value().snappedAtGeometry, resultIt.value().snappedVertexNr );
354+
mVlayer->moveVertex( p, resultIt.value().snappedAtGeometry, resultIt.value().snappedVertexNr );
369355
}
370356
}
371357
}
@@ -374,6 +360,7 @@ void QgsSelectedFeature::moveSelectedVertexes( const QgsVector &v )
374360
endGeometryChange();
375361

376362
mVlayer->endEditCommand();
363+
#endif //0
377364
}
378365

379366
void QgsSelectedFeature::replaceVertexMap()
@@ -386,6 +373,8 @@ void QgsSelectedFeature::replaceVertexMap()
386373

387374
// validate the geometry
388375
validateGeometry();
376+
377+
emit vertexMapChanged();
389378
}
390379

391380
void QgsSelectedFeature::deleteVertexMap()
@@ -409,127 +398,31 @@ QgsGeometry *QgsSelectedFeature::geometry()
409398
return mGeometry;
410399
}
411400

412-
void QgsSelectedFeature::createVertexMapPolygon()
413-
{
414-
int y = 0;
415-
QgsPolygon polygon = mGeometry->asPolygon();
416-
if ( !polygon.empty() )
417-
{
418-
// polygon
419-
for ( int i2 = 0; i2 < polygon.size(); i2++ )
420-
{
421-
const QgsPolyline& poly = polygon[i2];
422-
for ( int i = 0; i < poly.size(); i++ )
423-
{
424-
mVertexMap.insert( y + i, new QgsVertexEntry( mCanvas, mVlayer, poly[i], tr( "ring %1, vertex %2" ).arg( i2 ).arg( i ) ) );
425-
}
426-
mVertexMap[y + poly.size() - 1 ]->setEqual( y );
427-
mVertexMap[y]->setEqual( y + poly.size() - 1 );
428-
y += poly.size();
429-
}
430-
}
431-
else // multipolygon
432-
{
433-
QgsMultiPolygon multiPolygon = mGeometry->asMultiPolygon();
434-
for ( int i2 = 0; i2 < multiPolygon.size(); i2++ )
435-
{
436-
// iterating through polygons
437-
const QgsPolygon& poly2 = multiPolygon[i2];
438-
for ( int i3 = 0; i3 < poly2.size(); i3++ )
439-
{
440-
// iterating through polygon rings
441-
const QgsPolyline& poly = poly2[i3];
442-
for ( int i = 0; i < poly.size(); i++ )
443-
{
444-
mVertexMap.insert( y + i, new QgsVertexEntry( mCanvas, mVlayer, poly[i], tr( "polygon %1, ring %2, vertex %3" ).arg( i2 ).arg( i3 ).arg( i ) ) );
445-
}
446-
mVertexMap[y + poly.size() - 1]->setEqual( y );
447-
mVertexMap[y]->setEqual( y + poly.size() - 1 );
448-
y += poly.size();
449-
}
450-
}
451-
}
452-
}
453-
454-
void QgsSelectedFeature::createVertexMapLine()
455-
{
456-
Q_ASSERT( mGeometry );
457-
458-
if ( mGeometry->isMultipart() )
459-
{
460-
int y = 0;
461-
QgsMultiPolyline mLine = mGeometry->asMultiPolyline();
462-
for ( int i2 = 0; i2 < mLine.size(); i2++ )
463-
{
464-
// iterating through polylines
465-
QgsPolyline poly = mLine[i2];
466-
for ( int i = 0; i < poly.size(); i++ )
467-
{
468-
mVertexMap.insert( y + i, new QgsVertexEntry( mCanvas, mVlayer, poly[i], tr( "polyline %1, vertex %2" ).arg( i2 ).arg( i ) ) );
469-
}
470-
y += poly.size();
471-
}
472-
}
473-
else
474-
{
475-
QgsPolyline poly = mGeometry->asPolyline();
476-
for ( int i = 0; i < poly.size(); i++ )
477-
{
478-
mVertexMap.insert( i, new QgsVertexEntry( mCanvas, mVlayer, poly[i], tr( "vertex %1" ).arg( i ) ) );
479-
}
480-
}
481-
}
482-
483-
void QgsSelectedFeature::createVertexMapPoint()
484-
{
485-
Q_ASSERT( mGeometry );
486-
487-
if ( mGeometry->isMultipart() )
488-
{
489-
// multipoint
490-
QgsMultiPoint poly = mGeometry->asMultiPoint();
491-
for ( int i = 0; i < poly.size(); i++ )
492-
{
493-
mVertexMap.insert( i, new QgsVertexEntry( mCanvas, mVlayer, poly[i], tr( "point %1" ).arg( i ) ) );
494-
}
495-
}
496-
else
497-
{
498-
// single point
499-
mVertexMap.insert( 1, new QgsVertexEntry( mCanvas, mVlayer, mGeometry->asPoint(), tr( "single point" ) ) );
500-
}
501-
}
502-
503401
void QgsSelectedFeature::createVertexMap()
504402
{
505-
QgsDebugCall;
506403

507404
if ( !mGeometry )
508405
{
509406
QgsDebugMsg( "Loading feature" );
510407
updateGeometry( 0 );
511408
}
512409

513-
Q_ASSERT( mGeometry );
514-
515-
// createvertexmap for correct geometry type
516-
switch ( mGeometry->type() )
410+
if ( !mGeometry )
517411
{
518-
case QGis::Polygon:
519-
createVertexMapPolygon();
520-
break;
521-
522-
case QGis::Line:
523-
createVertexMapLine();
524-
break;
412+
return;
413+
}
525414

526-
case QGis::Point:
527-
createVertexMapPoint();
528-
break;
415+
const QgsAbstractGeometryV2* geom = mGeometry->geometry();
416+
if ( !geom )
417+
{
418+
return;
419+
}
529420

530-
case QGis::UnknownGeometry:
531-
case QGis::NoGeometry:
532-
break;
421+
QgsVertexId vertexId;
422+
QgsPointV2 pt;
423+
while ( geom->nextVertex( vertexId, pt ) )
424+
{
425+
mVertexMap.append( new QgsVertexEntry( mCanvas, mVlayer, pt, vertexId, tr( "ring %1, vertex %2" ).arg( vertexId.ring ).arg( vertexId.vertex ) ) );
533426
}
534427
}
535428

@@ -540,15 +433,8 @@ void QgsSelectedFeature::selectVertex( int vertexNr )
540433

541434
QgsVertexEntry *entry = mVertexMap[vertexNr];
542435
entry->setSelected();
543-
entry->update();
544436

545-
if ( entry->equals() != -1 )
546-
{
547-
// select both vertexes if this is first/last vertex
548-
entry = mVertexMap[ entry->equals()];
549-
entry->setSelected();
550-
entry->update();
551-
}
437+
emit selectionChanged();
552438
}
553439

554440
void QgsSelectedFeature::deselectVertex( int vertexNr )
@@ -558,27 +444,20 @@ void QgsSelectedFeature::deselectVertex( int vertexNr )
558444

559445
QgsVertexEntry *entry = mVertexMap[vertexNr];
560446
entry->setSelected( false );
561-
entry->update();
562447

563-
if ( entry->equals() != -1 )
564-
{
565-
// deselect both vertexes if this is first/last vertex
566-
entry = mVertexMap[ entry->equals()];
567-
entry->setSelected( false );
568-
entry->update();
569-
}
448+
emit selectionChanged();
570449
}
571450

572451
void QgsSelectedFeature::deselectAllVertexes()
573452
{
574453
for ( int i = 0; i < mVertexMap.size(); i++ )
575454
{
576455
mVertexMap[i]->setSelected( false );
577-
mVertexMap[i]->update();
578456
}
457+
emit selectionChanged();
579458
}
580459

581-
void QgsSelectedFeature::invertVertexSelection( int vertexNr, bool invert )
460+
void QgsSelectedFeature::invertVertexSelection( int vertexNr )
582461
{
583462
if ( vertexNr < 0 || vertexNr >= mVertexMap.size() )
584463
return;
@@ -588,24 +467,14 @@ void QgsSelectedFeature::invertVertexSelection( int vertexNr, bool invert )
588467
bool selected = !entry->isSelected();
589468

590469
entry->setSelected( selected );
591-
entry->update();
592-
593-
if ( entry->equals() != -1 && invert )
594-
{
595-
entry = mVertexMap[ entry->equals()];
596-
entry->setSelected( selected );
597-
entry->update();
598-
}
470+
emit selectionChanged();
599471
}
600472

601473
void QgsSelectedFeature::updateVertexMarkersPosition()
602474
{
603-
// function for on-line updating vertex markers without refresh of canvas
604-
for ( int i = 0; i < mVertexMap.size(); i++ )
475+
foreach ( QgsVertexEntry* vertexEntry, mVertexMap )
605476
{
606-
QgsVertexEntry *entry = mVertexMap[i];
607-
entry->setCenter( entry->point() );
608-
entry->update();
477+
vertexEntry->placeMarker();
609478
}
610479
}
611480

‎src/app/nodetool/qgsselectedfeature.h

Lines changed: 5 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ class QgsSelectedFeature: public QObject
8989
* @param vertexNr number of vertex which is to be inverted
9090
* @param invert flag if vertex selection should be inverted or not
9191
*/
92-
void invertVertexSelection( int vertexNr, bool invert = true );
92+
void invertVertexSelection( int vertexNr );
9393

9494
/**
9595
* Tells if vertex is selected
@@ -115,11 +115,6 @@ class QgsSelectedFeature: public QObject
115115
*/
116116
void replaceVertexMap();
117117

118-
/**
119-
* Clears data about vertexes if they are in rubber band for moving etc.
120-
*/
121-
void cleanRubberBandsData();
122-
123118
/**
124119
* Get the layer of the selected feature
125120
* @return used vector layer
@@ -134,6 +129,10 @@ class QgsSelectedFeature: public QObject
134129
void beginGeometryChange();
135130
void endGeometryChange();
136131

132+
signals:
133+
void selectionChanged();
134+
void vertexMapChanged();
135+
137136
public slots:
138137
/*
139138
* geometry validation found a problem
@@ -186,21 +185,6 @@ class QgsSelectedFeature: public QObject
186185
*/
187186
void createVertexMap();
188187

189-
/**
190-
* Creates vertex map for polygon type feature
191-
*/
192-
void createVertexMapPolygon();
193-
194-
/**
195-
* Creates vertex map for line type feature
196-
*/
197-
void createVertexMapLine();
198-
199-
/**
200-
* Creates vertex map for ppint type feature
201-
*/
202-
void createVertexMapPoint();
203-
204188
/**
205189
* Updates stored geometry to actual one loaded from layer
206190
* (or already available geometry)
@@ -217,7 +201,6 @@ class QgsSelectedFeature: public QObject
217201
bool mFeatureSelected;
218202
bool mChangingGeometry;
219203
QgsVectorLayer* mVlayer;
220-
QgsRubberBand* mRubberBand;
221204
QList<QgsVertexEntry*> mVertexMap;
222205
QgsMapCanvas* mCanvas;
223206

‎src/app/nodetool/qgsvertexentry.cpp

Lines changed: 24 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -16,50 +16,50 @@
1616
#include "nodetool/qgsvertexentry.h"
1717
#include "qgsmaprenderer.h"
1818

19-
QgsVertexEntry::QgsVertexEntry( QgsMapCanvas *canvas, QgsMapLayer *layer, QgsPoint p, QString tooltip, QgsVertexMarker::IconType type, int penWidth )
19+
QgsVertexEntry::QgsVertexEntry( QgsMapCanvas *canvas, QgsMapLayer *layer, const QgsPointV2 &p, const QgsVertexId &vertexId, QString tooltip, QgsVertexMarker::IconType type, int penWidth )
2020
: mSelected( false )
21-
, mEquals( -1 )
22-
, mInRubberBand( false )
23-
, mRubberBandNr( 0 )
24-
, mRubberBandIndex( 0 )
21+
, mPoint( p )
22+
, mVertexId( vertexId )
2523
, mPenWidth( penWidth )
2624
, mToolTip( tooltip )
2725
, mType( type )
2826
, mMarker( 0 )
2927
, mCanvas( canvas )
3028
, mLayer( layer )
3129
{
32-
setCenter( p );
30+
placeMarker();
3331
}
3432

3533
QgsVertexEntry::~QgsVertexEntry()
3634
{
37-
if ( mMarker )
38-
{
39-
delete mMarker;
40-
mMarker = 0;
41-
}
35+
delete mMarker;
4236
}
4337

44-
void QgsVertexEntry::setCenter( QgsPoint p )
38+
void QgsVertexEntry::placeMarker()
4539
{
46-
mPoint = p;
47-
p = mCanvas->mapSettings().layerToMapCoordinates( mLayer, p );
40+
QgsPoint pm = mCanvas->mapSettings().layerToMapCoordinates( mLayer, pointV1() );
4841

49-
if ( mCanvas->extent().contains( p ) )
42+
if ( mCanvas->extent().contains( pm ) )
5043
{
5144
if ( !mMarker )
5245
{
5346
mMarker = new QgsVertexMarker( mCanvas );
54-
mMarker->setIconType( mType );
55-
mMarker->setColor( mSelected ? Qt::blue : Qt::red );
47+
QColor c = mSelected ? QColor( Qt::blue ) : QColor( Qt::red );
48+
if ( mVertexId.type == QgsVertexId::CurveVertex )
49+
{
50+
mMarker->setIconType( QgsVertexMarker::ICON_CIRCLE );
51+
}
52+
else
53+
{
54+
mMarker->setIconType( mType );
55+
}
56+
mMarker->setColor( c );
5657
mMarker->setPenWidth( mPenWidth );
57-
58-
if ( !mToolTip.isEmpty() )
59-
mMarker->setToolTip( mToolTip );
58+
mMarker->setToolTip( mToolTip );
6059
}
6160

62-
mMarker->setCenter( p );
61+
mMarker->setCenter( pm );
62+
mMarker->update();
6363
}
6464
else if ( mMarker )
6565
{
@@ -73,19 +73,8 @@ void QgsVertexEntry::setSelected( bool selected )
7373
mSelected = selected;
7474
if ( mMarker )
7575
{
76-
mMarker->setColor( mSelected ? Qt::blue : Qt::red );
77-
}
78-
}
79-
80-
void QgsVertexEntry::setRubberBandValues( bool inRubberBand, int rubberBandNr, int indexInRubberBand )
81-
{
82-
mRubberBandIndex = indexInRubberBand;
83-
mInRubberBand = inRubberBand;
84-
mRubberBandNr = rubberBandNr;
85-
}
86-
87-
void QgsVertexEntry::update()
88-
{
89-
if ( mMarker )
76+
QColor c = mSelected ? QColor( Qt::blue ) : QColor( Qt::red );
77+
mMarker->setColor( c );
9078
mMarker->update();
79+
}
9180
}

‎src/app/nodetool/qgsvertexentry.h

Lines changed: 9 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -16,19 +16,16 @@
1616
#ifndef QGSVERTEXENTRY_H
1717
#define QGSVERTEXENTRY_H
1818

19-
#include <qgspoint.h>
19+
#include <qgspointv2.h>
2020
#include <qgsvertexmarker.h>
2121
#include <qgsmapcanvas.h>
2222
#include <qgsmaplayer.h>
2323

2424
class QgsVertexEntry
2525
{
2626
bool mSelected;
27-
QgsPoint mPoint;
28-
int mEquals;
29-
bool mInRubberBand;
30-
int mRubberBandNr;
31-
int mRubberBandIndex;
27+
QgsPointV2 mPoint;
28+
QgsVertexId mVertexId;
3229
int mPenWidth;
3330
QString mToolTip;
3431
QgsVertexMarker::IconType mType;
@@ -39,28 +36,21 @@ class QgsVertexEntry
3936
public:
4037
QgsVertexEntry( QgsMapCanvas *canvas,
4138
QgsMapLayer *layer,
42-
QgsPoint p,
39+
const QgsPointV2& p,
40+
const QgsVertexId& vertexId,
4341
QString tooltip = QString::null,
4442
QgsVertexMarker::IconType type = QgsVertexMarker::ICON_BOX,
4543
int penWidth = 2 );
4644
~QgsVertexEntry();
4745

48-
QgsPoint point() const { return mPoint; }
49-
int equals() const { return mEquals; }
46+
const QgsPointV2& point() const { return mPoint; }
47+
QgsPoint pointV1() const { return QgsPoint( mPoint.x(), mPoint.y() ); }
48+
const QgsVertexId& vertexId() const { return mVertexId; }
5049
bool isSelected() const { return mSelected; }
51-
bool isInRubberBand() const { return mInRubberBand; }
5250

53-
void setCenter( QgsPoint p );
51+
void placeMarker();
5452

55-
void setEqual( int index ) { mEquals = index; }
5653
void setSelected( bool selected = true );
57-
void setInRubberBand( bool inRubberBand = true ) { mInRubberBand = inRubberBand; }
58-
59-
int rubberBandNr() const { return mRubberBandNr; }
60-
int rubberBandIndex() { return mRubberBandIndex; }
61-
62-
void setRubberBandValues( bool inRubberBand, int rubberBandNr, int indexInRubberBand );
63-
void update();
6454
};
6555

6656
#endif

‎src/core/qgsvectorlayer.cpp

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -990,6 +990,14 @@ bool QgsVectorLayer::moveVertex( double x, double y, QgsFeatureId atFeatureId, i
990990
return utils.moveVertex( x, y, atFeatureId, atVertex );
991991
}
992992

993+
bool QgsVectorLayer::moveVertex( const QgsPointV2& p, QgsFeatureId atFeatureId, int atVertex )
994+
{
995+
if ( !mEditBuffer || !mDataProvider )
996+
return false;
997+
998+
QgsVectorLayerEditUtils utils( this );
999+
return utils.moveVertex( p, atFeatureId, atVertex );
1000+
}
9931001

9941002
bool QgsVectorLayer::deleteVertex( QgsFeatureId atFeatureId, int atVertex )
9951003
{
@@ -2189,7 +2197,7 @@ bool QgsVectorLayer::deleteAttributes( QList<int> attrs )
21892197

21902198
qSort( attrs.begin(), attrs.end(), qGreater<int>() );
21912199

2192-
Q_FOREACH ( int attr, attrs )
2200+
Q_FOREACH( int attr, attrs )
21932201
{
21942202
if ( deleteAttribute( attr ) )
21952203
{
@@ -2963,7 +2971,7 @@ void QgsVectorLayer::uniqueValues( int index, QList<QVariant> &uniqueValues, int
29632971
if ( mEditBuffer )
29642972
{
29652973
QSet<QString> vals;
2966-
Q_FOREACH ( const QVariant& v, uniqueValues )
2974+
Q_FOREACH( const QVariant& v, uniqueValues )
29672975
{
29682976
vals << v.toString();
29692977
}
@@ -3771,7 +3779,7 @@ void QgsVectorLayer::invalidateSymbolCountedFlag()
37713779

37723780
void QgsVectorLayer::onRelationsLoaded()
37733781
{
3774-
Q_FOREACH ( QgsAttributeEditorElement* elem, mAttributeEditorElements )
3782+
Q_FOREACH( QgsAttributeEditorElement* elem, mAttributeEditorElements )
37753783
{
37763784
if ( elem->type() == QgsAttributeEditorElement::AeTypeContainer )
37773785
{
@@ -3780,7 +3788,7 @@ void QgsVectorLayer::onRelationsLoaded()
37803788
continue;
37813789

37823790
QList<QgsAttributeEditorElement*> relations = cont->findElements( QgsAttributeEditorElement::AeTypeRelation );
3783-
Q_FOREACH ( QgsAttributeEditorElement* relElem, relations )
3791+
Q_FOREACH( QgsAttributeEditorElement* relElem, relations )
37843792
{
37853793
QgsAttributeEditorRelation* rel = dynamic_cast< QgsAttributeEditorRelation* >( relElem );
37863794
if ( !rel )
@@ -3849,7 +3857,7 @@ QDomElement QgsAttributeEditorContainer::toDomElement( QDomDocument& doc ) const
38493857
QDomElement elem = doc.createElement( "attributeEditorContainer" );
38503858
elem.setAttribute( "name", mName );
38513859

3852-
Q_FOREACH ( QgsAttributeEditorElement* child, mChildren )
3860+
Q_FOREACH( QgsAttributeEditorElement* child, mChildren )
38533861
{
38543862
elem.appendChild( child->toDomElement( doc ) );
38553863
}
@@ -3870,7 +3878,7 @@ QList<QgsAttributeEditorElement*> QgsAttributeEditorContainer::findElements( Qgs
38703878
{
38713879
QList<QgsAttributeEditorElement*> results;
38723880

3873-
Q_FOREACH ( QgsAttributeEditorElement* elem, mChildren )
3881+
Q_FOREACH( QgsAttributeEditorElement* elem, mChildren )
38743882
{
38753883
if ( elem->type() == type )
38763884
{

‎src/core/qgsvectorlayer.h

Lines changed: 56 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include "qgsfeatureiterator.h"
3131
#include "qgseditorwidgetconfig.h"
3232
#include "qgsfield.h"
33+
#include "qgspointv2.h"
3334
#include "qgssnapper.h"
3435
#include "qgsrelation.h"
3536
#include "qgsvectorsimplifymethod.h"
@@ -966,18 +967,18 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
966967
/** Returns true if this is a geometry layer and false in case of NoGeometry (table only) or UnknownGeometry */
967968
bool hasGeometryType() const;
968969

969-
/**Returns the WKBType or WKBUnknown in case of error*/
970+
/** Returns the WKBType or WKBUnknown in case of error*/
970971
QGis::WkbType wkbType() const;
971972

972973
/** Return the provider type for this layer */
973974
QString providerType() const;
974975

975-
/** reads vector layer specific state from project file Dom node.
976+
/** Reads vector layer specific state from project file Dom node.
976977
* @note Called by QgsMapLayer::readXML().
977978
*/
978979
virtual bool readXml( const QDomNode& layer_node ) override;
979980

980-
/** write vector layer specific state to project file Dom node.
981+
/** Write vector layer specific state to project file Dom node.
981982
* @note Called by QgsMapLayer::writeXML().
982983
*/
983984
virtual bool writeXml( QDomNode & layer_node, QDomDocument & doc ) override;
@@ -1036,7 +1037,7 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
10361037
*/
10371038
virtual bool applyNamedStyle( QString namedStyle, QString &errorMsg );
10381039

1039-
/** convert a saved attribute editor element into a AttributeEditor structure as it's used internally.
1040+
/** Convert a saved attribute editor element into a AttributeEditor structure as it's used internally.
10401041
* @param elem the DOM element
10411042
* @param parent the QObject which will own this object
10421043
*/
@@ -1143,6 +1144,12 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
11431144
*/
11441145
bool moveVertex( double x, double y, QgsFeatureId atFeatureId, int atVertex );
11451146

1147+
/** Moves the vertex at the given position number,
1148+
* ring and item (first number is index 0), and feature
1149+
* to the given coordinates
1150+
*/
1151+
bool moveVertex( const QgsPointV2& p, QgsFeatureId atFeatureId, int atVertex );
1152+
11461153
/** Deletes a vertex from a feature
11471154
*/
11481155
bool deleteVertex( QgsFeatureId atFeatureId, int atVertex );
@@ -1152,7 +1159,7 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
11521159
*/
11531160
bool deleteSelectedFeatures( int *deletedCount = 0 );
11541161

1155-
/**Adds a ring to polygon/multipolygon features
1162+
/** Adds a ring to polygon/multipolygon features
11561163
@return
11571164
0 in case of success,
11581165
1 problem with feature type,
@@ -1163,7 +1170,7 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
11631170
6 layer not editable */
11641171
int addRing( const QList<QgsPoint>& ring );
11651172

1166-
/**Adds a new part polygon to a multipart feature
1173+
/** Adds a new part polygon to a multipart feature
11671174
@return
11681175
0 in case of success,
11691176
1 if selected feature is not multipart,
@@ -1175,14 +1182,14 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
11751182
7 layer not editable */
11761183
int addPart( const QList<QgsPoint>& ring );
11771184

1178-
/**Translates feature by dx, dy
1185+
/** Translates feature by dx, dy
11791186
@param featureId id of the feature to translate
11801187
@param dx translation of x-coordinate
11811188
@param dy translation of y-coordinate
11821189
@return 0 in case of success*/
11831190
int translateFeature( QgsFeatureId featureId, double dx, double dy );
11841191

1185-
/**Splits parts cut by the given line
1192+
/** Splits parts cut by the given line
11861193
* @param splitLine line that splits the layer features
11871194
* @param topologicalEditing true if topological editing is enabled
11881195
* @return
@@ -1191,7 +1198,7 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
11911198
*/
11921199
int splitParts( const QList<QgsPoint>& splitLine, bool topologicalEditing = false );
11931200

1194-
/**Splits features cut by the given line
1201+
/** Splits features cut by the given line
11951202
* @param splitLine line that splits the layer features
11961203
* @param topologicalEditing true if topological editing is enabled
11971204
* @return
@@ -1200,7 +1207,7 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
12001207
*/
12011208
int splitFeatures( const QList<QgsPoint>& splitLine, bool topologicalEditing = false );
12021209

1203-
/**Changes the specified geometry such that it has no intersections with other
1210+
/** Changes the specified geometry such that it has no intersections with other
12041211
* polygon (or multipolygon) geometries in this vector layer
12051212
* @param geom geometry to modify
12061213
* @param ignoreFeatures list of feature ids where intersections should be ignored
@@ -1226,7 +1233,7 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
12261233
*/
12271234
int addTopologicalPoints( const QgsPoint& p );
12281235

1229-
/**Inserts vertices to the snapped segments.
1236+
/** Inserts vertices to the snapped segments.
12301237
* This is useful for topological editing if snap to segment is enabled.
12311238
* @param snapResults results collected from the snapping operation
12321239
* @return 0 in case of success
@@ -1252,15 +1259,15 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
12521259
/** Returns true if the provider has been modified since the last commit */
12531260
virtual bool isModified() const;
12541261

1255-
/**Snaps a point to the closest vertex if there is one within the snapping tolerance
1262+
/** Snaps a point to the closest vertex if there is one within the snapping tolerance
12561263
* @param point The point which is set to the position of a vertex if there is one within the snapping tolerance.
12571264
* If there is no point within this tolerance, point is left unchanged.
12581265
* @param tolerance The snapping tolerance
12591266
* @return true if the point has been snapped, false if no vertex within search tolerance
12601267
*/
12611268
bool snapPoint( QgsPoint& point, double tolerance );
12621269

1263-
/**Snaps to segment or vertex within given tolerance
1270+
/** Snaps to segment or vertex within given tolerance
12641271
* @param startPoint point to snap (in layer coordinates)
12651272
* @param snappingTolerance distance tolerance for snapping
12661273
* @param snappingResults snapping results. Key is the distance between startPoint and snapping target
@@ -1272,7 +1279,7 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
12721279
QMultiMap < double, QgsSnappingResult > &snappingResults,
12731280
QgsSnapper::SnappingType snap_to );
12741281

1275-
/**Synchronises with changes in the datasource */
1282+
/** Synchronises with changes in the datasource */
12761283
virtual void reload() override;
12771284

12781285
/** Return new instance of QgsMapLayerRenderer that will be used for rendering of given context
@@ -1293,16 +1300,16 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
12931300
/** Return the extent of the layer as a QRect */
12941301
QgsRectangle extent() override;
12951302

1296-
/** returns field list in the to-be-committed state */
1303+
/** Returns field list in the to-be-committed state */
12971304
const QgsFields &pendingFields() const;
12981305

1299-
/** returns list of attributes */
1306+
/** Returns list of attributes */
13001307
QgsAttributeList pendingAllAttributesList();
13011308

1302-
/** returns list of attribute making up the primary key */
1309+
/** Returns list of attribute making up the primary key */
13031310
QgsAttributeList pendingPkAttributesList();
13041311

1305-
/** returns feature count after commit */
1312+
/** Returns feature count after commit */
13061313
int pendingFeatureCount();
13071314

13081315
/** Make layer read-only (editing disabled) or not
@@ -1313,7 +1320,7 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
13131320
/** Make layer editable */
13141321
bool startEditing();
13151322

1316-
/** change feature's geometry */
1323+
/** Change feature's geometry */
13171324
bool changeGeometry( QgsFeatureId fid, QgsGeometry* geom );
13181325

13191326
/**
@@ -1336,7 +1343,7 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
13361343
*/
13371344
bool changeAttributeValue( QgsFeatureId fid, int field, const QVariant &newValue, const QVariant &oldValue = QVariant() );
13381345

1339-
/** add an attribute field (but does not commit it)
1346+
/** Add an attribute field (but does not commit it)
13401347
returns true if the field was added */
13411348
bool addAttribute( const QgsField &field );
13421349

@@ -1414,7 +1421,7 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
14141421
const QSet<QString>& excludeAttributesWFS() const { return mExcludeAttributesWFS; }
14151422
void setExcludeAttributesWFS( const QSet<QString>& att ) { mExcludeAttributesWFS = att; }
14161423

1417-
/** delete an attribute field (but does not commit it) */
1424+
/** Delete an attribute field (but does not commit it) */
14181425
bool deleteAttribute( int attr );
14191426

14201427
/**
@@ -1429,7 +1436,7 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
14291436
/** Insert a copy of the given features into the layer (but does not commit it) */
14301437
bool addFeatures( QgsFeatureList features, bool makeSelected = true );
14311438

1432-
/** delete a feature from the layer (but does not commit it) */
1439+
/** Delete a feature from the layer (but does not commit it) */
14331440
bool deleteFeature( QgsFeatureId fid );
14341441

14351442
/**
@@ -1469,10 +1476,10 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
14691476
*/
14701477
Q_DECL_DEPRECATED void setEditType( int idx, EditType edit );
14711478

1472-
/** get the active layout for the attribute editor for this layer */
1479+
/** Get the active layout for the attribute editor for this layer */
14731480
EditorLayout editorLayout();
14741481

1475-
/** set the active layout for the attribute editor for this layer */
1482+
/** Set the active layout for the attribute editor for this layer */
14761483
void setEditorLayout( EditorLayout editorLayout );
14771484

14781485
/**
@@ -1529,10 +1536,10 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
15291536
*/
15301537
Q_DECL_DEPRECATED void setCheckedState( int idx, QString checked, QString notChecked );
15311538

1532-
/** get edit form */
1539+
/** Get edit form */
15331540
QString editForm();
15341541

1535-
/** set edit form */
1542+
/** Set edit form */
15361543
void setEditForm( QString ui );
15371544

15381545
/** Type of feature form pop-up suppression after feature creation (overrides app setting)
@@ -1543,16 +1550,16 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
15431550
* @note added in 2.1 */
15441551
void setFeatureFormSuppress( QgsVectorLayer::FeatureFormSuppress s ) { mFeatureFormSuppress = s; }
15451552

1546-
/** get annotation form */
1553+
/** Get annotation form */
15471554
QString annotationForm() const { return mAnnotationForm; }
15481555

1549-
/** set annotation form for layer */
1556+
/** Set annotation form for layer */
15501557
void setAnnotationForm( const QString& ui );
15511558

1552-
/** get python function for edit form initialization */
1559+
/** Get python function for edit form initialization */
15531560
QString editFormInit();
15541561

1555-
/** set python function for edit form initialization */
1562+
/** Set python function for edit form initialization */
15561563
void setEditFormInit( QString function );
15571564

15581565
/**
@@ -1593,16 +1600,16 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
15931600
*/
15941601
Q_DECL_DEPRECATED QSize widgetSize( int idx );
15951602

1596-
/**is edit widget editable **/
1603+
/** Is edit widget editable **/
15971604
bool fieldEditable( int idx );
15981605

1599-
/**label widget on top **/
1606+
/** Label widget on top **/
16001607
bool labelOnTop( int idx );
16011608

1602-
/**set edit widget editable **/
1609+
/** Set edit widget editable **/
16031610
void setFieldEditable( int idx, bool editable );
16041611

1605-
/**label widget on top **/
1612+
/** Label widget on top **/
16061613
void setLabelOnTop( int idx, bool onTop );
16071614

16081615
//! Buffer with uncommitted editing operations. Only valid after editing has been turned on.
@@ -1640,16 +1647,16 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
16401647
/** Caches joined attributes if required (and not already done) */
16411648
void createJoinCaches();
16421649

1643-
/**Returns unique values for column
1650+
/** Returns unique values for column
16441651
@param index column index for attribute
16451652
@param uniqueValues out: result list
16461653
@param limit maximum number of values to return (-1 if unlimited) */
16471654
void uniqueValues( int index, QList<QVariant> &uniqueValues, int limit = -1 );
16481655

1649-
/**Returns minimum value for an attribute column or invalid variant in case of error */
1656+
/** Returns minimum value for an attribute column or invalid variant in case of error */
16501657
QVariant minimumValue( int index );
16511658

1652-
/**Returns maximum value for an attribute column or invalid variant in case of error */
1659+
/** Returns maximum value for an attribute column or invalid variant in case of error */
16531660
QVariant maximumValue( int index );
16541661

16551662
/** Fetches all values from a specified field name or expression.
@@ -1917,14 +1924,14 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
19171924

19181925
private: // Private methods
19191926

1920-
/** vector layers are not copyable */
1927+
/** Vector layers are not copyable */
19211928
QgsVectorLayer( const QgsVectorLayer & rhs );
19221929

1923-
/** vector layers are not copyable */
1930+
/** Vector layers are not copyable */
19241931
QgsVectorLayer & operator=( QgsVectorLayer const & rhs );
19251932

19261933

1927-
/** bind layer to a specific data provider
1934+
/** Bind layer to a specific data provider
19281935
@param provider should be "postgres", "ogr", or ??
19291936
@todo XXX should this return bool? Throw exceptions?
19301937
*/
@@ -1933,7 +1940,7 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
19331940
/** Goes through all features and finds a free id (e.g. to give it temporarily to a not-commited feature) */
19341941
QgsFeatureId findFreeId();
19351942

1936-
/**Snaps to a geometry and adds the result to the multimap if it is within the snapping result
1943+
/** Snaps to a geometry and adds the result to the multimap if it is within the snapping result
19371944
@param startPoint start point of the snap
19381945
@param featureId id of feature
19391946
@param geom geometry to snap
@@ -1959,10 +1966,10 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
19591966
/** Pointer to data provider derived from the abastract base class QgsDataProvider */
19601967
QgsVectorDataProvider *mDataProvider;
19611968

1962-
/** index of the primary label field */
1969+
/** Index of the primary label field */
19631970
QString mDisplayField;
19641971

1965-
/** the preview expression used to generate a human readable preview string for features */
1972+
/** The preview expression used to generate a human readable preview string for features */
19661973
QString mDisplayExpression;
19671974

19681975
/** Data provider key */
@@ -1980,21 +1987,21 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
19801987
*/
19811988
QgsFeatureIds mSelectedFeatureIds;
19821989

1983-
/** field map to commit */
1990+
/** Field map to commit */
19841991
QgsFields mUpdatedFields;
19851992

1986-
/**Map that stores the aliases for attributes. Key is the attribute name and value the alias for that attribute*/
1993+
/** Map that stores the aliases for attributes. Key is the attribute name and value the alias for that attribute*/
19871994
QMap< QString, QString > mAttributeAliasMap;
19881995

1989-
/**Stores a list of attribute editor elements (Each holding a tree structure for a tab in the attribute editor)*/
1996+
/** Stores a list of attribute editor elements (Each holding a tree structure for a tab in the attribute editor)*/
19901997
QList< QgsAttributeEditorElement* > mAttributeEditorElements;
19911998

1992-
/**Attributes which are not published in WMS*/
1999+
/** Attributes which are not published in WMS*/
19932000
QSet<QString> mExcludeAttributesWMS;
1994-
/**Attributes which are not published in WFS*/
2001+
/** Attributes which are not published in WFS*/
19952002
QSet<QString> mExcludeAttributesWFS;
19962003

1997-
/**Map that stores the tab for attributes in the edit form. Key is the tab order and value the tab name*/
2004+
/** Map that stores the tab for attributes in the edit form. Key is the tab order and value the tab name*/
19982005
QList< TabData > mTabs;
19992006

20002007
/** Geometry type as defined in enum WkbType (qgis.h) */

‎src/core/qgsvectorlayereditutils.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,12 @@ bool QgsVectorLayerEditUtils::insertVertex( double x, double y, QgsFeatureId atF
5151

5252

5353
bool QgsVectorLayerEditUtils::moveVertex( double x, double y, QgsFeatureId atFeatureId, int atVertex )
54+
{
55+
QgsPointV2 p( x, y );
56+
return moveVertex( p, atFeatureId, atVertex );
57+
}
58+
59+
bool QgsVectorLayerEditUtils::moveVertex( const QgsPointV2& p, QgsFeatureId atFeatureId, int atVertex )
5460
{
5561
if ( !L->hasGeometryType() )
5662
return false;
@@ -60,13 +66,13 @@ bool QgsVectorLayerEditUtils::moveVertex( double x, double y, QgsFeatureId atFea
6066
{
6167
// it's not in cache: let's fetch it from layer
6268
QgsFeature f;
63-
if ( !L->getFeatures( QgsFeatureRequest().setFilterFid( atFeatureId ).setSubsetOfAttributes( QgsAttributeList() ) ).nextFeature( f ) || !f.constGeometry() )
69+
if ( !L->getFeatures( QgsFeatureRequest().setFilterFid( atFeatureId ).setSubsetOfAttributes( QgsAttributeList() ) ).nextFeature( f ) || !f.geometry() )
6470
return false; // geometry not found
6571

66-
geometry = *f.constGeometry();
72+
geometry = *f.geometry();
6773
}
6874

69-
geometry.moveVertex( x, y, atVertex );
75+
geometry.moveVertex( p, atVertex );
7076

7177
L->editBuffer()->changeGeometry( atFeatureId, &geometry );
7278
return true;

‎src/core/qgsvectorlayereditutils.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,12 @@ class CORE_EXPORT QgsVectorLayerEditUtils
4242
*/
4343
bool moveVertex( double x, double y, QgsFeatureId atFeatureId, int atVertex );
4444

45+
/** Moves the vertex at the given position number,
46+
* ring and item (first number is index 0), and feature
47+
* to the given coordinates
48+
*/
49+
bool moveVertex( const QgsPointV2& p, QgsFeatureId atFeatureId, int atVertex );
50+
4551
/** Deletes a vertex from a feature
4652
*/
4753
bool deleteVertex( QgsFeatureId atFeatureId, int atVertex );

‎src/gui/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,7 @@ SET(QGIS_GUI_SRCS
175175
qgsfilterlineedit.cpp
176176
qgsformannotationitem.cpp
177177
qgsgenericprojectionselector.cpp
178+
qgsgeometryrubberband.cpp
178179
qgshighlight.cpp
179180
qgshistogramwidget.cpp
180181
qgsidentifymenu.cpp

‎src/gui/qgsgeometryrubberband.cpp

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
/***************************************************************************
2+
qgsgeometryrubberband.cpp
3+
-------------------------
4+
begin : December 2014
5+
copyright : (C) 2014 by Marco Hugentobler
6+
email : marco at sourcepole dot ch
7+
***************************************************************************/
8+
9+
/***************************************************************************
10+
* *
11+
* This program is free software; you can redistribute it and/or modify *
12+
* it under the terms of the GNU General Public License as published by *
13+
* the Free Software Foundation; either version 2 of the License, or *
14+
* (at your option) any later version. *
15+
* *
16+
***************************************************************************/
17+
18+
#include "qgsgeometryrubberband.h"
19+
#include "qgsabstractgeometryv2.h"
20+
#include "qgsmapcanvas.h"
21+
#include "qgspointv2.h"
22+
#include <QPainter>
23+
24+
QgsGeometryRubberBand::QgsGeometryRubberBand( QgsMapCanvas* mapCanvas, QGis::GeometryType geomType ): QgsMapCanvasItem( mapCanvas ),
25+
mGeometry( 0 ), mIconSize( 5 ), mIconType( ICON_CIRCLE ), mGeometryType( geomType )
26+
{
27+
mPen = QPen( QColor( 255, 0, 0 ) );
28+
mBrush = QBrush( QColor( 255, 0, 0 ) );
29+
}
30+
31+
QgsGeometryRubberBand::~QgsGeometryRubberBand()
32+
{
33+
delete mGeometry;
34+
}
35+
36+
void QgsGeometryRubberBand::paint( QPainter* painter )
37+
{
38+
if ( !mGeometry || !painter )
39+
{
40+
return;
41+
}
42+
43+
painter->save();
44+
painter->translate( -pos() );
45+
46+
if ( mGeometryType == QGis::Polygon )
47+
{
48+
painter->setBrush( mBrush );
49+
}
50+
else
51+
{
52+
painter->setBrush( Qt::NoBrush );
53+
}
54+
painter->setPen( mPen );
55+
56+
57+
QgsAbstractGeometryV2* paintGeom = mGeometry->clone();
58+
59+
paintGeom->transform( mMapCanvas->getCoordinateTransform()->transform() );
60+
paintGeom->draw( *painter );
61+
62+
//draw vertices
63+
QgsVertexId vertexId;
64+
QgsPointV2 vertex;
65+
while ( paintGeom->nextVertex( vertexId, vertex ) )
66+
{
67+
drawVertex( painter, vertex.x(), vertex.y() );
68+
}
69+
70+
delete paintGeom;
71+
painter->restore();
72+
}
73+
74+
void QgsGeometryRubberBand::drawVertex( QPainter* p, double x, double y )
75+
{
76+
qreal s = ( mIconSize - 1 ) / 2;
77+
78+
switch ( mIconType )
79+
{
80+
case ICON_NONE:
81+
break;
82+
83+
case ICON_CROSS:
84+
p->drawLine( QLineF( x - s, y, x + s, y ) );
85+
p->drawLine( QLineF( x, y - s, x, y + s ) );
86+
break;
87+
88+
case ICON_X:
89+
p->drawLine( QLineF( x - s, y - s, x + s, y + s ) );
90+
p->drawLine( QLineF( x - s, y + s, x + s, y - s ) );
91+
break;
92+
93+
case ICON_BOX:
94+
p->drawLine( QLineF( x - s, y - s, x + s, y - s ) );
95+
p->drawLine( QLineF( x + s, y - s, x + s, y + s ) );
96+
p->drawLine( QLineF( x + s, y + s, x - s, y + s ) );
97+
p->drawLine( QLineF( x - s, y + s, x - s, y - s ) );
98+
break;
99+
100+
case ICON_FULL_BOX:
101+
p->drawRect( x - s, y - s, mIconSize, mIconSize );
102+
break;
103+
104+
case ICON_CIRCLE:
105+
p->drawEllipse( x - s, y - s, mIconSize, mIconSize );
106+
break;
107+
}
108+
}
109+
110+
void QgsGeometryRubberBand::setGeometry( QgsAbstractGeometryV2* geom )
111+
{
112+
delete mGeometry;
113+
mGeometry = geom;
114+
115+
if ( mGeometry )
116+
{
117+
setRect( rubberBandRectangle() );
118+
}
119+
}
120+
121+
void QgsGeometryRubberBand::moveVertex( const QgsVertexId& id, const QgsPointV2& newPos )
122+
{
123+
if ( mGeometry )
124+
{
125+
mGeometry->moveVertex( id, newPos );
126+
setRect( rubberBandRectangle() );
127+
}
128+
}
129+
130+
void QgsGeometryRubberBand::setFillColor( const QColor& c )
131+
{
132+
mBrush.setColor( c );
133+
}
134+
135+
void QgsGeometryRubberBand::setOutlineColor( const QColor& c )
136+
{
137+
mPen.setColor( c );
138+
}
139+
140+
void QgsGeometryRubberBand::setOutlineWidth( int width )
141+
{
142+
mPen.setWidth( width );
143+
}
144+
145+
void QgsGeometryRubberBand::setLineStyle( Qt::PenStyle penStyle )
146+
{
147+
mPen.setStyle( penStyle );
148+
}
149+
150+
void QgsGeometryRubberBand::setBrushStyle( Qt::BrushStyle brushStyle )
151+
{
152+
mBrush.setStyle( brushStyle );
153+
}
154+
155+
QgsRectangle QgsGeometryRubberBand::rubberBandRectangle() const
156+
{
157+
qreal scale = mMapCanvas->mapUnitsPerPixel();
158+
qreal s = ( mIconSize - 1 ) / 2.0 * scale;
159+
qreal p = mPen.width() * scale;
160+
return mGeometry->boundingBox().buffer( s + p );
161+
}

‎src/gui/qgsgeometryrubberband.h

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
/***************************************************************************
2+
qgsgeometryrubberband.h
3+
-----------------------
4+
begin : December 2014
5+
copyright : (C) 2014 by Marco Hugentobler
6+
email : marco at sourcepole dot ch
7+
***************************************************************************/
8+
9+
/***************************************************************************
10+
* *
11+
* This program is free software; you can redistribute it and/or modify *
12+
* it under the terms of the GNU General Public License as published by *
13+
* the Free Software Foundation; either version 2 of the License, or *
14+
* (at your option) any later version. *
15+
* *
16+
***************************************************************************/
17+
18+
#ifndef QGSGEOMETRYRUBBERBAND_H
19+
#define QGSGEOMETRYRUBBERBAND_H
20+
21+
#include "qgsmapcanvasitem.h"
22+
#include <QBrush>
23+
#include <QPen>
24+
25+
26+
class QgsAbstractGeometryV2;
27+
class QgsPointV2;
28+
struct QgsVertexId;
29+
30+
class GUI_EXPORT QgsGeometryRubberBand: public QgsMapCanvasItem
31+
{
32+
public:
33+
enum IconType
34+
{
35+
/**
36+
* No icon is used
37+
*/
38+
ICON_NONE,
39+
/**
40+
* A cross is used to highlight points (+)
41+
*/
42+
ICON_CROSS,
43+
/**
44+
* A cross is used to highlight points (x)
45+
*/
46+
ICON_X,
47+
/**
48+
* A box is used to highlight points (□)
49+
*/
50+
ICON_BOX,
51+
/**
52+
* A circle is used to highlight points (○)
53+
*/
54+
ICON_CIRCLE,
55+
/**
56+
* A full box is used to highlight points (■)
57+
*/
58+
ICON_FULL_BOX
59+
};
60+
61+
QgsGeometryRubberBand( QgsMapCanvas* mapCanvas, QGis::GeometryType geomType = QGis::Line );
62+
~QgsGeometryRubberBand();
63+
64+
/** Sets geometry (takes ownership). Geometry is expected to be in map coordinates */
65+
void setGeometry( QgsAbstractGeometryV2* geom );
66+
const QgsAbstractGeometryV2* geometry() { return mGeometry; }
67+
68+
void moveVertex( const QgsVertexId& id, const QgsPointV2& newPos );
69+
70+
void setFillColor( const QColor& c );
71+
void setOutlineColor( const QColor& c );
72+
void setOutlineWidth( int width );
73+
void setLineStyle( Qt::PenStyle penStyle );
74+
void setBrushStyle( Qt::BrushStyle brushStyle );
75+
void setIconType( IconType iconType ) { mIconType = iconType; }
76+
77+
protected:
78+
virtual void paint( QPainter* painter );
79+
80+
private:
81+
QgsAbstractGeometryV2* mGeometry;
82+
QBrush mBrush;
83+
QPen mPen;
84+
int mIconSize;
85+
IconType mIconType;
86+
QGis::GeometryType mGeometryType;
87+
88+
void drawVertex( QPainter* p, double x, double y );
89+
QgsRectangle rubberBandRectangle() const;
90+
};
91+
92+
#endif // QGSGEOMETRYRUBBERBAND_H

‎src/gui/qgsmaptool.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,12 @@ QgsPoint QgsMapTool::toMapCoordinates( const QPoint& point )
4444
return mCanvas->getCoordinateTransform()->toMapCoordinates( point );
4545
}
4646

47+
QgsPointV2 QgsMapTool::toMapCoordinates( QgsMapLayer* layer, const QgsPointV2& point )
48+
{
49+
QgsPoint result = mCanvas->mapSettings().layerToMapCoordinates( layer, QgsPoint( point.x(), point.y() ) );
50+
return QgsPointV2( result.x(), result.y() );
51+
}
52+
4753

4854
QgsPoint QgsMapTool::toLayerCoordinates( QgsMapLayer* layer, const QPoint& point )
4955
{

‎src/gui/qgsmaptool.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
#include "qgsconfig.h"
2020
#include "qgsmessagebar.h"
21+
#include "qgspointv2.h"
2122

2223
#include <QCursor>
2324
#include <QString>
@@ -178,6 +179,9 @@ class GUI_EXPORT QgsMapTool : public QObject
178179
//!transformation from layer's coordinates to map coordinates (which is different in case reprojection is used)
179180
QgsPoint toMapCoordinates( QgsMapLayer* layer, const QgsPoint& point );
180181

182+
//!transformation from layer's coordinates to map coordinates (which is different in case reprojection is used)
183+
QgsPointV2 toMapCoordinates( QgsMapLayer* layer, const QgsPointV2 &point );
184+
181185
//! trnasformation of the rect from map coordinates to layer's coordinates
182186
QgsRectangle toLayerCoordinates( QgsMapLayer* layer, const QgsRectangle& rect );
183187

‎src/gui/qgsvertexmarker.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,10 @@ void QgsVertexMarker::paint( QPainter* p )
8383
p->drawLine( QLineF( s, s, -s, s ) );
8484
p->drawLine( QLineF( -s, s, -s, -s ) );
8585
break;
86+
87+
case ICON_CIRCLE:
88+
p->drawEllipse( QPointF( 0, 0 ), s, s );
89+
break;
8690
}
8791
}
8892

‎src/gui/qgsvertexmarker.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ class GUI_EXPORT QgsVertexMarker : public QgsMapCanvasItem
3434
ICON_NONE,
3535
ICON_CROSS,
3636
ICON_X,
37-
ICON_BOX
37+
ICON_BOX,
38+
ICON_CIRCLE
3839
};
3940

4041
QgsVertexMarker( QgsMapCanvas* mapCanvas );

‎src/plugins/dxf2shp_converter/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ ADD_LIBRARY (dxf2shpconverterplugin MODULE ${dxf2shpconverter_SRCS} ${dxf2shpcon
3333
INCLUDE_DIRECTORIES(
3434
${CMAKE_CURRENT_BINARY_DIR}
3535
../../core
36+
../../core/geometry
3637
../../core/raster
3738
../../gui
3839
..

0 commit comments

Comments
 (0)
Please sign in to comment.