18
18
#include " qgsmapcanvas.h"
19
19
#include " qgsvertexmarker.h"
20
20
#include " qgsvectorlayer.h"
21
+ #include " qgsmessagebar.h"
22
+ #include " qgisapp.h"
21
23
22
24
#include < QMouseEvent>
23
25
#include < QMessageBox>
24
26
25
27
QgsMapToolDeleteRing::QgsMapToolDeleteRing ( QgsMapCanvas* canvas )
26
28
: QgsMapToolVertexEdit( canvas )
27
- , mCross( 0 )
28
29
{
29
30
mToolName = tr ( " Delete ring" );
30
31
}
31
32
32
33
QgsMapToolDeleteRing::~QgsMapToolDeleteRing ()
33
34
{
34
- delete mCross ;
35
35
}
36
36
37
37
void QgsMapToolDeleteRing::canvasMoveEvent ( QMouseEvent *e )
@@ -42,62 +42,110 @@ void QgsMapToolDeleteRing::canvasMoveEvent( QMouseEvent *e )
42
42
43
43
void QgsMapToolDeleteRing::canvasPressEvent ( QMouseEvent *e )
44
44
{
45
- delete mCross ;
46
- mCross = 0 ;
47
-
48
- mRecentSnappingResults .clear ();
49
45
// do snap -> new recent snapping results
50
46
if ( mSnapper .snapToCurrentLayer ( e->pos (), mRecentSnappingResults , QgsSnapper::SnapToVertexAndSegment ) != 0 )
51
47
{
52
48
// error
53
49
}
54
-
55
- if ( mRecentSnappingResults .size () > 0 )
56
- {
57
- // remove previous warning
58
- emit messageDiscarded ();
59
-
60
- QgsPoint markerPoint = mRecentSnappingResults .begin ()->snappedVertex ;
61
-
62
- // show vertex marker
63
- mCross = new QgsVertexMarker ( mCanvas );
64
- mCross ->setIconType ( QgsVertexMarker::ICON_X );
65
- mCross ->setCenter ( markerPoint );
66
- }
67
- else
68
- {
69
- emit messageEmitted ( tr ( " could not snap to a ring on the current layer." ) );
70
- }
71
50
}
72
51
73
52
void QgsMapToolDeleteRing::canvasReleaseEvent ( QMouseEvent *e )
74
53
{
75
54
Q_UNUSED ( e );
76
- delete mCross ;
77
- mCross = 0 ;
78
55
79
56
QgsMapLayer* currentLayer = mCanvas ->currentLayer ();
80
57
if ( !currentLayer )
81
58
return ;
82
59
83
- QgsVectorLayer* vlayer = qobject_cast<QgsVectorLayer *>( currentLayer );
60
+ vlayer = qobject_cast<QgsVectorLayer *>( currentLayer );
84
61
if ( !vlayer )
62
+ {
63
+ notifyNotVectorLayer ();
64
+ return ;
65
+ }
66
+
67
+ if ( vlayer->geometryType () != QGis::Polygon )
68
+ {
69
+ emit messageEmitted ( tr ( " Delete ring can only be used in a polygon layer." ) );
70
+ return ;
71
+ }
72
+
73
+ if ( !vlayer->isEditable () )
74
+ {
75
+ notifyNotEditableLayer ();
85
76
return ;
77
+ }
86
78
79
+ QgsPoint p = mCanvas ->getCoordinateTransform ()->toMapCoordinates ( e->x (),e->y ());
80
+ p = toLayerCoordinates (vlayer, p);
87
81
88
- if ( mRecentSnappingResults .size () > 0 )
82
+ // There is no easy way to find if we are inside the ring of a feature,
83
+ // so we iterate over all the features visible in the canvas
84
+ QgsFeatureIterator fit = vlayer->getFeatures ( QgsFeatureRequest ().setFilterRect ( mCanvas ->extent () ) );
85
+ QgsFeature f;
86
+ QgsGeometry* g;
87
+ QgsMultiPolygon pol;
88
+ QgsPolygon tempPol;
89
+ QgsGeometry* tempGeom;
90
+ int fid, partNum, ringNum;
91
+ double area = std::numeric_limits<double >::max ();
92
+ while ( fit.nextFeature ( f ) )
89
93
{
90
- QList<QgsSnappingResult>::iterator sr_it = mRecentSnappingResults .begin ();
91
- for ( ; sr_it != mRecentSnappingResults .end (); ++sr_it )
94
+ QgsDebugMsg (QString (" Feature %1" ).arg (f.id ()));
95
+ g = f.geometry ();
96
+ if ( !g )
97
+ continue ;
98
+ if ( g->wkbType () == QGis::WKBPolygon || g->wkbType () == QGis::WKBPolygon25D )
99
+ {
100
+ pol = QgsMultiPolygon () << g->asPolygon ();
101
+ }
102
+ else
92
103
{
93
- if ( sr_it->snappedVertexNr != -1 )
94
- deleteRing ( sr_it->snappedAtGeometry , sr_it->snappedVertexNr , vlayer );
95
- else if ( sr_it->beforeVertexNr != -1 )
96
- deleteRing ( sr_it->snappedAtGeometry , sr_it->beforeVertexNr , vlayer );
97
- else if ( sr_it->afterVertexNr != -1 )
98
- deleteRing ( sr_it->snappedAtGeometry , sr_it->afterVertexNr , vlayer );
104
+ pol = g->asMultiPolygon ();
99
105
}
106
+
107
+ for (int i = 0 ; i < pol.size () ; ++i)
108
+ {// for each part
109
+ QgsDebugMsg (QString (" Feature %1 part %2" ).arg (f.id ()).arg (i));
110
+ if ( pol[i].size () > 1 )
111
+ {
112
+ QgsDebugMsg (QString (" %1 has a ring in part %2" ).arg (f.id ()).arg (i));
113
+ for ( int j = 1 ; j<pol[i].size ();++j)
114
+ {
115
+ tempPol = QgsPolygon ()<<pol[i][j];
116
+ tempGeom = QgsGeometry::fromPolygon ( tempPol );
117
+ if (tempGeom->area () < area && tempGeom->contains (&p) )
118
+ {
119
+ QgsDebugMsg (QString (" %1, part %2, ring %3 contains the cursor" ).arg (f.id ()).arg (i).arg (j));
120
+ fid=f.id ();
121
+ partNum=i;
122
+ ringNum=j;
123
+ area=tempGeom->area ();
124
+ }
125
+ }
126
+ }
127
+ }
128
+ }
129
+
130
+ vlayer->getFeatures ( QgsFeatureRequest ().setFilterFid ( fid ) ).nextFeature ( f );
131
+
132
+ g = f.geometry ();
133
+ if ( g->deleteRing ( ringNum, partNum ) )
134
+ {
135
+ vlayer->beginEditCommand ( tr ( " Ring deleted" ) );
136
+ vlayer->changeGeometry ( fid, g );
137
+ vlayer->endEditCommand ();
138
+ mCanvas ->refresh ();
100
139
}
140
+ /*
141
+ if ( g->deleteRing( ringNum, partNum ) )
142
+ {
143
+ vlayer->beginEditCommand( tr( "Ring deleted" ) );
144
+ vlayer->changeGeometry( f.id(), g );
145
+ vlayer->endEditCommand();
146
+ mCanvas->refresh();
147
+ }
148
+ */
101
149
}
102
150
103
151
void QgsMapToolDeleteRing::deleteRing ( QgsFeatureId fId , int beforeVertexNr, QgsVectorLayer* vlayer )
@@ -130,6 +178,17 @@ void QgsMapToolDeleteRing::deleteRing( QgsFeatureId fId, int beforeVertexNr, Qgs
130
178
131
179
}
132
180
181
+ int QgsMapToolDeleteRing::partNumberOfPoint (QgsGeometry* g, QgsPoint p)
182
+ {
183
+ return 0 ;
184
+ }
185
+
186
+ int QgsMapToolDeleteRing::ringNumberOfPoint (QgsGeometry* g, QgsPoint p, int partNum)
187
+ {
188
+ return 0 ;
189
+ }
190
+
191
+
133
192
int QgsMapToolDeleteRing::ringNumInPolygon ( QgsGeometry* g, int vertexNr )
134
193
{
135
194
QgsPolygon polygon = g->asPolygon ();
@@ -166,8 +225,6 @@ int QgsMapToolDeleteRing::ringNumInMultiPolygon( QgsGeometry* g, int vertexNr, i
166
225
167
226
void QgsMapToolDeleteRing::deactivate ()
168
227
{
169
- delete mCross ;
170
- mCross = 0 ;
171
228
172
229
QgsMapTool::deactivate ();
173
230
}
0 commit comments