Skip to content

Commit

Permalink
[FEATURE]: Tool to add circular strings with start point, curve point…
Browse files Browse the repository at this point in the history
… and end point
  • Loading branch information
mhugent committed Aug 17, 2015
1 parent 9b31f34 commit c39ffe9
Show file tree
Hide file tree
Showing 37 changed files with 308 additions and 118 deletions.
1 change: 1 addition & 0 deletions images/images.qrc
Expand Up @@ -504,6 +504,7 @@
<file>themes/default/mIconClear.png</file>
<file>flags/zh.png</file>
<file>themes/default/mIconPaintEffects.svg</file>
<file>themes/default/mActionCircularStringCurvePoint.png</file>
</qresource>
<qresource prefix="/images/tips">
<file alias="symbol_levels.png">qgis_tips/symbol_levels.png</file>
Expand Down
2 changes: 1 addition & 1 deletion python/core/geometry/qgsabstractgeometryv2.sip
Expand Up @@ -90,7 +90,7 @@ class QgsAbstractGeometryV2
virtual QgsRectangle calculateBoundingBox() const;

//render pipeline
virtual void transform( const QgsCoordinateTransform& ct ) = 0;
virtual void transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d = QgsCoordinateTransform::ForwardTransform ) = 0;
virtual void transform( const QTransform& t ) = 0;
//virtual void clip( const QgsRectangle& rect );
virtual void draw( QPainter& p ) const = 0;
Expand Down
2 changes: 1 addition & 1 deletion python/core/geometry/qgscircularstringv2.sip
Expand Up @@ -38,7 +38,7 @@ class QgsCircularStringV2: public QgsCurveV2
virtual QgsLineStringV2* curveToLine() const;

void draw( QPainter& p ) const;
void transform( const QgsCoordinateTransform& ct );
void transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d = QgsCoordinateTransform::ForwardTransform );
void transform( const QTransform& t );
//void clip( const QgsRectangle& rect );
void addToPainterPath( QPainterPath& path ) const;
Expand Down
2 changes: 1 addition & 1 deletion python/core/geometry/qgscompoundcurvev2.sip
Expand Up @@ -45,7 +45,7 @@ class QgsCompoundCurveV2: public QgsCurveV2
void close();

void draw( QPainter& p ) const;
void transform( const QgsCoordinateTransform& ct );
void transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d = QgsCoordinateTransform::ForwardTransform );
void transform( const QTransform& t );
void addToPainterPath( QPainterPath& path ) const;
void drawAsPolygon( QPainter& p ) const;
Expand Down
2 changes: 1 addition & 1 deletion python/core/geometry/qgscurvepolygonv2.sip
Expand Up @@ -49,7 +49,7 @@ class QgsCurvePolygonV2: public QgsSurfaceV2
bool removeInteriorRing( int nr );

virtual void draw( QPainter& p ) const;
void transform( const QgsCoordinateTransform& ct );
void transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d = QgsCoordinateTransform::ForwardTransform );
void transform( const QTransform& t );

virtual bool insertVertex( const QgsVertexId& position, const QgsPointV2& vertex );
Expand Down
2 changes: 1 addition & 1 deletion python/core/geometry/qgsgeometrycollectionv2.sip
Expand Up @@ -23,7 +23,7 @@ class QgsGeometryCollectionV2: public QgsAbstractGeometryV2
virtual bool addGeometry( QgsAbstractGeometryV2* g /Transfer/ );
virtual bool removeGeometry( int nr );

virtual void transform( const QgsCoordinateTransform& ct );
virtual void transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d = QgsCoordinateTransform::ForwardTransform );
void transform( const QTransform& t );
//virtual void clip( const QgsRectangle& rect );
virtual void draw( QPainter& p ) const;
Expand Down
2 changes: 1 addition & 1 deletion python/core/geometry/qgslinestringv2.sip
Expand Up @@ -38,7 +38,7 @@ class QgsLineStringV2: public QgsCurveV2
void append( const QgsLineStringV2* line );

void draw( QPainter& p ) const;
void transform( const QgsCoordinateTransform& ct );
void transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d = QgsCoordinateTransform::ForwardTransform );
void transform( const QTransform& t );

