Skip to content
Permalink
Browse files

[FEATURE]: Tool to add circular strings with start point, curve point…

… and end point
  • Loading branch information
mhugent committed Aug 17, 2015
1 parent 9b31f34 commit c39ffe9fc20035d69035515bcd0f3362722fe880
Showing with 308 additions and 118 deletions.
  1. +1 −0 images/images.qrc
  2. +1 −1 python/core/geometry/qgsabstractgeometryv2.sip
  3. +1 −1 python/core/geometry/qgscircularstringv2.sip
  4. +1 −1 python/core/geometry/qgscompoundcurvev2.sip
  5. +1 −1 python/core/geometry/qgscurvepolygonv2.sip
  6. +1 −1 python/core/geometry/qgsgeometrycollectionv2.sip
  7. +1 −1 python/core/geometry/qgslinestringv2.sip
  8. +3 −0 src/app/CMakeLists.txt
  9. +10 −0 src/app/qgisapp.cpp
  10. +3 −0 src/app/qgisapp.h
  11. +30 −37 src/app/qgsmaptooladdfeature.cpp
  12. +41 −19 src/app/qgsmaptooladdpart.cpp
  13. +19 −1 src/app/qgsmaptooladdring.cpp
  14. +15 −7 src/app/qgsmaptoolcapture.cpp
  15. +6 −3 src/app/qgsmaptoolcapture.h
  16. +16 −0 src/app/qgsmaptooledit.cpp
  17. +4 −0 src/app/qgsmaptooledit.h
  18. +2 −1 src/core/geometry/qgsabstractgeometryv2.h
  19. +2 −2 src/core/geometry/qgscircularstringv2.cpp
  20. +1 −1 src/core/geometry/qgscircularstringv2.h
  21. +2 −2 src/core/geometry/qgscompoundcurvev2.cpp
  22. +1 −1 src/core/geometry/qgscompoundcurvev2.h
  23. +3 −3 src/core/geometry/qgscurvepolygonv2.cpp
  24. +1 −1 src/core/geometry/qgscurvepolygonv2.h
  25. +2 −2 src/core/geometry/qgsgeometrycollectionv2.cpp
  26. +1 −1 src/core/geometry/qgsgeometrycollectionv2.h
  27. +2 −2 src/core/geometry/qgslinestringv2.cpp
  28. +1 −1 src/core/geometry/qgslinestringv2.h
  29. +2 −2 src/core/geometry/qgspointv2.cpp
  30. +1 −1 src/core/geometry/qgspointv2.h
  31. +3 −1 src/core/qgsvectordataprovider.h
  32. +49 −6 src/core/qgsvectorlayer.cpp
  33. +11 −0 src/core/qgsvectorlayer.h
  34. +40 −17 src/core/qgsvectorlayereditutils.cpp
  35. +13 −0 src/core/qgsvectorlayereditutils.h
  36. +3 −0 src/providers/postgres/qgspostgresprovider.cpp
  37. +14 −1 src/ui/qgisapp.ui
@@ -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>
@@ -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;
@@ -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;
@@ -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;
@@ -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 );
@@ -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;
@@ -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;
@@ -117,6 +117,8 @@ SET(QGIS_APP_SRCS
qgsvectorlayerproperties.cpp
qgsvisibilitypresets.cpp
qgshandlebadlayers.cpp
qgsmaptooladdcircularstring.cpp
qgsmaptoolcircularstringcurvepoint.cpp

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

nodetool/qgsmaptoolnodetool.h
nodetool/qgsselectedfeature.h
@@ -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"
@@ -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() ) );

@@ -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) && \
@@ -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 );
@@ -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 );
@@ -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
@@ -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;
@@ -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"
@@ -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 )
@@ -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"

@@ -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;
@@ -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"


@@ -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;

0 comments on commit c39ffe9

Please sign in to comment.
You can’t perform that action at this time.