Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[FEATURE]: Tool to add circular strings with two points and radius
  • Loading branch information
mhugent committed Aug 21, 2015
1 parent c39ffe9 commit e6219e7
Show file tree
Hide file tree
Showing 13 changed files with 607 additions and 1 deletion.
1 change: 1 addition & 0 deletions images/images.qrc
Expand Up @@ -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>
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: 2 additions & 0 deletions src/app/CMakeLists.txt
Expand Up @@ -119,6 +119,7 @@ SET(QGIS_APP_SRCS
qgshandlebadlayers.cpp
qgsmaptooladdcircularstring.cpp
qgsmaptoolcircularstringcurvepoint.cpp
qgsmaptoolcircularstringradius.cpp

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

qgsmaptooladdfeature.h
qgsmaptoolcapture.h
qgsmaptoolcircularstringradius.h
qgsmaptooladdpart.h
qgsmaptooladdring.h
qgsmaptooledit.h
Expand Down
11 changes: 10 additions & 1 deletion src/app/qgisapp.cpp
Expand Up @@ -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"
Expand Down Expand Up @@ -286,7 +287,6 @@

// Editor widgets
#include "qgseditorwidgetregistry.h"

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

Expand Down Expand Up @@ -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) && \
Expand Down Expand Up @@ -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 );
Expand Down Expand Up @@ -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 );
Expand Down
3 changes: 3 additions & 0 deletions src/app/qgisapp.h
Expand Up @@ -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
Expand Down Expand Up @@ -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;
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;
}
55 changes: 55 additions & 0 deletions src/app/qgsmaptooladdcircularstring.h
@@ -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.