void addToPainterPath( QPainterPath& path ) const;
Expand Down
3 changes: 3 additions & 0 deletions src/app/CMakeLists.txt
Expand Up @@ -117,6 +117,8 @@ SET(QGIS_APP_SRCS
qgsvectorlayerproperties.cpp
qgsvisibilitypresets.cpp
qgshandlebadlayers.cpp
qgsmaptooladdcircularstring.cpp
qgsmaptoolcircularstringcurvepoint.cpp

composer/qgsattributeselectiondialog.cpp
composer/qgscomposer.cpp
Expand Down Expand Up @@ -240,6 +242,7 @@ SET (QGIS_APP_MOC_HDRS
qgsmaptoolsimplify.h
qgsmaptoolsplitfeatures.h
qgsmaptoolsplitparts.h
qgsmaptooladdcircularstring.h

nodetool/qgsmaptoolnodetool.h
nodetool/qgsselectedfeature.h
Expand Down
10 changes: 10 additions & 0 deletions src/app/qgisapp.cpp
Expand Up @@ -250,6 +250,7 @@
#include "qgsmaptooladdring.h"
#include "qgsmaptoolfillring.h"
#include "qgsmaptoolannotation.h"
#include "qgsmaptoolcircularstringcurvepoint.h"
#include "qgsmaptooldeletering.h"
#include "qgsmaptooldeletepart.h"
#include "qgsmaptoolfeatureaction.h"
Expand Down Expand Up @@ -1170,6 +1171,7 @@ void QgisApp::createActions()
connect( mActionCopyStyle, SIGNAL( triggered() ), this, SLOT( copyStyle() ) );
connect( mActionPasteStyle, SIGNAL( triggered() ), this, SLOT( pasteStyle() ) );
connect( mActionAddFeature, SIGNAL( triggered() ), this, SLOT( addFeature() ) );
connect( mActionCircularStringCurvePoint, SIGNAL( triggered() ), this, SLOT( circularStringCurvePoint() ) );
connect( mActionMoveFeature, SIGNAL( triggered() ), this, SLOT( moveFeature() ) );
connect( mActionRotateFeature, SIGNAL( triggered() ), this, SLOT( rotateFeature() ) );

Expand Down Expand Up @@ -1444,6 +1446,7 @@ void QgisApp::createActionGroups()
mMapToolGroup->addAction( mActionMeasureArea );
mMapToolGroup->addAction( mActionMeasureAngle );
mMapToolGroup->addAction( mActionAddFeature );
mMapToolGroup->addAction( mActionCircularStringCurvePoint );
mMapToolGroup->addAction( mActionMoveFeature );
mMapToolGroup->addAction( mActionRotateFeature );
#if defined(GEOS_VERSION_MAJOR) && defined(GEOS_VERSION_MINOR) && \
Expand Down Expand Up @@ -2293,6 +2296,8 @@ void QgisApp::createCanvasTools()
mMapTools.mAnnotation->setAction( mActionAnnotation );
mMapTools.mAddFeature = new QgsMapToolAddFeature( mMapCanvas );
mMapTools.mAddFeature->setAction( mActionAddFeature );
mMapTools.mCircularStringCurvePoint = new QgsMapToolCircularStringCurvePoint( dynamic_cast<QgsMapToolAddFeature*>( mMapTools.mAddFeature ), mMapCanvas );
mMapTools.mCircularStringCurvePoint->setAction( mActionCircularStringCurvePoint );
mMapTools.mMoveFeature = new QgsMapToolMoveFeature( mMapCanvas );
mMapTools.mMoveFeature->setAction( mActionMoveFeature );
mMapTools.mRotateFeature = new QgsMapToolRotateFeature( mMapCanvas );
Expand Down Expand Up @@ -6159,6 +6164,11 @@ void QgisApp::addFeature()
mMapCanvas->setMapTool( mMapTools.mAddFeature );
}

void QgisApp::circularStringCurvePoint()
{
mMapCanvas->setMapTool( mMapTools.mCircularStringCurvePoint );
}

void QgisApp::selectFeatures()
{
mMapCanvas->setMapTool( mMapTools.mSelectFeatures );
Expand Down
3 changes: 3 additions & 0 deletions src/app/qgisapp.h
Expand Up @@ -966,6 +966,8 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
void newBookmark();
//! activates the add feature tool
void addFeature();
//! activates the add circular string tool
void circularStringCurvePoint();
//! activates the move feature tool
void moveFeature();
//! activates the offset curve tool
Expand Down Expand Up @@ -1471,6 +1473,7 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
QgsMapTool *mMeasureArea;
QgsMapTool *mMeasureAngle;
QgsMapTool *mAddFeature;
QgsMapTool *mCircularStringCurvePoint;
QgsMapTool *mMoveFeature;
QgsMapTool *mOffsetCurve;
QgsMapTool *mReshapeFeatures;
Expand Down
67 changes: 30 additions & 37 deletions src/app/qgsmaptooladdfeature.cpp
Expand Up @@ -17,11 +17,14 @@
#include "qgsapplication.h"
#include "qgsattributedialog.h"
#include "qgscsexception.h"
#include "qgscurvepolygonv2.h"
#include "qgsfield.h"
#include "qgsgeometry.h"
#include "qgslinestringv2.h"
#include "qgsmapcanvas.h"
#include "qgsmaplayerregistry.h"
#include "qgsmapmouseevent.h"
#include "qgspolygonv2.h"
#include "qgsproject.h"
#include "qgsvectordataprovider.h"
#include "qgsvectorlayer.h"
Expand Down Expand Up @@ -199,56 +202,46 @@ void QgsMapToolAddFeature::canvasMapReleaseEvent( QgsMapMouseEvent* e )
return;
}

if ( mode() == CapturePolygon )
{
closePolygon();
}

//create QgsFeature with wkb representation
QgsFeature* f = new QgsFeature( vlayer->fields(), 0 );

QgsGeometry *g;
//does compoundcurve contain circular strings?
//does provider support circular strings?
bool hasCurvedSegments = captureCurve()->hasCurvedSegments();
bool providerSupportsCurvedSegments = vlayer->dataProvider()->capabilities() & QgsVectorDataProvider::CircularGeometries;

if ( mode() == CaptureLine )
QgsCurveV2* curveToAdd = 0;
if ( hasCurvedSegments && providerSupportsCurvedSegments )
{
if ( layerWKBType == QGis::WKBLineString || layerWKBType == QGis::WKBLineString25D )
{
g = QgsGeometry::fromPolyline( points().toVector() );
}
else if ( layerWKBType == QGis::WKBMultiLineString || layerWKBType == QGis::WKBMultiLineString25D )
{
g = QgsGeometry::fromMultiPolyline( QgsMultiPolyline() << points().toVector() );
}
else
{
emit messageEmitted( tr( "Cannot add feature. Unknown WKB type" ), QgsMessageBar::CRITICAL );
stopCapturing();
delete f;
return; //unknown wkbtype
}
curveToAdd = dynamic_cast<QgsCurveV2*>( captureCurve()->clone() );
}
else
{
curveToAdd = captureCurve()->curveToLine();
}

f->setGeometry( g );
if ( mode() == CaptureLine )
{
f->setGeometry( new QgsGeometry( curveToAdd ) );
}
else // polygon
else
{
if ( layerWKBType == QGis::WKBPolygon || layerWKBType == QGis::WKBPolygon25D )
QgsCurvePolygonV2* poly = 0;
if ( hasCurvedSegments && providerSupportsCurvedSegments )
{
g = QgsGeometry::fromPolygon( QgsPolygon() << points().toVector() );
}
else if ( layerWKBType == QGis::WKBMultiPolygon || layerWKBType == QGis::WKBMultiPolygon25D )
{
g = QgsGeometry::fromMultiPolygon( QgsMultiPolygon() << ( QgsPolygon() << points().toVector() ) );
poly = new QgsCurvePolygonV2();
}
else
{
emit messageEmitted( tr( "Cannot add feature. Unknown WKB type" ), QgsMessageBar::CRITICAL );
stopCapturing();
delete f;
return; //unknown wkbtype
}

if ( !g )
{
stopCapturing();
delete f;
return; // invalid geometry; one possibility is from duplicate points
poly = new QgsPolygonV2();
}
f->setGeometry( g );
poly->setExteriorRing( curveToAdd );
f->setGeometry( poly );

int avoidIntersectionsReturn = f->geometry()->avoidIntersections();
if ( avoidIntersectionsReturn == 1 )
Expand Down
60 changes: 41 additions & 19 deletions src/app/qgsmaptooladdpart.cpp
Expand Up @@ -14,9 +14,12 @@
***************************************************************************/

#include "qgsmaptooladdpart.h"
#include "qgscurvepolygonv2.h"
#include "qgsgeometry.h"
#include "qgslinestringv2.h"
#include "qgsmapcanvas.h"
#include "qgsproject.h"
#include "qgsvectordataprovider.h"
#include "qgsvectorlayer.h"
#include "qgslogger.h"

Expand Down Expand Up @@ -118,33 +121,52 @@ void QgsMapToolAddPart::canvasMapReleaseEvent( QgsMapMouseEvent * e )
if ( !isCapturing() )
return;

// we are now going to finish the capturing

if ( mode() == CapturePolygon )
{
//close polygon
closePolygon();
}

//does compoundcurve contain circular strings?
//does provider support circular strings?
bool hasCurvedSegments = captureCurve()->hasCurvedSegments();
bool providerSupportsCurvedSegments = vlayer->dataProvider()->capabilities() & QgsVectorDataProvider::CircularGeometries;

QgsCurveV2* curveToAdd = 0;
if ( hasCurvedSegments && providerSupportsCurvedSegments )
{
curveToAdd = dynamic_cast<QgsCurveV2*>( captureCurve()->clone() );
}
else
{
curveToAdd = captureCurve()->curveToLine();
}

vlayer->beginEditCommand( tr( "Part added" ) );
int errorCode = 0;
if ( mode() == CapturePolygon )
{
//avoid intersections
QgsGeometry* geom = QgsGeometry::fromPolygon( QgsPolygon() << points().toVector() );
if ( geom )
QgsCurvePolygonV2* cp = new QgsCurvePolygonV2();
cp->setExteriorRing( curveToAdd );
QgsGeometry* geom = new QgsGeometry( cp );
geom->avoidIntersections();

const QgsCurvePolygonV2* cpGeom = dynamic_cast<const QgsCurvePolygonV2*>( geom->geometry() );
if ( !cpGeom )
{
geom->avoidIntersections();
QgsPolygon poly = geom->asPolygon();
if ( poly.size() < 1 )
{
stopCapturing();
delete geom;
vlayer->destroyEditCommand();
return;
}
setPoints( geom->asPolygon()[0].toList() );
stopCapturing();
delete geom;
vlayer->destroyEditCommand();
return;
}
}

vlayer->beginEditCommand( tr( "Part added" ) );
errorCode = vlayer->addPart( points() );

errorCode = vlayer->addPart( dynamic_cast<QgsCurveV2*>( cpGeom->exteriorRing()->clone() ) );
delete geom;
}
else
{
errorCode = vlayer->addPart( curveToAdd );
}
stopCapturing();
}
break;
Expand Down
20 changes: 19 additions & 1 deletion src/app/qgsmaptooladdring.cpp
Expand Up @@ -17,8 +17,10 @@

