Skip to content
Permalink
Browse files

Merge pull request #2268 from mhugent/curve_capture_tool

Curve capture tool
  • Loading branch information
mhugent committed Aug 24, 2015
2 parents 2c4f02a + ed69f1c commit 5807875797f2fe03c75ba771b8ba2a58f188efb3
Showing with 1,027 additions and 125 deletions.
  1. +2 −0 images/images.qrc
  2. BIN images/themes/default/mActionCircularStringCurvePoint.png
  3. BIN images/themes/default/mActionCircularStringRadius.png
  4. +1 −1 python/core/geometry/qgsabstractgeometryv2.sip
  5. +1 −1 python/core/geometry/qgscircularstringv2.sip
  6. +1 −1 python/core/geometry/qgscompoundcurvev2.sip
  7. +1 −1 python/core/geometry/qgscurvepolygonv2.sip
  8. +1 −1 python/core/geometry/qgsgeometrycollectionv2.sip
  9. +1 −1 python/core/geometry/qgslinestringv2.sip
  10. +5 −0 src/app/CMakeLists.txt
  11. +20 −1 src/app/qgisapp.cpp
  12. +6 −0 src/app/qgisapp.h
  13. +182 −0 src/app/qgsmaptooladdcircularstring.cpp
  14. +55 −0 src/app/qgsmaptooladdcircularstring.h
  15. +30 −37 src/app/qgsmaptooladdfeature.cpp
  16. +41 −20 src/app/qgsmaptooladdpart.cpp
  17. +19 −1 src/app/qgsmaptooladdring.cpp
  18. +95 −9 src/app/qgsmaptoolcapture.cpp
  19. +11 −6 src/app/qgsmaptoolcapture.h
  20. +87 −0 src/app/qgsmaptoolcircularstringcurvepoint.cpp
  21. +32 −0 src/app/qgsmaptoolcircularstringcurvepoint.h
  22. +170 −0 src/app/qgsmaptoolcircularstringradius.cpp
  23. +52 −0 src/app/qgsmaptoolcircularstringradius.h
  24. +16 −0 src/app/qgsmaptooledit.cpp
  25. +4 −0 src/app/qgsmaptooledit.h
  26. +3 −1 src/core/geometry/qgsabstractgeometryv2.h
  27. +2 −2 src/core/geometry/qgscircularstringv2.cpp
  28. +5 −1 src/core/geometry/qgscircularstringv2.h
  29. +2 −2 src/core/geometry/qgscompoundcurvev2.cpp
  30. +5 −1 src/core/geometry/qgscompoundcurvev2.h
  31. +3 −3 src/core/geometry/qgscurvepolygonv2.cpp
  32. +5 −1 src/core/geometry/qgscurvepolygonv2.h
  33. +2 −2 src/core/geometry/qgsgeometrycollectionv2.cpp
  34. +5 −1 src/core/geometry/qgsgeometrycollectionv2.h
  35. +2 −2 src/core/geometry/qgslinestringv2.cpp
  36. +6 −1 src/core/geometry/qgslinestringv2.h
  37. +2 −2 src/core/geometry/qgspointv2.cpp
  38. +6 −1 src/core/geometry/qgspointv2.h
  39. +3 −1 src/core/qgsvectordataprovider.h
  40. +49 −6 src/core/qgsvectorlayer.cpp
  41. +11 −0 src/core/qgsvectorlayer.h
  42. +40 −17 src/core/qgsvectorlayereditutils.cpp
  43. +13 −0 src/core/qgsvectorlayereditutils.h
  44. +3 −0 src/providers/postgres/qgspostgresprovider.cpp
  45. +27 −1 src/ui/qgisapp.ui
