Skip to content
Permalink
Browse files

[FEATURE]: Tool to add circular strings with two points and radius

  • Loading branch information
mhugent committed Aug 21, 2015
1 parent c39ffe9 commit e6219e713b28cb37de133bd06805d7fbf8db5951
@@ -505,6 +505,7 @@
<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.
@@ -119,6 +119,7 @@ SET(QGIS_APP_SRCS
qgshandlebadlayers.cpp
qgsmaptooladdcircularstring.cpp
qgsmaptoolcircularstringcurvepoint.cpp
qgsmaptoolcircularstringradius.cpp

composer/qgsattributeselectiondialog.cpp
composer/qgscomposer.cpp
@@ -214,6 +215,7 @@ SET (QGIS_APP_MOC_HDRS

qgsmaptooladdfeature.h
qgsmaptoolcapture.h
qgsmaptoolcircularstringradius.h
qgsmaptooladdpart.h
qgsmaptooladdring.h
qgsmaptooledit.h
@@ -251,6 +251,7 @@
#include "qgsmaptoolfillring.h"
#include "qgsmaptoolannotation.h"
#include "qgsmaptoolcircularstringcurvepoint.h"
#include "qgsmaptoolcircularstringradius.h"
#include "qgsmaptooldeletering.h"
#include "qgsmaptooldeletepart.h"
#include "qgsmaptoolfeatureaction.h"
@@ -286,7 +287,6 @@

// Editor widgets
#include "qgseditorwidgetregistry.h"

//
// Conditional Includes
//
@@ -1172,6 +1172,7 @@ void QgisApp::createActions()
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() ) );

@@ -1447,6 +1448,7 @@ void QgisApp::createActionGroups()
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) && \
@@ -2298,6 +2300,8 @@ void QgisApp::createCanvasTools()
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 );
@@ -6169,6 +6173,11 @@ void QgisApp::circularStringCurvePoint()
mMapCanvas->setMapTool( mMapTools.mCircularStringCurvePoint );
}

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

void QgisApp::selectFeatures()
{
mMapCanvas->setMapTool( mMapTools.mSelectFeatures );
@@ -968,6 +968,8 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
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
@@ -1474,6 +1476,7 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
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;
}
@@ -0,0 +1,55 @@
/***************************************************************************
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. *
* *
***************************************************************************/

#ifndef QGSMAPTOOLADDCIRCULARSTRING_H
#define QGSMAPTOOLADDCIRCULARSTRING_H

#include "qgsmaptoolcapture.h"

class QgsGeometryRubberBand;

class QgsMapToolAddCircularString: public QgsMapToolCapture
{
Q_OBJECT
public:
QgsMapToolAddCircularString( QgsMapToolCapture* parentTool, QgsMapCanvas* canvas, CaptureMode mode = CaptureLine );
~QgsMapToolAddCircularString();

void keyPressEvent( QKeyEvent* e );
void keyReleaseEvent( QKeyEvent* e );

void deactivate();

private slots:
void setParentTool( QgsMapTool* newTool, QgsMapTool* oldTool );

protected:
QgsMapToolAddCircularString( QgsMapCanvas* canvas = 0 ); //forbidden

QgsMapToolCapture* mParentTool;
/** Circular string points (in map coordinates)*/
QList< QgsPointV2 > mPoints;
QgsGeometryRubberBand* mRubberBand;

//center point rubber band
bool mShowCenterPointRubberBand;
QgsGeometryRubberBand* mCenterPointRubberBand;

void createCenterPointRubberBand();
void updateCenterPointRubberBand( const QgsPointV2& pt );
void removeCenterPointRubberBand();
};

#endif // QGSMAPTOOLADDCIRCULARSTRING_H

0 comments on commit e6219e7

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