#include "qgsmaptooladdring.h"
#include "qgsgeometry.h"
#include "qgslinestringv2.h"
#include "qgsmapcanvas.h"
#include "qgsproject.h"
#include "qgsvectordataprovider.h"
#include "qgsvectorlayer.h"


Expand Down Expand Up @@ -80,7 +82,23 @@ void QgsMapToolAddRing::canvasMapReleaseEvent( QgsMapMouseEvent * e )
closePolygon();

vlayer->beginEditCommand( tr( "Ring added" ) );
int addRingReturnCode = vlayer->addRing( points() );

//does compoundcurve contain circular strings?
//does provider support circular strings?
bool hasCurvedSegments = captureCurve()->hasCurvedSegments();
bool providerSupportsCurvedSegments = vlayer->dataProvider()->capabilities() & QgsVectorDataProvider::CircularGeometries;

QgsCurveV2* curveToAdd = 0;
if ( hasCurvedSegments && providerSupportsCurvedSegments )
{
curveToAdd = dynamic_cast<QgsCurveV2*>( captureCurve()->clone() );
}
else
{
curveToAdd = captureCurve()->curveToLine();
}

int addRingReturnCode = vlayer->addRing( curveToAdd );
if ( addRingReturnCode != 0 )
{
QString errorMessage;
Expand Down

0 comments on commit c39ffe9

Please sign in to comment.