Skip to content

Commit 112b9f1

Browse files
committed
In case of offset curve on background layers: try to merge together the source layers
1 parent 313e0ed commit 112b9f1

File tree

3 files changed

+78
-21
lines changed

3 files changed

+78
-21
lines changed

src/app/qgsmaptooloffsetcurve.cpp

Lines changed: 72 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
#include "qgsmaptooloffsetcurve.h"
1717
#include "qgsmapcanvas.h"
18+
#include "qgsmaplayerregistry.h"
1819
#include "qgsrubberband.h"
1920
#include "qgsvectorlayer.h"
2021
#include <QMouseEvent>
@@ -40,26 +41,21 @@ void QgsMapToolOffsetCurve::canvasPressEvent( QMouseEvent * e )
4041
return;
4142
}
4243

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 )
4548
{
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 )
5852
{
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 ) )
6157
{
62-
mOriginalGeometry = fet.geometryAndOwnership();
58+
mOriginalGeometry = createOriginGeometry( vl, snapResult, fet );
6359
mRubberBand = createRubberBand();
6460
mRubberBand->setToGeometry( mOriginalGeometry, layer );
6561
mModifiedFeature = fet.id();
@@ -78,7 +74,20 @@ void QgsMapToolOffsetCurve::canvasReleaseEvent( QMouseEvent * e )
7874
}
7975

8076
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 )
8291
{
8392
vlayer->endEditCommand();
8493
}
@@ -113,7 +122,7 @@ void QgsMapToolOffsetCurve::canvasMoveEvent( QMouseEvent * e )
113122
int beforeVertex;
114123
double leftOf;
115124
double offset = sqrt( mOriginalGeometry->closestSegmentWithContext( layerCoords, minDistPoint, beforeVertex, &leftOf ) );
116-
qWarning( QString::number( offset ).toLocal8Bit().data() );
125+
//qWarning( QString::number( offset ).toLocal8Bit().data() );
117126

118127
//create offset geometry using geos
119128
QgsGeometry geomCopy( *mOriginalGeometry );
@@ -129,6 +138,50 @@ void QgsMapToolOffsetCurve::canvasMoveEvent( QMouseEvent * e )
129138
}
130139
}
131140

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+
132185
void QgsMapToolOffsetCurve::deleteRubberBandAndGeometry()
133186
{
134187
delete mRubberBand;

src/app/qgsmaptooloffsetcurve.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
#include "qgsmaptooledit.h"
2020
#include "qgsgeometry.h"
21+
#include "qgssnapper.h"
2122

2223
class QgsMapToolOffsetCurve: public QgsMapToolEdit
2324
{
@@ -39,10 +40,14 @@ class QgsMapToolOffsetCurve: public QgsMapToolEdit
3940
QgsGeometry mModifiedGeometry;
4041
/**ID of manipulated feature*/
4142
QgsFeatureId mModifiedFeature;
43+
/**Layer ID of source layer*/
44+
QString mSourceLayerId;
4245
/**Internal flag to distinguish move from click*/
4346
bool mGeometryModified;
4447

48+
4549
void deleteRubberBandAndGeometry();
50+
QgsGeometry* createOriginGeometry( QgsVectorLayer* vl, const QgsSnappingResult& sr, QgsFeature& snappedFeature );
4651
};
4752

4853
#endif // QGSMAPTOOLOFFSETCURVE_H

src/core/qgsgeometry.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6158,8 +6158,7 @@ QgsGeometry* QgsGeometry::combine( QgsGeometry* geometry )
61586158
GEOSGeometry* unionGeom = GEOSUnion( mGeos, geometry->mGeos );
61596159
QGis::WkbType thisGeomType = wkbType();
61606160
QGis::WkbType otherGeomType = geometry->wkbType();
6161-
if (( thisGeomType == QGis::WKBLineString || thisGeomType == QGis::WKBLineString25D )
6162-
&& ( otherGeomType == QGis::WKBLineString || otherGeomType == QGis::WKBLineString25D ) )
6161+
if ( type() == QGis::Line )
61636162
{
61646163
GEOSGeometry* mergedGeom = GEOSLineMerge( unionGeom );
61656164
if ( mergedGeom )

0 commit comments

Comments
 (0)