Skip to content

Commit 49dfe3d

Browse files
committedDec 14, 2017
[bugfix] Do not add binding line in both side in reshape map tool
1 parent 2ef6a82 commit 49dfe3d

File tree

4 files changed

+110
-53
lines changed

4 files changed

+110
-53
lines changed
 

‎src/app/qgsmaptoolreshape.cpp

Lines changed: 103 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -75,70 +75,122 @@ void QgsMapToolReshape::cadCanvasReleaseEvent( QgsMapMouseEvent * e )
7575
stopCapturing();
7676
return;
7777
}
78-
QgsPoint firstPoint = points().at( 0 );
79-
QgsRectangle bbox( firstPoint.x(), firstPoint.y(), firstPoint.x(), firstPoint.y() );
80-
for ( int i = 1; i < size(); ++i )
81-
{
82-
bbox.combineExtentWith( points().at( i ).x(), points().at( i ).y() );
83-
}
8478

85-
//query all the features that intersect bounding box of capture line
86-
QgsFeatureIterator fit = vlayer->getFeatures( QgsFeatureRequest().setFilterRect( bbox ).setSubsetOfAttributes( QgsAttributeList() ) );
87-
QgsFeature f;
88-
int reshapeReturn;
89-
bool reshapeDone = false;
79+
reshape( vlayer );
80+
81+
stopCapturing();
82+
}
83+
}
84+
85+
void QgsMapToolReshape::reshape( QgsVectorLayer *vlayer )
86+
{
87+
std::cout << "QgsMapToolReshape::reshape 0" << std::endl;
88+
if ( !vlayer )
89+
return;
90+
91+
QgsPoint firstPoint = points().at( 0 );
92+
QgsRectangle bbox( firstPoint.x(), firstPoint.y(), firstPoint.x(), firstPoint.y() );
93+
for ( int i = 1; i < size(); ++i )
94+
{
95+
bbox.combineExtentWith( points().at( i ).x(), points().at( i ).y() );
96+
}
9097

91-
vlayer->beginEditCommand( tr( "Reshape" ) );
92-
while ( fit.nextFeature( f ) )
98+
//query all the features that intersect bounding box of capture line
99+
std::cout << "QgsMapToolReshape::reshape 1" << std::endl;
100+
QgsFeatureIterator fit = vlayer->getFeatures( QgsFeatureRequest().setFilterRect( bbox ).setSubsetOfAttributes( QgsAttributeList() ) );
101+
QgsFeature f;
102+
int reshapeReturn;
103+
bool reshapeDone = false;
104+
bool isBinding = isBindingLine( vlayer, bbox );
105+
106+
vlayer->beginEditCommand( tr( "Reshape" ) );
107+
std::cout << "QgsMapToolReshape::reshape 2" << std::endl;
108+
while ( fit.nextFeature( f ) )
109+
{
110+
std::cout << "QgsMapToolReshape::reshape 3" << std::endl;
111+
//query geometry
112+
//call geometry->reshape(mCaptureList)
113+
//register changed geometry in vector layer
114+
QgsGeometry* geom = f.geometry();
115+
if ( geom )
93116
{
94-
//query geometry
95-
//call geometry->reshape(mCaptureList)
96-
//register changed geometry in vector layer
97-
QgsGeometry* geom = f.geometry();
98-
if ( geom )
117+
std::cout << "QgsMapToolReshape::reshape 4" << std::endl;
118+
// in case of a binding line, we just want to update the line from
119+
// the starting point and not both side
120+
if ( isBinding && !geom->asPolyline().contains( points().first() ) )
121+
continue;
122+
123+
std::cout << "QgsMapToolReshape::reshape 5" << std::endl;
124+
reshapeReturn = geom->reshapeGeometry( pointsV2() );
125+
if ( reshapeReturn == 0 )
99126
{
100-
reshapeReturn = geom->reshapeGeometry( pointsV2() );
101-
if ( reshapeReturn == 0 )
127+
//avoid intersections on polygon layers
128+
if ( vlayer->geometryType() == QGis::Polygon )
102129
{
103-
//avoid intersections on polygon layers
104-
if ( vlayer->geometryType() == QGis::Polygon )
130+
//ignore all current layer features as they should be reshaped too
131+
QMap<QgsVectorLayer*, QSet<QgsFeatureId> > ignoreFeatures;
132+
ignoreFeatures.insert( vlayer, vlayer->allFeatureIds() );
133+
134+
if ( geom->avoidIntersections( ignoreFeatures ) != 0 )
105135
{
106-
//ignore all current layer features as they should be reshaped too
107-
QMap<QgsVectorLayer*, QSet<QgsFeatureId> > ignoreFeatures;
108-
ignoreFeatures.insert( vlayer, vlayer->allFeatureIds() );
109-
110-
if ( geom->avoidIntersections( ignoreFeatures ) != 0 )
111-
{
112-
emit messageEmitted( tr( "An error was reported during intersection removal" ), QgsMessageBar::CRITICAL );
113-
vlayer->destroyEditCommand();
114-
stopCapturing();
115-
return;
116-
}
117-
118-
if ( geom->isGeosEmpty() ) //intersection removal might have removed the whole geometry
119-
{
120-
emit messageEmitted( tr( "The feature cannot be reshaped because the resulting geometry is empty" ), QgsMessageBar::CRITICAL );
121-
vlayer->destroyEditCommand();
122-
stopCapturing();
123-
return;
124-
}
136+
emit messageEmitted( tr( "An error was reported during intersection removal" ), QgsMessageBar::CRITICAL );
137+
vlayer->destroyEditCommand();
138+
stopCapturing();
139+
return;
125140
}
126141

127-
vlayer->changeGeometry( f.id(), geom );
128-
reshapeDone = true;
142+
if ( geom->isGeosEmpty() ) //intersection removal might have removed the whole geometry
143+
{
144+
emit messageEmitted( tr( "The feature cannot be reshaped because the resulting geometry is empty" ), QgsMessageBar::CRITICAL );
145+
vlayer->destroyEditCommand();
146+
stopCapturing();
147+
return;
148+
}
129149
}
150+
151+
vlayer->changeGeometry( f.id(), geom );
152+
reshapeDone = true;
130153
}
131154
}
155+
}
132156

133-
if ( reshapeDone )
134-
{
135-
vlayer->endEditCommand();
136-
}
137-
else
157+
if ( reshapeDone )
158+
{
159+
vlayer->endEditCommand();
160+
}
161+
else
162+
{
163+
vlayer->destroyEditCommand();
164+
}
165+
}
166+
167+
bool QgsMapToolReshape::isBindingLine( QgsVectorLayer *vlayer, const QgsRectangle &bbox ) const
168+
{
169+
if ( vlayer->geometryType() != QGis::Line )
170+
return false;
171+
172+
bool begin = false;
173+
bool end = false;
174+
const QgsPoint beginPoint = points().first();
175+
const QgsPoint endPoint = points().last();
176+
177+
QgsFeatureIterator fit = vlayer->getFeatures( QgsFeatureRequest().setFilterRect( bbox ).setSubsetOfAttributes( QgsAttributeList() ) );
178+
QgsFeature f;
179+
180+
// check that extremities of the new line are contained by features
181+
while ( fit.nextFeature( f ) )
182+
{
183+
const QgsGeometry *geom = f.geometry();
184+
if ( geom )
138185
{
139-
vlayer->destroyEditCommand();
140-
}
186+
const QgsPolyline line = geom->asPolyline();
141187

142-
stopCapturing();
188+
if ( line.contains( beginPoint ) )
189+
begin = true;
190+
else if ( line.contains( endPoint ) )
191+
end = true;
192+
}
143193
}
194+
195+
return end && begin;
144196
}

