Skip to content
Permalink
Browse files
Offset curve tool: convert multiline features in both directions
  • Loading branch information
mhugent committed Feb 23, 2012
1 parent df25981 commit 44554e159daed0a2ccecbf2cd7ff1ebe7591e80d
Showing with 58 additions and 5 deletions.
  1. +53 −5 src/app/qgsmaptooloffsetcurve.cpp
  2. +5 −0 src/app/qgsmaptooloffsetcurve.h
@@ -25,7 +25,7 @@
#include "qgisapp.h"

QgsMapToolOffsetCurve::QgsMapToolOffsetCurve( QgsMapCanvas* canvas ): QgsMapToolEdit( canvas ), mRubberBand( 0 ),
mOriginalGeometry( 0 ), mGeometryModified( false ), mDistanceItem( 0 ), mDistanceSpinBox( 0 ), mSnapVertexMarker( 0 ), mForceCopy( false )
mOriginalGeometry( 0 ), mGeometryModified( false ), mDistanceItem( 0 ), mDistanceSpinBox( 0 ), mSnapVertexMarker( 0 ), mForceCopy( false ), mMultiPartGeometry( false )
{
}

@@ -90,6 +90,11 @@ void QgsMapToolOffsetCurve::canvasReleaseEvent( QMouseEvent * e )
return;
}

if ( mMultiPartGeometry )
{
mModifiedGeometry.convertToMultiType();
}

vlayer->beginEditCommand( tr( "Offset curve" ) );

bool editOk;
@@ -218,27 +223,30 @@ QgsGeometry* QgsMapToolOffsetCurve::createOriginGeometry( QgsVectorLayer* vl, co
{
return 0;
}
mMultiPartGeometry = false;
//assign feature part by vertex number (snap to vertex) or by before vertex number (snap to segment)
int partVertexNr = ( sr.snappedVertexNr == -1 ? sr.beforeVertexNr : sr.snappedVertexNr );

if ( vl == currentVectorLayer() && !mForceCopy )
{
//don't consider selected geometries, only the snap result
return snappedFeature.geometryAndOwnership();
return convertToSingleLine( snappedFeature.geometryAndOwnership(), partVertexNr, mMultiPartGeometry );
}
else //snapped to a background layer
{
//if source layer is polygon / multipolygon, create a linestring from the snapped ring
if ( vl->geometryType() == QGis::Polygon )
{
//make linestring from polygon ring and return this geometry
return linestringFromPolygon( snappedFeature.geometry(), sr.snappedVertexNr );
return linestringFromPolygon( snappedFeature.geometry(), partVertexNr );
}


//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();
return convertToSingleLine( snappedFeature.geometryAndOwnership(), partVertexNr, mMultiPartGeometry );
}
else
{
@@ -256,7 +264,7 @@ QgsGeometry* QgsMapToolOffsetCurve::createOriginGeometry( QgsVectorLayer* vl, co
if ( geom->isMultipart() )
{
delete geom;
return snappedFeature.geometryAndOwnership();
return convertToSingleLine( snappedFeature.geometryAndOwnership(), sr.snappedVertexNr, mMultiPartGeometry );
}

return geom;
@@ -416,3 +424,43 @@ void QgsMapToolOffsetCurve::configureSnapper( QgsSnapper& s )
s.setSnapLayers( snapLayers );
s.setSnapMode( QgsSnapper::SnapWithOneResult );
}

QgsGeometry* QgsMapToolOffsetCurve::convertToSingleLine( QgsGeometry* geom, int vertex, bool& isMulti )
{
if ( !geom )
{
return 0;
}

isMulti = false;
QGis::WkbType geomType = geom->wkbType();
if ( geomType == QGis::WKBLineString || geomType == QGis::WKBLineString25D )
{
return geom;
}
else if ( geomType == QGis::WKBMultiLineString || geomType == QGis::WKBMultiLineString25D )
{
//search vertex
isMulti = true;
int currentVertex = 0;
QgsMultiPolyline multiLine = geom->asMultiPolyline();
QgsMultiPolyline::const_iterator it = multiLine.constBegin();
for ( ; it != multiLine.constEnd(); ++it )
{
currentVertex += it->size();
if ( vertex < currentVertex )
{
QgsGeometry* g = QgsGeometry::fromPolyline( *it );
delete geom;
return g;
}
}
}
delete geom;
return 0;
}

QgsGeometry* QgsMapToolOffsetCurve::convertToMultiLine( QgsGeometry* geom )
{
return 0;
}
@@ -61,6 +61,7 @@ class QgsMapToolOffsetCurve: public QgsMapToolEdit
QgsVertexMarker* mSnapVertexMarker;
/**Forces geometry copy (no modification of geometry in current layer)*/
bool mForceCopy;
bool mMultiPartGeometry;


void deleteRubberBandAndGeometry();
@@ -72,6 +73,10 @@ class QgsMapToolOffsetCurve: public QgsMapToolEdit
QgsGeometry* linestringFromPolygon( QgsGeometry* featureGeom, int vertex );
/**Sets snapping with default vertex search tolerance to all layers (to vertex and segment)*/
void configureSnapper( QgsSnapper& s );
/**Returns a single line from a multiline (or does nothing if geometry is already a single line). Deletes the input geometry*/
QgsGeometry* convertToSingleLine( QgsGeometry* geom, int vertex, bool& isMulti );
/**Converts offset line back to a multiline if necessary*/
QgsGeometry* convertToMultiLine( QgsGeometry* geom );
};

#endif // QGSMAPTOOLOFFSETCURVE_H

0 comments on commit 44554e1

Please sign in to comment.