Skip to content
Permalink
Browse files
In case of offset curve on background layers: try to merge together t…
…he source layers
  • Loading branch information
mhugent committed Feb 17, 2012
1 parent 313e0ed commit 112b9f1fd0706faa5f343e1b161d00344774625e
Showing with 78 additions and 21 deletions.
  1. +72 −19 src/app/qgsmaptooloffsetcurve.cpp
  2. +5 −0 src/app/qgsmaptooloffsetcurve.h
  3. +1 −2 src/core/qgsgeometry.cpp
@@ -15,6 +15,7 @@

#include "qgsmaptooloffsetcurve.h"
#include "qgsmapcanvas.h"
#include "qgsmaplayerregistry.h"
#include "qgsrubberband.h"
#include "qgsvectorlayer.h"
#include <QMouseEvent>
@@ -40,26 +41,21 @@ void QgsMapToolOffsetCurve::canvasPressEvent( QMouseEvent * e )
return;
}

QgsFeatureList selectedFeatures = layer->selectedFeatures();
if ( selectedFeatures.size() > 0 )
QList<QgsSnappingResult> snapResults;
QgsMapCanvasSnapper snapper( mCanvas );
snapper.snapToBackgroundLayers( e->pos(), snapResults );
if ( snapResults.size() > 0 )
{
//take the first selected feature
mOriginalGeometry = selectedFeatures[0].geometryAndOwnership();
mRubberBand = createRubberBand();
mRubberBand->setToGeometry( mOriginalGeometry, layer );
mModifiedFeature = selectedFeatures[0].id();
}
else //do a snap to the closest feature
{
QList<QgsSnappingResult> snapResults;
QgsMapCanvasSnapper snapper( mCanvas );
snapper.snapToCurrentLayer( e->pos(), snapResults, QgsSnapper::SnapToSegment );
if ( snapResults.size() > 0 )
QgsFeature fet;
const QgsSnappingResult& snapResult = snapResults.at( 0 );
if ( snapResult.layer )
{
QgsFeature fet;
if ( layer->featureAtId( snapResults.at( 0 ).snappedAtGeometry, fet ) )
mSourceLayerId = snapResult.layer->id();

QgsVectorLayer* vl = dynamic_cast<QgsVectorLayer*>( QgsMapLayerRegistry::instance()->mapLayer( mSourceLayerId ) );
if ( vl && vl->featureAtId( snapResult.snappedAtGeometry, fet ) )
{
mOriginalGeometry = fet.geometryAndOwnership();
mOriginalGeometry = createOriginGeometry( vl, snapResult, fet );
mRubberBand = createRubberBand();
mRubberBand->setToGeometry( mOriginalGeometry, layer );
mModifiedFeature = fet.id();
@@ -78,7 +74,20 @@ void QgsMapToolOffsetCurve::canvasReleaseEvent( QMouseEvent * e )
}

vlayer->beginEditCommand( tr( "Offset curve" ) );
if ( vlayer->changeGeometry( mModifiedFeature, &mModifiedGeometry ) )

bool editOk;
if ( mSourceLayerId == vlayer->id() )
{
editOk = vlayer->changeGeometry( mModifiedFeature, &mModifiedGeometry );
}
else
{
QgsFeature f;
f.setGeometry( mModifiedGeometry );
editOk = vlayer->addFeature( f );
}

if ( editOk )
{
vlayer->endEditCommand();
}
@@ -113,7 +122,7 @@ void QgsMapToolOffsetCurve::canvasMoveEvent( QMouseEvent * e )
int beforeVertex;
double leftOf;
double offset = sqrt( mOriginalGeometry->closestSegmentWithContext( layerCoords, minDistPoint, beforeVertex, &leftOf ) );
qWarning( QString::number( offset ).toLocal8Bit().data() );
//qWarning( QString::number( offset ).toLocal8Bit().data() );

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

QgsGeometry* QgsMapToolOffsetCurve::createOriginGeometry( QgsVectorLayer* vl, const QgsSnappingResult& sr, QgsFeature& snappedFeature )
{
if ( !vl )
{
return 0;
}

if ( vl == currentVectorLayer() )
{
//don't consider selected geometries, only the snap result
return snappedFeature.geometryAndOwnership();
}
else
{
//for background layers, try to merge selected entries together if snapped feature is contained in selection
const QgsFeatureIds& selection = vl->selectedFeaturesIds();
if ( selection.size() < 1 || !selection.contains( sr.snappedAtGeometry ) )
{
return snappedFeature.geometryAndOwnership();
}
else
{
//merge together if several features
QgsFeatureList selectedFeatures = vl->selectedFeatures();
QgsFeatureList::iterator selIt = selectedFeatures.begin();
QgsGeometry* geom = selIt->geometryAndOwnership();
++selIt;
for ( ; selIt != selectedFeatures.end(); ++selIt )
{
geom = geom->combine( selIt->geometry() );
}

//if multitype, return only the snaped to geometry
if ( geom->isMultipart() )
{
delete geom;
return snappedFeature.geometryAndOwnership();
}

return geom;
}
}
}

void QgsMapToolOffsetCurve::deleteRubberBandAndGeometry()
{
delete mRubberBand;
@@ -18,6 +18,7 @@

#include "qgsmaptooledit.h"
#include "qgsgeometry.h"
#include "qgssnapper.h"

class QgsMapToolOffsetCurve: public QgsMapToolEdit
{
@@ -39,10 +40,14 @@ class QgsMapToolOffsetCurve: public QgsMapToolEdit
QgsGeometry mModifiedGeometry;
/**ID of manipulated feature*/
QgsFeatureId mModifiedFeature;
/**Layer ID of source layer*/
QString mSourceLayerId;
/**Internal flag to distinguish move from click*/
bool mGeometryModified;


void deleteRubberBandAndGeometry();
QgsGeometry* createOriginGeometry( QgsVectorLayer* vl, const QgsSnappingResult& sr, QgsFeature& snappedFeature );
};

#endif // QGSMAPTOOLOFFSETCURVE_H
@@ -6158,8 +6158,7 @@ QgsGeometry* QgsGeometry::combine( QgsGeometry* geometry )
GEOSGeometry* unionGeom = GEOSUnion( mGeos, geometry->mGeos );
QGis::WkbType thisGeomType = wkbType();
QGis::WkbType otherGeomType = geometry->wkbType();
if (( thisGeomType == QGis::WKBLineString || thisGeomType == QGis::WKBLineString25D )
&& ( otherGeomType == QGis::WKBLineString || otherGeomType == QGis::WKBLineString25D ) )
if ( type() == QGis::Line )
{
GEOSGeometry* mergedGeom = GEOSLineMerge( unionGeom );
if ( mergedGeom )

0 comments on commit 112b9f1

Please sign in to comment.