1818#include " qgsmapcanvas.h"
1919#include " qgsvertexmarker.h"
2020#include " qgsvectorlayer.h"
21+ #include " qgsgeometry.h"
22+ #include " qgstolerance.h"
2123
2224#include < QMouseEvent>
2325#include < QMessageBox>
2426
2527QgsMapToolDeletePart::QgsMapToolDeletePart ( QgsMapCanvas* canvas )
26- : QgsMapToolVertexEdit ( canvas ), mCross ( 0 )
28+ : QgsMapToolEdit ( canvas ), mRubberBand ( 0 )
2729{
2830}
2931
3032QgsMapToolDeletePart::~QgsMapToolDeletePart ()
3133{
32- delete mCross ;
34+ delete mRubberBand ;
3335}
3436
3537void QgsMapToolDeletePart::canvasMoveEvent ( QMouseEvent *e )
@@ -40,150 +42,158 @@ void QgsMapToolDeletePart::canvasMoveEvent( QMouseEvent *e )
4042
4143void QgsMapToolDeletePart::canvasPressEvent ( QMouseEvent *e )
4244{
43- delete mCross ;
44- mCross = 0 ;
45+ mPressedFid = -1 ;
46+ mPressedPartNum = -1 ;
47+ delete mRubberBand ;
48+ mRubberBand = 0 ;
4549
46- mRecentSnappingResults .clear ();
47- // do snap -> new recent snapping results
48- if ( mSnapper .snapToCurrentLayer ( e->pos (), mRecentSnappingResults , QgsSnapper::SnapToVertexAndSegment ) != 0 )
50+ QgsMapLayer* currentLayer = mCanvas ->currentLayer ();
51+ if ( !currentLayer )
52+ return ;
53+
54+ vlayer = qobject_cast<QgsVectorLayer *>( currentLayer );
55+ if ( !vlayer )
4956 {
50- // error
57+ notifyNotVectorLayer ();
58+ return ;
5159 }
5260
53- if ( mRecentSnappingResults . size () > 0 )
61+ if ( !vlayer-> isEditable () )
5462 {
55- // remove previous warning
56- emit messageDiscarded ();
63+ notifyNotEditableLayer ();
64+ return ;
65+ }
5766
58- QgsPoint markerPoint = mRecentSnappingResults . begin ()-> snappedVertex ;
67+ QgsGeometry* geomPart ;
5968
60- // show vertex marker
61- mCross = new QgsVertexMarker ( mCanvas );
62- mCross ->setIconType ( QgsVertexMarker::ICON_X );
63- mCross ->setCenter ( markerPoint );
64- }
65- else
69+ geomPart = partUnderPoint ( e->pos (), mPressedFid , mPressedPartNum );
70+
71+ if ( mPressedFid != -1 )
6672 {
67- emit messageEmitted ( tr ( " could not snap to a part on the current layer." ) );
73+ mRubberBand = createRubberBand ( vlayer->geometryType () );
74+
75+ mRubberBand ->setToGeometry ( geomPart, vlayer );
76+ mRubberBand ->show ();
6877 }
78+
6979}
7080
7181void QgsMapToolDeletePart::canvasReleaseEvent ( QMouseEvent *e )
7282{
7383 Q_UNUSED ( e );
74- delete mCross ;
75- mCross = 0 ;
7684
77- QgsMapLayer* currentLayer = mCanvas ->currentLayer ();
78- if ( !currentLayer )
79- return ;
85+ delete mRubberBand ;
86+ mRubberBand = 0 ;
8087
81- QgsVectorLayer* vlayer = qobject_cast<QgsVectorLayer *>( currentLayer );
82- if ( !vlayer )
83- return ;
84-
85- if ( mRecentSnappingResults .size () > 0 )
88+ if ( !vlayer || !vlayer->isEditable () )
8689 {
87- QList<QgsSnappingResult>::iterator sr_it = mRecentSnappingResults .begin ();
88- for ( ; sr_it != mRecentSnappingResults .end (); ++sr_it )
89- {
90- if ( sr_it->snappedVertexNr != -1 )
91- deletePart ( sr_it->snappedAtGeometry , sr_it->snappedVertexNr , vlayer );
92- else if ( sr_it->beforeVertexNr != -1 )
93- deletePart ( sr_it->snappedAtGeometry , sr_it->beforeVertexNr , vlayer );
94- else if ( sr_it->afterVertexNr != -1 )
95- deletePart ( sr_it->snappedAtGeometry , sr_it->afterVertexNr , vlayer );
96- }
90+ return ;
9791 }
9892
99- }
100-
93+ if ( mPressedFid == - 1 )
94+ return ;
10195
102- void QgsMapToolDeletePart::deletePart ( QgsFeatureId fId , int beforeVertexNr, QgsVectorLayer* vlayer )
103- {
10496 QgsFeature f;
105- vlayer->getFeatures ( QgsFeatureRequest ().setFilterFid ( fId ) ).nextFeature ( f );
106-
107- // find out the part number
97+ vlayer->getFeatures ( QgsFeatureRequest ().setFilterFid ( mPressedFid ) ).nextFeature ( f );
10898 QgsGeometry* g = f.geometry ();
109- if ( !g->isMultipart () )
110- {
111- QMessageBox::information ( mCanvas , tr ( " Delete part" ), tr ( " This isn't a multipart geometry." ) );
112- return ;
113- }
114-
115- int partNum = partNumberOfVertex ( g, beforeVertexNr );
11699
117- if ( g->deletePart ( partNum ) )
100+ if ( g->deletePart ( mPressedPartNum ) )
118101 {
119102 vlayer->beginEditCommand ( tr ( " Part of multipart feature deleted" ) );
120- vlayer->changeGeometry ( fId , g );
103+ vlayer->changeGeometry ( f. id () , g );
121104 vlayer->endEditCommand ();
122105 mCanvas ->refresh ();
123106 }
124107 else
125108 {
126- QMessageBox::information ( mCanvas , tr ( " Delete part " ), tr ( " Couldn't remove the selected part." ) );
109+ emit messageEmitted ( tr ( " Couldn't remove the selected part." ) );
127110 }
128-
111+ return ;
129112}
130113
131- int QgsMapToolDeletePart::partNumberOfVertex ( QgsGeometry* g , int beforeVertexNr )
114+ QgsGeometry* QgsMapToolDeletePart::partUnderPoint ( QPoint point , int & fid, int & partNum )
132115{
133- int part;
116+ QgsFeature f;
117+ QgsGeometry* geomPart = new QgsGeometry ();
134118
135- switch ( g-> wkbType () )
119+ switch ( vlayer-> geometryType () )
136120 {
137- case QGis::WKBMultiPoint25D:
138- case QGis::WKBMultiPoint:
139- if ( beforeVertexNr < g->asMultiPoint ().count () )
140- return beforeVertexNr;
141- else
142- return -1 ;
143-
144- case QGis::WKBMultiLineString25D:
145- case QGis::WKBMultiLineString:
121+ case QGis::Point:
122+ case QGis::Line:
146123 {
147- QgsMultiPolyline mline = g->asMultiPolyline ();
148- for ( part = 0 ; part < mline.count (); part++ )
124+ if ( mSnapper .snapToCurrentLayer ( point, mRecentSnappingResults , QgsSnapper::SnapToVertexAndSegment ) == 0 )
149125 {
150- if ( beforeVertexNr < mline[part].count () )
151- return part;
152-
153- beforeVertexNr -= mline[part].count ();
126+ if ( mRecentSnappingResults .length () > 0 )
127+ {
128+ QgsSnappingResult sr = mRecentSnappingResults .first ();
129+ int snapVertex = sr.snappedVertexNr ;
130+ if ( snapVertex == -1 )
131+ snapVertex = sr.beforeVertexNr ;
132+ vlayer->getFeatures ( QgsFeatureRequest ().setFilterFid ( sr.snappedAtGeometry ) ).nextFeature ( f );
133+ QgsGeometry* g = f.geometry ();
134+ if ( !g->isMultipart () )
135+ return geomPart;
136+ if ( g->wkbType () == QGis::WKBMultiPoint || g->wkbType () == QGis::WKBMultiPoint25D )
137+ {
138+ fid = sr.snappedAtGeometry ;
139+ partNum = snapVertex;
140+ return QgsGeometry::fromPoint ( sr.snappedVertex );
141+ }
142+ if ( g->wkbType () == QGis::WKBMultiLineString || g->wkbType () == QGis::WKBMultiLineString25D )
143+ {
144+ QgsMultiPolyline mline = g->asMultiPolyline ();
145+ for ( int part = 0 ; part < mline.count (); part++ )
146+ {
147+ if ( snapVertex < mline[part].count () )
148+ {
149+ fid = sr.snappedAtGeometry ;
150+ partNum = part;
151+ return QgsGeometry::fromPolyline ( mline[part] );
152+ }
153+ snapVertex -= mline[part].count ();
154+ }
155+ }
156+ }
154157 }
155- return - 1 ; // not found
158+ break ;
156159 }
157-
158- case QGis::WKBMultiPolygon25D:
159- case QGis::WKBMultiPolygon:
160+ case QGis::Polygon:
160161 {
162+ QgsPoint layerCoords = toLayerCoordinates ( vlayer, point );
163+ double searchRadius = QgsTolerance::vertexSearchRadius ( mCanvas ->currentLayer (), mCanvas ->mapSettings () );
164+ QgsRectangle selectRect ( layerCoords.x () - searchRadius, layerCoords.y () - searchRadius,
165+ layerCoords.x () + searchRadius, layerCoords.y () + searchRadius );
166+ QgsFeatureIterator fit = vlayer->getFeatures ( QgsFeatureRequest ().setFilterRect ( selectRect ) );
167+ fit.nextFeature ( f );
168+ QgsGeometry* g = f.geometry ();
169+ if ( !g )
170+ return geomPart;
171+ if ( !g->isMultipart () )
172+ return geomPart;
161173 QgsMultiPolygon mpolygon = g->asMultiPolygon ();
162- for ( part = 0 ; part < mpolygon.count (); part++ ) // go through the polygons
174+ for ( int part = 0 ; part < mpolygon.count (); part++ ) // go through the polygons
163175 {
164176 const QgsPolygon& polygon = mpolygon[part];
165- for ( int ring = 0 ; ring < polygon.count (); ring++ ) // go through the rings
177+ QgsGeometry* partGeo = QgsGeometry::fromPolygon ( polygon );
178+ if ( partGeo->contains ( &layerCoords ) )
166179 {
167- if ( beforeVertexNr < polygon[ring].count () )
168- return part;
169-
170- beforeVertexNr -= polygon[ring].count ();
180+ fid = f.id ();
181+ partNum = part;
182+ return partGeo;
171183 }
172184 }
173- return - 1 ; // not found
185+ break ;
174186 }
175-
176187 default :
177- return -1 ;
188+ {
189+ break ;
190+ }
178191 }
192+ return geomPart;
179193}
180194
181-
182195void QgsMapToolDeletePart::deactivate ()
183196{
184- delete mCross ;
185- mCross = 0 ;
186-
187197 QgsMapTool::deactivate ();
188198}
189199
0 commit comments