@@ -508,6 +508,8 @@
<file>themes/default/mIconClear.png</file>
<file>flags/zh.png</file>
<file>themes/default/mIconPaintEffects.svg</file>
<file>themes/default/mActionCircularStringCurvePoint.png</file>
<file>themes/default/mActionCircularStringRadius.png</file>
</qresource>
<qresource prefix="/images/tips">
<file alias="symbol_levels.png">qgis_tips/symbol_levels.png</file>
Binary file not shown.
Binary file not shown.
@@ -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;
@@ -119,6 +119,9 @@ SET(QGIS_APP_SRCS
qgsvectorlayerproperties.cpp
qgsvisibilitypresets.cpp
qgshandlebadlayers.cpp
qgsmaptooladdcircularstring.cpp
qgsmaptoolcircularstringcurvepoint.cpp
qgsmaptoolcircularstringradius.cpp

composer/qgsattributeselectiondialog.cpp
composer/qgscomposer.cpp
@@ -217,6 +220,7 @@ SET (QGIS_APP_MOC_HDRS

qgsmaptooladdfeature.h
qgsmaptoolcapture.h
qgsmaptoolcircularstringradius.h
qgsmaptooladdpart.h
qgsmaptooladdring.h
qgsmaptooledit.h
@@ -245,6 +249,7 @@ SET (QGIS_APP_MOC_HDRS
qgsmaptoolsimplify.h
qgsmaptoolsplitfeatures.h
qgsmaptoolsplitparts.h
qgsmaptooladdcircularstring.h

nodetool/qgsmaptoolnodetool.h
nodetool/qgsselectedfeature.h
@@ -253,6 +253,8 @@
#include "qgsmaptooladdring.h"
#include "qgsmaptoolfillring.h"
#include "qgsmaptoolannotation.h"
#include "qgsmaptoolcircularstringcurvepoint.h"
#include "qgsmaptoolcircularstringradius.h"
#include "qgsmaptooldeletering.h"
#include "qgsmaptooldeletepart.h"
#include "qgsmaptoolfeatureaction.h"
@@ -288,7 +290,6 @@

// Editor widgets
#include "qgseditorwidgetregistry.h"

//
// Conditional Includes
//
@@ -1206,6 +1207,8 @@ 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( mActionCircularStringRadius, SIGNAL( triggered() ), this, SLOT( circularStringRadius() ) );
connect( mActionMoveFeature, SIGNAL( triggered() ), this, SLOT( moveFeature() ) );
connect( mActionRotateFeature, SIGNAL( triggered() ), this, SLOT( rotateFeature() ) );

@@ -1480,6 +1483,8 @@ void QgisApp::createActionGroups()
mMapToolGroup->addAction( mActionMeasureArea );
mMapToolGroup->addAction( mActionMeasureAngle );
mMapToolGroup->addAction( mActionAddFeature );
mMapToolGroup->addAction( mActionCircularStringCurvePoint );
mMapToolGroup->addAction( mActionCircularStringRadius );
mMapToolGroup->addAction( mActionMoveFeature );
mMapToolGroup->addAction( mActionRotateFeature );
#if defined(GEOS_VERSION_MAJOR) && defined(GEOS_VERSION_MINOR) && \
@@ -2329,6 +2334,10 @@ 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.mCircularStringRadius = new QgsMapToolCircularStringRadius( dynamic_cast<QgsMapToolAddFeature*>( mMapTools.mAddFeature ), mMapCanvas );
mMapTools.mCircularStringRadius->setAction( mActionCircularStringRadius );
mMapTools.mMoveFeature = new QgsMapToolMoveFeature( mMapCanvas );
mMapTools.mMoveFeature->setAction( mActionMoveFeature );
mMapTools.mRotateFeature = new QgsMapToolRotateFeature( mMapCanvas );
@@ -6233,6 +6242,16 @@ void QgisApp::addFeature()
mMapCanvas->setMapTool( mMapTools.mAddFeature );
}

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

void QgisApp::circularStringRadius()
{
mMapCanvas->setMapTool( mMapTools.mCircularStringRadius );
}

void QgisApp::selectFeatures()
{
mMapCanvas->setMapTool( mMapTools.mSelectFeatures );
@@ -971,6 +971,10 @@ 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 circular string radius tool
void circularStringRadius();
//! activates the move feature tool
void moveFeature();
//! activates the offset curve tool
@@ -1481,6 +1485,8 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
QgsMapTool *mMeasureArea;
QgsMapTool *mMeasureAngle;
QgsMapTool *mAddFeature;
QgsMapTool *mCircularStringCurvePoint;
QgsMapTool *mCircularStringRadius;
QgsMapTool *mMoveFeature;
QgsMapTool *mOffsetCurve;
QgsMapTool *mReshapeFeatures;
@@ -0,0 +1,182 @@
/***************************************************************************
qgsmaptooladdcircularstring.h - map tool for adding circular strings
---------------------
begin : December 2014
copyright : (C) 2014 by Marco Hugentobler
email : marco dot hugentobler at sourcepole dot ch
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#include "qgsmaptooladdcircularstring.h"
#include "qgscircularstringv2.h"
#include "qgscompoundcurvev2.h"
#include "qgscurvepolygonv2.h"
#include "qgsgeometryrubberband.h"
#include "qgsgeometryutils.h"
#include "qgslinestringv2.h"
#include "qgsmapcanvas.h"
#include "qgspointv2.h"
#include <QMouseEvent>

QgsMapToolAddCircularString::QgsMapToolAddCircularString( QgsMapToolCapture* parentTool, QgsMapCanvas* canvas, CaptureMode mode ): QgsMapToolCapture( canvas, mode ),
mParentTool( parentTool ), mRubberBand( 0 ), mShowCenterPointRubberBand( false ), mCenterPointRubberBand( 0 )
{
if ( mCanvas )
{
connect( mCanvas, SIGNAL( mapToolSet( QgsMapTool*, QgsMapTool* ) ), this, SLOT( setParentTool( QgsMapTool*, QgsMapTool* ) ) );
}
}

QgsMapToolAddCircularString::QgsMapToolAddCircularString( QgsMapCanvas* canvas ): QgsMapToolCapture( canvas ), mParentTool( 0 ),
mRubberBand( 0 ), mShowCenterPointRubberBand( false ), mCenterPointRubberBand( 0 )
{
if ( mCanvas )
{
connect( mCanvas, SIGNAL( mapToolSet( QgsMapTool*, QgsMapTool* ) ), this, SLOT( setParentTool( QgsMapTool*, QgsMapTool* ) ) );
}
}

QgsMapToolAddCircularString::~QgsMapToolAddCircularString()
{
delete mRubberBand;
removeCenterPointRubberBand();
}

void QgsMapToolAddCircularString::setParentTool( QgsMapTool* newTool, QgsMapTool* oldTool )
{
QgsMapToolCapture* tool = dynamic_cast<QgsMapToolCapture*>( oldTool );
QgsMapToolAddCircularString* csTool = dynamic_cast<QgsMapToolAddCircularString*>( oldTool );
if ( csTool && newTool == this )
{
mParentTool = csTool->mParentTool;
}
else if ( tool && newTool == this )
{
mParentTool = tool;
}
}

void QgsMapToolAddCircularString::keyPressEvent( QKeyEvent* e )
{
if ( e->isAutoRepeat() )
{
return;
}

if ( e && e->key() == Qt::Key_R )
{
mShowCenterPointRubberBand = true;

createCenterPointRubberBand();
}
}

void QgsMapToolAddCircularString::keyReleaseEvent( QKeyEvent* e )
{
if ( e->isAutoRepeat() )
{
return;
}

if ( e && e->key() == Qt::Key_R )
{
removeCenterPointRubberBand();
mShowCenterPointRubberBand = false;
}
}

void QgsMapToolAddCircularString::deactivate()
{
if ( !mParentTool || mPoints.size() < 3 )
{
return;
}

if ( mPoints.size() % 2 == 0 ) //a valid circularstring needs to have an odd number of vertices
{
mPoints.removeLast();
}

QgsCircularStringV2* c = new QgsCircularStringV2();
c->setPoints( mPoints );
mParentTool->addCurve( c );
mPoints.clear();
delete mRubberBand; mRubberBand = 0;
removeCenterPointRubberBand();
}

void QgsMapToolAddCircularString::createCenterPointRubberBand()
{
if ( !mShowCenterPointRubberBand || mPoints.size() < 2 || mPoints.size() % 2 != 0 )
{
return;
}

mCenterPointRubberBand = createGeometryRubberBand( QGis::Polygon );
mCenterPointRubberBand->show();

if ( mRubberBand )
{
const QgsAbstractGeometryV2* rubberBandGeom = mRubberBand->geometry();
if ( rubberBandGeom )
{
QgsVertexId idx; idx.part = 0; idx.ring = 0; idx.vertex = mPoints.size();
QgsPointV2 pt = rubberBandGeom->vertexAt( idx );
updateCenterPointRubberBand( pt );
}
}
}

void QgsMapToolAddCircularString::updateCenterPointRubberBand( const QgsPointV2& pt )
{
if ( !mShowCenterPointRubberBand || !mCenterPointRubberBand || mPoints.size() < 2 )
{
return;
}

if (( mPoints.size() ) % 2 != 0 )
{
return;
}

//create circular string
QgsCircularStringV2* cs = new QgsCircularStringV2();
QList< QgsPointV2 > csPoints;
csPoints.append( mPoints.at( mPoints.size() - 2 ) );
csPoints.append( mPoints.at( mPoints.size() - 1 ) );
csPoints.append( pt );
cs->setPoints( csPoints );

double centerX, centerY;
double radius;
QgsGeometryUtils::circleCenterRadius( csPoints.at( 0 ), csPoints.at( 1 ), csPoints.at( 2 ), radius, centerX, centerY );

QgsLineStringV2* segment1 = new QgsLineStringV2();
segment1->addVertex( QgsPointV2( centerX, centerY ) );
segment1->addVertex( csPoints.at( 0 ) );

QgsLineStringV2* segment2 = new QgsLineStringV2();
segment2->addVertex( csPoints.at( 2 ) );
segment2->addVertex( QgsPointV2( centerX, centerY ) );

QgsCompoundCurveV2* cc = new QgsCompoundCurveV2();
cc->addCurve( segment1 );
cc->addCurve( cs );
cc->addCurve( segment2 );

QgsCurvePolygonV2* cp = new QgsCurvePolygonV2();
cp->setExteriorRing( cc );
mCenterPointRubberBand->setGeometry( cp );
mCenterPointRubberBand->show();
}

void QgsMapToolAddCircularString::removeCenterPointRubberBand()
{
delete mCenterPointRubberBand; mCenterPointRubberBand = 0;
}

3 comments on commit 5807875

@nyalldawson

This comment has been minimized.

Copy link
Collaborator

@nyalldawson nyalldawson replied Aug 25, 2015

  • @mhugent at the moment these tools seem to always be enabled, even if the layer isn't editable...
@3nids

This comment has been minimized.

Copy link
Member

@3nids 3nids replied Aug 25, 2015

  • does it make sense to have two distinct icons for this?
    what about having a single button with drop dow actions (list the select icon)?
@3nids

This comment has been minimized.

Copy link
Member

@3nids 3nids replied Aug 25, 2015

  • when switching from standard add feature to curve tools, the rubber bands remains
    image
  • I would have a rubberband following the mouse even when first point of arc is not digitized otherwise we are not sure we are in the digitize mode. It's even more obvious when switching from standard add feature the arc tools.
  • right click should cancel and not finishing the arc. It should cancel the arc so you could start again from last point.
Please sign in to comment.
You can’t perform that action at this time.