15
15
16
16
#include " qgsmaptooloffsetcurve.h"
17
17
#include " qgsmapcanvas.h"
18
+ #include " qgsmaplayerregistry.h"
18
19
#include " qgsrubberband.h"
19
20
#include " qgsvectorlayer.h"
20
21
#include < QMouseEvent>
@@ -40,26 +41,21 @@ void QgsMapToolOffsetCurve::canvasPressEvent( QMouseEvent * e )
40
41
return ;
41
42
}
42
43
43
- QgsFeatureList selectedFeatures = layer->selectedFeatures ();
44
- if ( selectedFeatures.size () > 0 )
44
+ QList<QgsSnappingResult> snapResults;
45
+ QgsMapCanvasSnapper snapper ( mCanvas );
46
+ snapper.snapToBackgroundLayers ( e->pos (), snapResults );
47
+ if ( snapResults.size () > 0 )
45
48
{
46
- // take the first selected feature
47
- mOriginalGeometry = selectedFeatures[0 ].geometryAndOwnership ();
48
- mRubberBand = createRubberBand ();
49
- mRubberBand ->setToGeometry ( mOriginalGeometry , layer );
50
- mModifiedFeature = selectedFeatures[0 ].id ();
51
- }
52
- else // do a snap to the closest feature
53
- {
54
- QList<QgsSnappingResult> snapResults;
55
- QgsMapCanvasSnapper snapper ( mCanvas );
56
- snapper.snapToCurrentLayer ( e->pos (), snapResults, QgsSnapper::SnapToSegment );
57
- if ( snapResults.size () > 0 )
49
+ QgsFeature fet;
50
+ const QgsSnappingResult& snapResult = snapResults.at ( 0 );
51
+ if ( snapResult.layer )
58
52
{
59
- QgsFeature fet;
60
- if ( layer->featureAtId ( snapResults.at ( 0 ).snappedAtGeometry , fet ) )
53
+ mSourceLayerId = snapResult.layer ->id ();
54
+
55
+ QgsVectorLayer* vl = dynamic_cast <QgsVectorLayer*>( QgsMapLayerRegistry::instance ()->mapLayer ( mSourceLayerId ) );
56
+ if ( vl && vl->featureAtId ( snapResult.snappedAtGeometry , fet ) )
61
57
{
62
- mOriginalGeometry = fet. geometryAndOwnership ( );
58
+ mOriginalGeometry = createOriginGeometry ( vl, snapResult, fet );
63
59
mRubberBand = createRubberBand ();
64
60
mRubberBand ->setToGeometry ( mOriginalGeometry , layer );
65
61
mModifiedFeature = fet.id ();
@@ -78,7 +74,20 @@ void QgsMapToolOffsetCurve::canvasReleaseEvent( QMouseEvent * e )
78
74
}
79
75
80
76
vlayer->beginEditCommand ( tr ( " Offset curve" ) );
81
- if ( vlayer->changeGeometry ( mModifiedFeature , &mModifiedGeometry ) )
77
+
78
+ bool editOk;
79
+ if ( mSourceLayerId == vlayer->id () )
80
+ {
81
+ editOk = vlayer->changeGeometry ( mModifiedFeature , &mModifiedGeometry );
82
+ }
83
+ else
84
+ {
85
+ QgsFeature f;
86
+ f.setGeometry ( mModifiedGeometry );
87
+ editOk = vlayer->addFeature ( f );
88
+ }
89
+
90
+ if ( editOk )
82
91
{
83
92
vlayer->endEditCommand ();
84
93
}
@@ -113,7 +122,7 @@ void QgsMapToolOffsetCurve::canvasMoveEvent( QMouseEvent * e )
113
122
int beforeVertex;
114
123
double leftOf;
115
124
double offset = sqrt ( mOriginalGeometry ->closestSegmentWithContext ( layerCoords, minDistPoint, beforeVertex, &leftOf ) );
116
- qWarning ( QString::number ( offset ).toLocal8Bit ().data () );
125
+ // qWarning( QString::number( offset ).toLocal8Bit().data() );
117
126
118
127
// create offset geometry using geos
119
128
QgsGeometry geomCopy ( *mOriginalGeometry );
@@ -129,6 +138,50 @@ void QgsMapToolOffsetCurve::canvasMoveEvent( QMouseEvent * e )
129
138
}
130
139
}
131
140
141
+ QgsGeometry* QgsMapToolOffsetCurve::createOriginGeometry ( QgsVectorLayer* vl, const QgsSnappingResult& sr, QgsFeature& snappedFeature )
142
+ {
143
+ if ( !vl )
144
+ {
145
+ return 0 ;
146
+ }
147
+
148
+ if ( vl == currentVectorLayer () )
149
+ {
150
+ // don't consider selected geometries, only the snap result
151
+ return snappedFeature.geometryAndOwnership ();
152
+ }
153
+ else
154
+ {
155
+ // for background layers, try to merge selected entries together if snapped feature is contained in selection
156
+ const QgsFeatureIds& selection = vl->selectedFeaturesIds ();
157
+ if ( selection.size () < 1 || !selection.contains ( sr.snappedAtGeometry ) )
158
+ {
159
+ return snappedFeature.geometryAndOwnership ();
160
+ }
161
+ else
162
+ {
163
+ // merge together if several features
164
+ QgsFeatureList selectedFeatures = vl->selectedFeatures ();
165
+ QgsFeatureList::iterator selIt = selectedFeatures.begin ();
166
+ QgsGeometry* geom = selIt->geometryAndOwnership ();
167
+ ++selIt;
168
+ for ( ; selIt != selectedFeatures.end (); ++selIt )
169
+ {
170
+ geom = geom->combine ( selIt->geometry () );
171
+ }
172
+
173
+ // if multitype, return only the snaped to geometry
174
+ if ( geom->isMultipart () )
175
+ {
176
+ delete geom;
177
+ return snappedFeature.geometryAndOwnership ();
178
+ }
179
+
180
+ return geom;
181
+ }
182
+ }
183
+ }
184
+
132
185
void QgsMapToolOffsetCurve::deleteRubberBandAndGeometry ()
133
186
{
134
187
delete mRubberBand ;
0 commit comments