Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
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 5807875
Show file tree
Hide file tree
Showing 45 changed files with 1,027 additions and 125 deletions.
2 changes: 2 additions & 0 deletions images/images.qrc
Expand Up @@ -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>
Expand Down
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
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
5 changes: 5 additions & 0 deletions src/app/CMakeLists.txt
Expand Up @@ -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
Expand Down Expand Up @@ -217,6 +220,7 @@ SET (QGIS_APP_MOC_HDRS

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

nodetool/qgsmaptoolnodetool.h
nodetool/qgsselectedfeature.h
Expand Down
21 changes: 20 additions & 1 deletion src/app/qgisapp.cpp
Expand Up @@ -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"
Expand Down Expand Up @@ -288,7 +290,6 @@

// Editor widgets
#include "qgseditorwidgetregistry.h"

//
// Conditional Includes
//
Expand Down Expand Up @@ -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() ) );

Expand Down Expand Up @@ -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) && \
Expand Down Expand Up @@ -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 );
Expand Down Expand Up @@ -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 );
Expand Down
6 changes: 6 additions & 0 deletions src/app/qgisapp.h
Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand Down
182 changes: 182 additions & 0 deletions src/app/qgsmaptooladdcircularstring.cpp
@@ -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
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

@3nids
Copy link
Member

@3nids 3nids commented on 5807875 Aug 25, 2015

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • 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
Copy link
Member

@3nids 3nids commented on 5807875 Aug 25, 2015

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • 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.