15
15
16
16
#include " qgsmaptooldeletepart.h"
17
17
18
- #include " qgisapp.h"
19
18
#include " qgsmapcanvas.h"
20
19
#include " qgsvertexmarker.h"
21
20
#include " qgsvectorlayer.h"
22
- #include " qgsmessagebar.h"
23
21
#include " qgsgeometry.h"
22
+ #include " qgstolerance.h"
24
23
25
24
#include < QMouseEvent>
26
25
#include < QMessageBox>
27
26
28
27
QgsMapToolDeletePart::QgsMapToolDeletePart ( QgsMapCanvas* canvas )
29
- : QgsMapToolEdit( canvas )
28
+ : QgsMapToolEdit( canvas ), mRubberBand( 0 )
30
29
{
31
30
}
32
31
33
32
QgsMapToolDeletePart::~QgsMapToolDeletePart ()
34
33
{
34
+ delete mRubberBand ;
35
35
}
36
36
37
37
void QgsMapToolDeletePart::canvasMoveEvent ( QMouseEvent *e )
@@ -42,18 +42,10 @@ void QgsMapToolDeletePart::canvasMoveEvent( QMouseEvent *e )
42
42
43
43
void QgsMapToolDeletePart::canvasPressEvent ( QMouseEvent *e )
44
44
{
45
-
46
- mRecentSnappingResults .clear ();
47
- // do snap -> new recent snapping results
48
- if ( mSnapper .snapToCurrentLayer ( e->pos (), mRecentSnappingResults , QgsSnapper::SnapToVertexAndSegment ) != 0 )
49
- {
50
- // error
51
- }
52
- }
53
-
54
- void QgsMapToolDeletePart::canvasReleaseEvent ( QMouseEvent *e )
55
- {
56
- Q_UNUSED ( e );
45
+ mPressedFid = -1 ;
46
+ mPressedPartNum = -1 ;
47
+ delete mRubberBand ;
48
+ mRubberBand = 0 ;
57
49
58
50
QgsMapLayer* currentLayer = mCanvas ->currentLayer ();
59
51
if ( !currentLayer )
@@ -71,62 +63,48 @@ void QgsMapToolDeletePart::canvasReleaseEvent( QMouseEvent *e )
71
63
notifyNotEditableLayer ();
72
64
return ;
73
65
}
74
- QgsGeometry* g;
75
- QgsFeature f;
76
- int partNum;
77
- switch ( vlayer->geometryType () )
66
+
67
+ QgsGeometry* geomPart;
68
+
69
+ geomPart = partUnderPoint ( e->pos (), mPressedFid , mPressedPartNum );
70
+
71
+ if ( mPressedFid != -1 )
78
72
{
79
- case QGis::Point:
80
- case QGis::Line:
81
- {
82
- if ( mRecentSnappingResults .size () == 0 )
83
- {
84
- return ;
85
- }
86
- QgsSnappingResult sr = mRecentSnappingResults .first ();
87
- vlayer->getFeatures ( QgsFeatureRequest ().setFilterFid ( sr.snappedAtGeometry ) ).nextFeature ( f );
88
- g = f.geometry ();
89
- if ( !g )
90
- return ;
91
- if ( g->wkbType () == QGis::WKBPoint25D || g->wkbType () == QGis::WKBPoint ||
92
- g->wkbType () == QGis::WKBLineString25D || g->wkbType () == QGis::WKBLineString)
93
- {
94
- emit messageEmitted ( tr ( " The Delete part tool cannot be used on single part features." ) );
95
- return ;
96
- }
97
- int vertex = sr.snappedVertexNr ;
98
- if ( vertex == -1 )
99
- {
100
- vertex = sr.beforeVertexNr ;
101
- }
102
- partNum = partNumberOfVertex ( g, vertex );
103
- break ;
104
- }
105
- case QGis::Polygon:
106
- {
107
- QgsPoint p = mCanvas ->getCoordinateTransform ()->toMapCoordinates ( e->x (),e->y ());
108
- p = toLayerCoordinates (vlayer, p);
109
- f = featureUnderPoint (p);
110
- g = f.geometry ();
111
- if ( !g )
112
- return ;
73
+ mRubberBand = createRubberBand ( vlayer->geometryType () );
113
74
114
- if ( g->wkbType () == QGis::WKBPolygon25D || g->wkbType () == QGis::WKBPolygon)
115
- {
116
- emit messageEmitted ( tr ( " The Delete part tool cannot be used on single part features." ) );
117
- return ;
118
- }
119
- partNum = partNumberOfPoint ( g, p );
120
- if ( partNum < 0 )
121
- return ;
122
- break ;
123
- }
124
- default :
125
- {
126
- QgsDebugMsg (" Unknown geometry type" );
127
- return ;
128
- }
75
+ mRubberBand ->setToGeometry ( geomPart, vlayer );
76
+ mRubberBand ->setColor ( QColor ( 255 , 0 , 0 , 65 ) );
77
+ mRubberBand ->setWidth ( 2 );
78
+ mRubberBand ->show ();
79
+ }
80
+
81
+ }
82
+
83
+ void QgsMapToolDeletePart::canvasReleaseEvent ( QMouseEvent *e )
84
+ {
85
+
86
+ delete mRubberBand ;
87
+ mRubberBand = 0 ;
88
+
89
+ if ( !vlayer || !vlayer->isEditable () )
90
+ {
91
+ return ;
129
92
}
93
+
94
+ if ( mPressedFid == -1 )
95
+ return ;
96
+
97
+ int fid;
98
+ int partNum;
99
+ partUnderPoint ( e->pos (), fid, partNum );
100
+
101
+ if ( fid != mPressedFid || partNum != mPressedPartNum )
102
+ return ;
103
+
104
+ QgsFeature f;
105
+ vlayer->getFeatures ( QgsFeatureRequest ().setFilterFid ( fid ) ).nextFeature ( f );
106
+ QgsGeometry* g = f.geometry ();
107
+
130
108
if ( g->deletePart ( partNum ) )
131
109
{
132
110
vlayer->beginEditCommand ( tr ( " Part of multipart feature deleted" ) );
@@ -141,113 +119,89 @@ void QgsMapToolDeletePart::canvasReleaseEvent( QMouseEvent *e )
141
119
return ;
142
120
}
143
121
144
- QgsFeature QgsMapToolDeletePart::featureUnderPoint (QgsPoint p )
122
+ QgsGeometry* QgsMapToolDeletePart::partUnderPoint ( QPoint point, int & fid, int & partNum )
145
123
{
146
- QgsRectangle r;
147
- double searchRadius = mCanvas ->extent ().width ()/100 ;
148
- r.setXMinimum ( p.x () - searchRadius );
149
- r.setXMaximum ( p.x () + searchRadius );
150
- r.setYMinimum ( p.y () - searchRadius );
151
- r.setYMaximum ( p.y () + searchRadius );
152
- QgsFeatureIterator fit = vlayer->getFeatures ( QgsFeatureRequest ().setFilterRect ( r ) );
153
124
QgsFeature f;
154
- fit.nextFeature ( f );
155
- return f;
156
- }
157
-
158
-
159
- int QgsMapToolDeletePart::partNumberOfPoint (QgsGeometry *g, QgsPoint point)
160
- {
161
- int part;
162
- switch ( g->wkbType () )
163
- {
164
- case QGis::WKBMultiPolygon25D:
165
- case QGis::WKBMultiPolygon:
166
- {
167
- QgsMultiPolygon mpolygon = g->asMultiPolygon ();
168
- for ( part = 0 ; part < mpolygon.count (); part++ ) // go through the polygons
169
- {
170
- const QgsPolygon& polygon = mpolygon[part];
171
- QgsGeometry* partGeo = QgsGeometry::fromPolygon (polygon);
172
- if ( partGeo->contains ( &point ) )
173
- return part;
174
- }
175
- return -1 ; // not found
176
- }
177
- default :
178
- return -1 ;
179
- }
180
- }
181
-
182
- int QgsMapToolDeletePart::partNumberOfVertex ( QgsGeometry* g, int beforeVertexNr )
183
- {
184
- int part;
125
+ QgsGeometry* geomPart = new QgsGeometry ();
185
126
186
- switch ( g-> wkbType () )
127
+ switch ( vlayer-> geometryType () )
187
128
{
188
- case QGis::WKBLineString25D:
189
- case QGis::WKBLineString:
190
- case QGis::WKBPoint25D:
191
- case QGis::WKBPoint:
192
- case QGis::WKBPolygon25D:
193
- case QGis::WKBPolygon:
194
- return 1 ;
195
-
196
- case QGis::WKBMultiPoint25D:
197
- case QGis::WKBMultiPoint:
198
- if ( beforeVertexNr < g->asMultiPoint ().count () )
199
- return beforeVertexNr;
200
- else
201
- return -1 ;
202
-
203
- case QGis::WKBMultiLineString25D:
204
- case QGis::WKBMultiLineString:
129
+ case QGis::Point:
130
+ case QGis::Line:
205
131
{
206
- QgsMultiPolyline mline = g->asMultiPolyline ();
207
- for ( part = 0 ; part < mline.count (); part++ )
132
+ if ( mSnapper .snapToCurrentLayer ( point, mRecentSnappingResults , QgsSnapper::SnapToVertexAndSegment ) == 0 )
208
133
{
209
- if ( beforeVertexNr < mline[part].count () )
210
- return part;
211
-
212
- beforeVertexNr -= mline[part].count ();
134
+ if ( mRecentSnappingResults .length () > 0 )
135
+ {
136
+ QgsSnappingResult sr = mRecentSnappingResults .first ();
137
+ int snapVertex = sr.snappedVertexNr ;
138
+ if ( snapVertex == -1 )
139
+ snapVertex = sr.beforeVertexNr ;
140
+ vlayer->getFeatures ( QgsFeatureRequest ().setFilterFid ( sr.snappedAtGeometry ) ).nextFeature ( f );
141
+ QgsGeometry* g = f.geometry ();
142
+ if ( !g->isMultipart () )
143
+ return geomPart;
144
+ if ( g->wkbType () == QGis::WKBMultiPoint || g->wkbType () == QGis::WKBMultiPoint25D )
145
+ {
146
+ fid = sr.snappedAtGeometry ;
147
+ partNum = snapVertex;
148
+ return QgsGeometry::fromPoint ( sr.snappedVertex );
149
+ }
150
+ if ( g->wkbType () == QGis::WKBMultiLineString || g->wkbType () == QGis::WKBMultiLineString25D )
151
+ {
152
+ QgsMultiPolyline mline = g->asMultiPolyline ();
153
+ for ( int part = 0 ; part < mline.count (); part++ )
154
+ {
155
+ if ( snapVertex < mline[part].count () )
156
+ {
157
+ fid = sr.snappedAtGeometry ;
158
+ partNum = part;
159
+ return QgsGeometry::fromPolyline ( mline[part] );
160
+ }
161
+ snapVertex -= mline[part].count ();
162
+ }
163
+ }
164
+ }
213
165
}
214
- return - 1 ; // not found
166
+ break ;
215
167
}
216
-
217
- case QGis::WKBMultiPolygon25D:
218
- case QGis::WKBMultiPolygon:
168
+ case QGis::Polygon:
219
169
{
170
+ QgsPoint layerCoords = toLayerCoordinates ( vlayer, point );
171
+ double searchRadius = QgsTolerance::vertexSearchRadius ( mCanvas ->currentLayer (), mCanvas ->mapSettings () );
172
+ QgsRectangle selectRect ( layerCoords.x () - searchRadius, layerCoords.y () - searchRadius,
173
+ layerCoords.x () + searchRadius, layerCoords.y () + searchRadius );
174
+ QgsFeatureIterator fit = vlayer->getFeatures ( QgsFeatureRequest ().setFilterRect ( selectRect ) );
175
+ fit.nextFeature ( f );
176
+ QgsGeometry* g = f.geometry ();
177
+ if ( !g )
178
+ return geomPart;
179
+ if ( !g->isMultipart () )
180
+ return geomPart;
220
181
QgsMultiPolygon mpolygon = g->asMultiPolygon ();
221
- for ( part = 0 ; part < mpolygon.count (); part++ ) // go through the polygons
182
+ for ( int part = 0 ; part < mpolygon.count (); part++ ) // go through the polygons
222
183
{
223
184
const QgsPolygon& polygon = mpolygon[part];
224
- for ( int ring = 0 ; ring < polygon.count (); ring++ ) // go through the rings
185
+ QgsGeometry* partGeo = QgsGeometry::fromPolygon ( polygon );
186
+ if ( partGeo->contains ( &layerCoords ) )
225
187
{
226
- if ( beforeVertexNr < polygon[ring].count () )
227
- return part;
228
-
229
- beforeVertexNr -= polygon[ring].count ();
188
+ fid = f.id ();
189
+ partNum = part;
190
+ return partGeo;
230
191
}
231
192
}
232
- return - 1 ; // not found
193
+ break ;
233
194
}
234
-
235
195
default :
236
- return -1 ;
196
+ {
197
+ break ;
198
+ }
237
199
}
200
+ return geomPart;
238
201
}
239
202
240
203
void QgsMapToolDeletePart::deactivate ()
241
204
{
242
205
QgsMapTool::deactivate ();
243
206
}
244
207
245
- void QgsMapToolDeletePart::notifySinglePart ()
246
- {
247
- QgisApp::instance ()->messageBar ()->pushMessage (
248
- tr ( " Cannot use delete part" ),
249
- tr ( " The Delete part tool cannot be used on single part features." ),
250
- QgsMessageBar::INFO,
251
- QgisApp::instance ()->messageTimeout () );
252
- return ;
253
- }
0 commit comments