‎src/app/qgsmaptoolreshape.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@ class APP_EXPORT QgsMapToolReshape: public QgsMapToolCapture
2828
QgsMapToolReshape( QgsMapCanvas* canvas );
2929
virtual ~QgsMapToolReshape();
3030
void cadCanvasReleaseEvent( QgsMapMouseEvent * e ) override;
31+
32+
private:
33+
void reshape( QgsVectorLayer *vlayer );
34+
35+
bool isBindingLine( QgsVectorLayer *vlayer, const QgsRectangle &bbox ) const;
3136
};
3237

3338
#endif

‎src/gui/qgsmaptoolcapture.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -713,7 +713,7 @@ int QgsMapToolCapture::size()
713713
return mCaptureCurve.numPoints();
714714
}
715715

716-
QList<QgsPoint> QgsMapToolCapture::points()
716+
QList<QgsPoint> QgsMapToolCapture::points() const
717717
{
718718
QgsPointSequenceV2 pts;
719719
QList<QgsPoint> points;

‎src/gui/qgsmaptoolcapture.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ class GUI_EXPORT QgsMapToolCapture : public QgsMapToolAdvancedDigitizing
192192
* List of digitized points
193193
* @return List of points
194194
*/
195-
QList<QgsPoint> points();
195+
QList<QgsPoint> points() const;
196196

197197
/**
198198
* List of digitized points with z support

0 commit comments

Comments
 (0)
Please sign in to comment.