diff --git a/images/images.qrc b/images/images.qrc index 6abbaaed3ed6..61c9be0bdece 100644 --- a/images/images.qrc +++ b/images/images.qrc @@ -565,6 +565,10 @@ themes/default/mActionCircle2Points.svg themes/default/mActionCircle3Points.svg themes/default/mActionCircleCenterPoint.svg + themes/default/mActionEllipseFoci.svg + themes/default/mActionEllipseCenter2Points.svg + themes/default/mActionEllipseCenterPoint.svg + themes/default/mActionEllipseExtent.svg qgis_tips/symbol_levels.png diff --git a/images/themes/default/mActionEllipseCenter2Points.svg b/images/themes/default/mActionEllipseCenter2Points.svg new file mode 100644 index 000000000000..3ecb59e29f5a --- /dev/null +++ b/images/themes/default/mActionEllipseCenter2Points.svg @@ -0,0 +1,124 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/images/themes/default/mActionEllipseCenterPoint.svg b/images/themes/default/mActionEllipseCenterPoint.svg new file mode 100644 index 000000000000..63809c80d4ea --- /dev/null +++ b/images/themes/default/mActionEllipseCenterPoint.svg @@ -0,0 +1,120 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/images/themes/default/mActionEllipseExtent.svg b/images/themes/default/mActionEllipseExtent.svg new file mode 100644 index 000000000000..a1844a312747 --- /dev/null +++ b/images/themes/default/mActionEllipseExtent.svg @@ -0,0 +1,126 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/images/themes/default/mActionEllipseFoci.svg b/images/themes/default/mActionEllipseFoci.svg new file mode 100644 index 000000000000..47b1f15f45ec --- /dev/null +++ b/images/themes/default/mActionEllipseFoci.svg @@ -0,0 +1,118 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/app/CMakeLists.txt b/src/app/CMakeLists.txt index f96cfafff3c6..bc8fba21be6c 100755 --- a/src/app/CMakeLists.txt +++ b/src/app/CMakeLists.txt @@ -136,6 +136,11 @@ SET(QGIS_APP_SRCS qgsmaptoolcircle2points.cpp qgsmaptoolcircle3points.cpp qgsmaptoolcirclecenterpoint.cpp + qgsmaptooladdellipse.cpp + qgsmaptoolellipsefoci.cpp + qgsmaptoolellipseextent.cpp + qgsmaptoolellipsecenterpoint.cpp + qgsmaptoolellipsecenter2points.cpp composer/qgsattributeselectiondialog.cpp composer/qgscomposer.cpp @@ -291,6 +296,11 @@ SET (QGIS_APP_MOC_HDRS qgsmaptoolcircle2points.h qgsmaptoolcircle3points.h qgsmaptoolcirclecenterpoint.h + qgsmaptooladdellipse.h + qgsmaptoolellipsefoci.h + qgsmaptoolellipseextent.h + qgsmaptoolellipsecenterpoint.h + qgsmaptoolellipsecenter2points.h nodetool/qgsselectedfeature.h diff --git a/src/app/qgisapp.cpp b/src/app/qgisapp.cpp index dedd4b854177..e39007c0b75d 100644 --- a/src/app/qgisapp.cpp +++ b/src/app/qgisapp.cpp @@ -332,6 +332,10 @@ Q_GUI_EXPORT extern int qt_defaultDpiX(); #include "qgsmaptoolcircle2points.h" #include "qgsmaptoolcircle3points.h" #include "qgsmaptoolcirclecenterpoint.h" +#include "qgsmaptoolellipsecenter2points.h" +#include "qgsmaptoolellipsecenterpoint.h" +#include "qgsmaptoolellipseextent.h" +#include "qgsmaptoolellipsefoci.h" #include "qgsmaptooldeletering.h" #include "qgsmaptooldeletepart.h" #include "qgsmaptoolfeatureaction.h" @@ -1373,6 +1377,10 @@ QgisApp::~QgisApp() delete mMapTools.mCircle2Points; delete mMapTools.mCircle3Points; delete mMapTools.mCircleCenterPoint; + delete mMapTools.mEllipseCenter2Points; + delete mMapTools.mEllipseCenterPoint; + delete mMapTools.mEllipseExtent; + delete mMapTools.mEllipseFoci; delete mpMaptip; @@ -1796,6 +1804,10 @@ void QgisApp::createActions() connect( mActionCircle2Points, &QAction::triggered, this, &QgisApp::circle2Points ); connect( mActionCircle3Points, &QAction::triggered, this, &QgisApp::circle3Points ); connect( mActionCircleCenterPoint, &QAction::triggered, this, &QgisApp::circleCenterPoint ); + connect( mActionEllipseCenter2Points, &QAction::triggered, this, &QgisApp::ellipseCenter2Points ); + connect( mActionEllipseCenterPoint, &QAction::triggered, this, &QgisApp::ellipseCenterPoint ); + connect( mActionEllipseExtent, &QAction::triggered, this, &QgisApp::ellipseExtent ); + connect( mActionEllipseFoci, &QAction::triggered, this, &QgisApp::ellipseFoci ); connect( mActionMoveFeature, &QAction::triggered, this, &QgisApp::moveFeature ); connect( mActionMoveFeature, &QAction::triggered, this, &QgisApp::moveFeature ); connect( mActionMoveFeatureCopy, &QAction::triggered, this, &QgisApp::moveFeatureCopy ); @@ -2073,6 +2085,10 @@ void QgisApp::createActionGroups() mMapToolGroup->addAction( mActionCircle2Points ); mMapToolGroup->addAction( mActionCircle3Points ); mMapToolGroup->addAction( mActionCircleCenterPoint ); + mMapToolGroup->addAction( mActionEllipseCenter2Points ); + mMapToolGroup->addAction( mActionEllipseCenterPoint ); + mMapToolGroup->addAction( mActionEllipseExtent ); + mMapToolGroup->addAction( mActionEllipseFoci ); mMapToolGroup->addAction( mActionMoveFeature ); mMapToolGroup->addAction( mActionMoveFeatureCopy ); mMapToolGroup->addAction( mActionRotateFeature ); @@ -2551,6 +2567,17 @@ void QgisApp::createToolBars() connect( tbAddCircle, &QToolButton::triggered, this, &QgisApp::toolButtonActionTriggered ); mRegularShapeDigitizeToolBar->insertWidget( mActionNodeTool, tbAddCircle ); + //ellipse digitize tool button + QToolButton *tbAddEllipse = new QToolButton( mRegularShapeDigitizeToolBar ); + tbAddEllipse->setPopupMode( QToolButton::MenuButtonPopup ); + tbAddEllipse->addAction( mActionEllipseCenter2Points ); + tbAddEllipse->addAction( mActionEllipseCenterPoint ); + tbAddEllipse->addAction( mActionEllipseExtent ); + tbAddEllipse->addAction( mActionEllipseFoci ); + tbAddEllipse->setDefaultAction( mActionEllipseCenter2Points ); + connect( tbAddEllipse, &QToolButton::triggered, this, &QgisApp::toolButtonActionTriggered ); + mRegularShapeDigitizeToolBar->insertWidget( mActionNodeTool, tbAddEllipse ); + // move feature tool button QToolButton *moveFeatureButton = new QToolButton( mDigitizeToolBar ); moveFeatureButton->setPopupMode( QToolButton::MenuButtonPopup ); @@ -3138,6 +3165,14 @@ void QgisApp::createCanvasTools() mMapTools.mCircle3Points->setAction( mActionCircle3Points ); mMapTools.mCircleCenterPoint = new QgsMapToolCircleCenterPoint( dynamic_cast( mMapTools.mAddFeature ), mMapCanvas ); mMapTools.mCircleCenterPoint->setAction( mActionCircleCenterPoint ); + mMapTools.mEllipseCenter2Points = new QgsMapToolEllipseCenter2Points( dynamic_cast( mMapTools.mAddFeature ), mMapCanvas ); + mMapTools.mEllipseCenter2Points->setAction( mActionEllipseCenter2Points ); + mMapTools.mEllipseCenterPoint = new QgsMapToolEllipseCenterPoint( dynamic_cast( mMapTools.mAddFeature ), mMapCanvas ); + mMapTools.mEllipseCenterPoint->setAction( mActionEllipseCenterPoint ); + mMapTools.mEllipseExtent = new QgsMapToolEllipseExtent( dynamic_cast( mMapTools.mAddFeature ), mMapCanvas ); + mMapTools.mEllipseExtent->setAction( mActionEllipseExtent ); + mMapTools.mEllipseFoci = new QgsMapToolEllipseFoci( dynamic_cast( mMapTools.mAddFeature ), mMapCanvas ); + mMapTools.mEllipseFoci->setAction( mActionEllipseFoci ); mMapTools.mMoveFeature = new QgsMapToolMoveFeature( mMapCanvas, QgsMapToolMoveFeature::Move ); mMapTools.mMoveFeature->setAction( mActionMoveFeature ); mMapTools.mMoveFeatureCopy = new QgsMapToolMoveFeature( mMapCanvas, QgsMapToolMoveFeature::CopyMove ); @@ -7829,6 +7864,26 @@ void QgisApp::circleCenterPoint() mMapCanvas->setMapTool( mMapTools.mCircleCenterPoint ); } +void QgisApp::ellipseCenter2Points() +{ + mMapCanvas->setMapTool( mMapTools.mEllipseCenter2Points ); +} + +void QgisApp::ellipseCenterPoint() +{ + mMapCanvas->setMapTool( mMapTools.mEllipseCenterPoint ); +} + +void QgisApp::ellipseExtent() +{ + mMapCanvas->setMapTool( mMapTools.mEllipseExtent ); +} + +void QgisApp::ellipseFoci() +{ + mMapCanvas->setMapTool( mMapTools.mEllipseFoci ); +} + void QgisApp::selectFeatures() { mMapCanvas->setMapTool( mMapTools.mSelectFeatures ); @@ -11116,6 +11171,10 @@ void QgisApp::activateDeactivateLayerRelatedActions( QgsMapLayer *layer ) mActionCircle2Points->setEnabled( false ); mActionCircle3Points->setEnabled( false ); mActionCircleCenterPoint->setEnabled( false ); + mActionEllipseCenter2Points->setEnabled( false ); + mActionEllipseCenterPoint->setEnabled( false ); + mActionEllipseExtent->setEnabled( false ); + mActionEllipseFoci->setEnabled( false ); mActionMoveFeature->setEnabled( false ); mActionMoveFeatureCopy->setEnabled( false ); mActionRotateFeature->setEnabled( false ); @@ -11257,6 +11316,14 @@ void QgisApp::activateDeactivateLayerRelatedActions( QgsMapLayer *layer ) && ( vlayer->geometryType() == QgsWkbTypes::LineGeometry || vlayer->geometryType() == QgsWkbTypes::PolygonGeometry ) ); mActionCircleCenterPoint->setEnabled( isEditable && ( canAddFeatures || canChangeGeometry ) && ( vlayer->geometryType() == QgsWkbTypes::LineGeometry || vlayer->geometryType() == QgsWkbTypes::PolygonGeometry ) ); + mActionEllipseCenter2Points->setEnabled( isEditable && ( canAddFeatures || canChangeGeometry ) + && ( vlayer->geometryType() == QgsWkbTypes::LineGeometry || vlayer->geometryType() == QgsWkbTypes::PolygonGeometry ) ); + mActionEllipseCenterPoint->setEnabled( isEditable && ( canAddFeatures || canChangeGeometry ) + && ( vlayer->geometryType() == QgsWkbTypes::LineGeometry || vlayer->geometryType() == QgsWkbTypes::PolygonGeometry ) ); + mActionEllipseExtent->setEnabled( isEditable && ( canAddFeatures || canChangeGeometry ) + && ( vlayer->geometryType() == QgsWkbTypes::LineGeometry || vlayer->geometryType() == QgsWkbTypes::PolygonGeometry ) ); + mActionEllipseFoci->setEnabled( isEditable && ( canAddFeatures || canChangeGeometry ) + && ( vlayer->geometryType() == QgsWkbTypes::LineGeometry || vlayer->geometryType() == QgsWkbTypes::PolygonGeometry ) ); //does provider allow deleting of features? mActionDeleteSelected->setEnabled( isEditable && canDeleteFeatures && layerHasSelection ); mActionCutFeatures->setEnabled( isEditable && canDeleteFeatures && layerHasSelection ); diff --git a/src/app/qgisapp.h b/src/app/qgisapp.h index 3c1e1f473b32..c74d3a0ec64d 100644 --- a/src/app/qgisapp.h +++ b/src/app/qgisapp.h @@ -1203,6 +1203,14 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow void circle3Points(); //! activates the add circle from center and radius tool void circleCenterPoint(); + //! activates the add ellipse from center and 2 points tool + void ellipseCenter2Points(); + //! activates the add ellipse from center point tool + void ellipseCenterPoint(); + //! activates the add ellipse from extent tool + void ellipseExtent(); + //! activates the add ellipse from foci tool + void ellipseFoci(); //! activates the move feature tool void moveFeature(); //! activates the copy and move feature tool @@ -1754,6 +1762,10 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow , mCircle2Points( nullptr ) , mCircle3Points( nullptr ) , mCircleCenterPoint( nullptr ) + , mEllipseCenter2Points( nullptr ) + , mEllipseCenterPoint( nullptr ) + , mEllipseExtent( nullptr ) + , mEllipseFoci( nullptr ) , mMoveFeature( nullptr ) , mOffsetCurve( nullptr ) , mReshapeFeatures( nullptr ) @@ -1803,6 +1815,10 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow QgsMapTool *mCircle2Points = nullptr; QgsMapTool *mCircle3Points = nullptr; QgsMapTool *mCircleCenterPoint = nullptr; + QgsMapTool *mEllipseCenter2Points = nullptr; + QgsMapTool *mEllipseCenterPoint = nullptr; + QgsMapTool *mEllipseExtent = nullptr; + QgsMapTool *mEllipseFoci = nullptr; QgsMapTool *mMoveFeature = nullptr; QgsMapTool *mMoveFeatureCopy = nullptr; QgsMapTool *mOffsetCurve = nullptr; diff --git a/src/app/qgsmaptooladdellipse.cpp b/src/app/qgsmaptooladdellipse.cpp new file mode 100644 index 000000000000..c725d232fa36 --- /dev/null +++ b/src/app/qgsmaptooladdellipse.cpp @@ -0,0 +1,118 @@ +/*************************************************************************** + qgsmaptooladdellipse.cpp - map tool for adding ellipse + --------------------- + begin : July 2017 + copyright : (C) 2017 + email : lbartoletti at tuxfamily dot org + *************************************************************************** + * * + * 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 "qgsmaptooladdellipse.h" +#include "qgscompoundcurve.h" +#include "qgscurvepolygon.h" +#include "qgsgeometryrubberband.h" +#include "qgsgeometryutils.h" +#include "qgslinestring.h" +#include "qgsmapcanvas.h" +#include "qgspoint.h" +#include "qgisapp.h" + +QgsMapToolAddEllipse::QgsMapToolAddEllipse( QgsMapToolCapture *parentTool, QgsMapCanvas *canvas, CaptureMode mode ) + : QgsMapToolCapture( canvas, QgisApp::instance()->cadDockWidget(), mode ) + , mParentTool( parentTool ) + , mTempRubberBand( nullptr ) + , mEllipse( QgsEllipse() ) +{ + if ( mCanvas ) + { + connect( mCanvas, &QgsMapCanvas::mapToolSet, this, &QgsMapToolAddEllipse::setParentTool ); + } +} + +QgsMapToolAddEllipse::QgsMapToolAddEllipse( QgsMapCanvas *canvas ) + : QgsMapToolCapture( canvas, QgisApp::instance()->cadDockWidget() ) + , mParentTool( nullptr ) + , mTempRubberBand( nullptr ) + , mEllipse( QgsEllipse() ) +{ + if ( mCanvas ) + { + connect( mCanvas, &QgsMapCanvas::mapToolSet, this, &QgsMapToolAddEllipse::setParentTool ); + } +} + +QgsMapToolAddEllipse::~QgsMapToolAddEllipse() +{ + delete mTempRubberBand; + mPoints.clear(); +} + +void QgsMapToolAddEllipse::setParentTool( QgsMapTool *newTool, QgsMapTool *oldTool ) +{ + QgsMapToolCapture *tool = dynamic_cast( oldTool ); + QgsMapToolAddEllipse *csTool = dynamic_cast( oldTool ); + if ( csTool && newTool == this ) + { + mParentTool = csTool->mParentTool; + } + else if ( tool && newTool == this ) + { + mParentTool = tool; + } +} + +void QgsMapToolAddEllipse::keyPressEvent( QKeyEvent *e ) +{ + if ( e && e->isAutoRepeat() ) + { + return; + } + + if ( e && e->key() == Qt::Key_Escape ) + { + mPoints.clear(); + delete mTempRubberBand; + mTempRubberBand = nullptr; + if ( mParentTool ) + mParentTool->keyPressEvent( e ); + } +} + +void QgsMapToolAddEllipse::keyReleaseEvent( QKeyEvent *e ) +{ + if ( e && e->isAutoRepeat() ) + { + return; + } +} + +void QgsMapToolAddEllipse::deactivate() +{ + if ( !mParentTool || mEllipse.isEmpty() ) + { + return; + } + + mParentTool->addCurve( mEllipse.toLineString() ); + + delete mTempRubberBand; + mTempRubberBand = nullptr; + mPoints.clear(); + mEllipse = QgsEllipse(); + QgsMapToolCapture::deactivate(); +} + +void QgsMapToolAddEllipse::activate() +{ + if ( mParentTool ) + { + mParentTool->deleteTempRubberBand(); + } + QgsMapToolCapture::activate(); +} diff --git a/src/app/qgsmaptooladdellipse.h b/src/app/qgsmaptooladdellipse.h new file mode 100644 index 000000000000..9eb7186712f7 --- /dev/null +++ b/src/app/qgsmaptooladdellipse.h @@ -0,0 +1,56 @@ +/*************************************************************************** + qgsmaptooladdellipse.h - map tool for adding ellipse + --------------------- + begin : July 2017 + copyright : (C) 2017 + email : lbartoletti at tuxfamily dot org + *************************************************************************** + * * + * 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 QGSMAPTOOLADDELLIPSE_H +#define QGSMAPTOOLADDELLIPSE_H + +#include "qgsmaptoolcapture.h" +#include "qgsellipse.h" + +class QgsGeometryRubberBand; + +class QgsMapToolAddEllipse: public QgsMapToolCapture +{ + Q_OBJECT + public: + QgsMapToolAddEllipse( QgsMapToolCapture *parentTool, QgsMapCanvas *canvas, CaptureMode mode = CaptureLine ); + ~QgsMapToolAddEllipse(); + + void keyPressEvent( QKeyEvent *e ) override; + void keyReleaseEvent( QKeyEvent *e ) override; + + void deactivate() override; + + void activate() override; + + private slots: + void setParentTool( QgsMapTool *newTool, QgsMapTool *oldTool ); + + protected: + explicit QgsMapToolAddEllipse( QgsMapCanvas *canvas ); //forbidden + + /** The parent map tool, e.g. the add feature tool. + * Completed ellipse will be added to this tool by calling its toLineString() method. + * */ + QgsMapToolCapture *mParentTool = nullptr; + //! Ellipse points (in map coordinates) + QgsPointSequence mPoints; + //! The rubberband to show the ellipse currently working on + QgsGeometryRubberBand *mTempRubberBand = nullptr; + //! Ellipse + QgsEllipse mEllipse; + +}; + +#endif // QGSMAPTOOLADDELLIPSE_H diff --git a/src/app/qgsmaptoolellipsecenter2points.cpp b/src/app/qgsmaptoolellipsecenter2points.cpp new file mode 100644 index 000000000000..44b591ea2ba9 --- /dev/null +++ b/src/app/qgsmaptoolellipsecenter2points.cpp @@ -0,0 +1,86 @@ +/*************************************************************************** + qgmaptoolellilpsecenter2points.cpp - map tool for adding ellipse + from center and 2 points + --------------------- + begin : July 2017 + copyright : (C) 2017 by Loïc Bartoletti + email : lbartoletti at tuxfamily dot org + *************************************************************************** + * * + * 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 "qgsmaptoolellipsecenter2points.h" +#include "qgsgeometryrubberband.h" +#include "qgslinestring.h" +#include "qgsmapcanvas.h" +#include "qgspoint.h" +#include + +QgsMapToolEllipseCenter2Points::QgsMapToolEllipseCenter2Points( QgsMapToolCapture *parentTool, + QgsMapCanvas *canvas, CaptureMode mode ) + : QgsMapToolAddEllipse( parentTool, canvas, mode ) +{ +} + +QgsMapToolEllipseCenter2Points::~QgsMapToolEllipseCenter2Points() +{ +} + +void QgsMapToolEllipseCenter2Points::cadCanvasReleaseEvent( QgsMapMouseEvent *e ) +{ + QgsPoint mapPoint( e->mapPoint() ); + + if ( e->button() == Qt::LeftButton ) + { + mPoints.append( mapPoint ); + + if ( !mPoints.isEmpty() ) + { + if ( !mTempRubberBand ) + { + mTempRubberBand = createGeometryRubberBand( ( mode() == CapturePolygon ) ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry, true ); + mTempRubberBand->show(); + } + } + } + else if ( e->button() == Qt::RightButton ) + { + deactivate(); + if ( mParentTool ) + { + mParentTool->canvasReleaseEvent( e ); + } + } +} + +void QgsMapToolEllipseCenter2Points::cadCanvasMoveEvent( QgsMapMouseEvent *e ) +{ + QgsPoint mapPoint( e->mapPoint() ); + + if ( mTempRubberBand ) + { + switch ( mPoints.size() ) + { + case 1: + { + QgsLineString *line = new QgsLineString(); + line->addVertex( mPoints.at( 0 ) ); + line->addVertex( mapPoint ); + mTempRubberBand->setGeometry( line ); + } + break; + case 2: + { + mEllipse = QgsEllipse().fromCenter2Points( mPoints.at( 0 ), mPoints.at( 1 ), mapPoint ); + mTempRubberBand->setGeometry( mEllipse.toPolygon() ); + } + break; + default: + break; + } + } +} diff --git a/src/app/qgsmaptoolellipsecenter2points.h b/src/app/qgsmaptoolellipsecenter2points.h new file mode 100644 index 000000000000..53e6fc7a3305 --- /dev/null +++ b/src/app/qgsmaptoolellipsecenter2points.h @@ -0,0 +1,33 @@ +/*************************************************************************** + qgmaptoolellilpsecenter2points.h - map tool for adding ellipse + from center and 2 points + --------------------- + begin : July 2017 + copyright : (C) 2017 by Loïc Bartoletti + email : lbartoletti at tuxfamily dot org + *************************************************************************** + * * + * 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 3 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +#ifndef QGSMAPTOOLELLIPSECENTER2POINTS_H +#define QGSMAPTOOLELLIPSECENTER2POINTS_H + +#include "qgsmaptooladdellipse.h" + +class QgsMapToolEllipseCenter2Points: public QgsMapToolAddEllipse +{ + Q_OBJECT + + public: + QgsMapToolEllipseCenter2Points( QgsMapToolCapture *parentTool, QgsMapCanvas *canvas, CaptureMode mode = CaptureLine ); + ~QgsMapToolEllipseCenter2Points(); + + void cadCanvasReleaseEvent( QgsMapMouseEvent *e ) override; + void cadCanvasMoveEvent( QgsMapMouseEvent *e ) override; +}; + +#endif // QGSMAPTOOLELLIPSECENTER2POINTS_H diff --git a/src/app/qgsmaptoolellipsecenterpoint.cpp b/src/app/qgsmaptoolellipsecenterpoint.cpp new file mode 100644 index 000000000000..034b413ebf9c --- /dev/null +++ b/src/app/qgsmaptoolellipsecenterpoint.cpp @@ -0,0 +1,68 @@ +/*************************************************************************** + qgmaptoolellipsecenterpoint.cpp - map tool for adding ellipse + from center and a point + --------------------- + begin : July 2017 + copyright : (C) 2017 by Loïc Bartoletti + email : lbartoletti at tuxfamily dot org + *************************************************************************** + * * + * 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 "qgsmaptoolellipsecenterpoint.h" +#include "qgsgeometryrubberband.h" +#include "qgsmapcanvas.h" +#include "qgspoint.h" +#include + +QgsMapToolEllipseCenterPoint::QgsMapToolEllipseCenterPoint( QgsMapToolCapture *parentTool, + QgsMapCanvas *canvas, CaptureMode mode ) + : QgsMapToolAddEllipse( parentTool, canvas, mode ) +{ + +} + +QgsMapToolEllipseCenterPoint::~QgsMapToolEllipseCenterPoint() +{ +} + +void QgsMapToolEllipseCenterPoint::cadCanvasReleaseEvent( QgsMapMouseEvent *e ) +{ + QgsPoint mapPoint( e->mapPoint() ); + + if ( e->button() == Qt::LeftButton ) + { + mPoints.append( mapPoint ); + + if ( !mPoints.isEmpty() ) + { + if ( !mTempRubberBand ) + { + mTempRubberBand = createGeometryRubberBand( ( mode() == CapturePolygon ) ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry, true ); + mTempRubberBand->show(); + } + } + } + else if ( e->button() == Qt::RightButton ) + { + deactivate(); + if ( mParentTool ) + { + mParentTool->canvasReleaseEvent( e ); + } + } +} + +void QgsMapToolEllipseCenterPoint::cadCanvasMoveEvent( QgsMapMouseEvent *e ) +{ + QgsPoint mapPoint( e->mapPoint() ); + if ( mTempRubberBand ) + { + mEllipse = QgsEllipse().fromCenterPoint( mPoints.at( 0 ), mapPoint ); + mTempRubberBand->setGeometry( mEllipse.toPolygon() ); + } +} diff --git a/src/app/qgsmaptoolellipsecenterpoint.h b/src/app/qgsmaptoolellipsecenterpoint.h new file mode 100644 index 000000000000..65a865b82ffe --- /dev/null +++ b/src/app/qgsmaptoolellipsecenterpoint.h @@ -0,0 +1,33 @@ +/*************************************************************************** + qgmaptoolellipsecenterpoint.h - map tool for adding ellipse + from center and a point + --------------------- + begin : July 2017 + copyright : (C) 2017 by Loïc Bartoletti + email : lbartoletti at tuxfamily dot org + *************************************************************************** + * * + * 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 QGSMAPTOOLELLIPSECENTERPOINT_H +#define QGSMAPTOOLELLIPSECENTERPOINT_H + +#include "qgsmaptooladdellipse.h" + +class QgsMapToolEllipseCenterPoint: public QgsMapToolAddEllipse +{ + Q_OBJECT + + public: + QgsMapToolEllipseCenterPoint( QgsMapToolCapture *parentTool, QgsMapCanvas *canvas, CaptureMode mode = CaptureLine ); + ~QgsMapToolEllipseCenterPoint(); + + void cadCanvasReleaseEvent( QgsMapMouseEvent *e ) override; + void cadCanvasMoveEvent( QgsMapMouseEvent *e ) override; +}; + +#endif // QGSMAPTOOLELLIPSECENTERPOINT_H diff --git a/src/app/qgsmaptoolellipseextent.cpp b/src/app/qgsmaptoolellipseextent.cpp new file mode 100644 index 000000000000..a8bd186c2c1f --- /dev/null +++ b/src/app/qgsmaptoolellipseextent.cpp @@ -0,0 +1,68 @@ +/*************************************************************************** + qgmaptoolellipseextent.cpp - map tool for adding ellipse + from extent + --------------------- + begin : July 2017 + copyright : (C) 2017 by Loïc Bartoletti + email : lbartoletti at tuxfamily dot org + *************************************************************************** + * * + * 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 "qgsmaptoolellipseextent.h" +#include "qgsgeometryrubberband.h" +#include "qgsmapcanvas.h" +#include "qgspoint.h" +#include + +QgsMapToolEllipseExtent::QgsMapToolEllipseExtent( QgsMapToolCapture *parentTool, + QgsMapCanvas *canvas, CaptureMode mode ) + : QgsMapToolAddEllipse( parentTool, canvas, mode ) +{ + +} + +QgsMapToolEllipseExtent::~QgsMapToolEllipseExtent() +{ +} + +void QgsMapToolEllipseExtent::cadCanvasReleaseEvent( QgsMapMouseEvent *e ) +{ + QgsPoint mapPoint( e->mapPoint() ); + + if ( e->button() == Qt::LeftButton ) + { + mPoints.append( mapPoint ); + + if ( !mPoints.isEmpty() ) + { + if ( !mTempRubberBand ) + { + mTempRubberBand = createGeometryRubberBand( ( mode() == CapturePolygon ) ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry, true ); + mTempRubberBand->show(); + } + } + } + else if ( e->button() == Qt::RightButton ) + { + deactivate(); + if ( mParentTool ) + { + mParentTool->canvasReleaseEvent( e ); + } + } +} + +void QgsMapToolEllipseExtent::cadCanvasMoveEvent( QgsMapMouseEvent *e ) +{ + QgsPoint mapPoint( e->mapPoint() ); + if ( mTempRubberBand ) + { + mEllipse = QgsEllipse().fromExtent( mPoints.at( 0 ), mapPoint ); + mTempRubberBand->setGeometry( mEllipse.toPolygon() ); + } +} diff --git a/src/app/qgsmaptoolellipseextent.h b/src/app/qgsmaptoolellipseextent.h new file mode 100644 index 000000000000..3c4625bded9d --- /dev/null +++ b/src/app/qgsmaptoolellipseextent.h @@ -0,0 +1,33 @@ +/*************************************************************************** + qgmaptoolellipseextent.h - map tool for adding ellipse + from extent + --------------------- + begin : July 2017 + copyright : (C) 2017 by Loïc Bartoletti + email : lbartoletti at tuxfamily dot org + *************************************************************************** + * * + * 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 QGSMAPTOOLELLIPSEEXTENT_H +#define QGSMAPTOOLELLIPSEEXTENT_H + +#include "qgsmaptooladdellipse.h" + +class QgsMapToolEllipseExtent: public QgsMapToolAddEllipse +{ + Q_OBJECT + + public: + QgsMapToolEllipseExtent( QgsMapToolCapture *parentTool, QgsMapCanvas *canvas, CaptureMode mode = CaptureLine ); + ~QgsMapToolEllipseExtent(); + + void cadCanvasReleaseEvent( QgsMapMouseEvent *e ) override; + void cadCanvasMoveEvent( QgsMapMouseEvent *e ) override; +}; + +#endif // QGSMAPTOOLELLIPSEEXTENT_H diff --git a/src/app/qgsmaptoolellipsefoci.cpp b/src/app/qgsmaptoolellipsefoci.cpp new file mode 100644 index 000000000000..42f5b29fc7b2 --- /dev/null +++ b/src/app/qgsmaptoolellipsefoci.cpp @@ -0,0 +1,86 @@ +/*************************************************************************** + qgmaptoolellipsefoci.cpp - map tool for adding ellipse + from foci and a point + --------------------- + begin : July 2017 + copyright : (C) 2017 by Loïc Bartoletti + email : lbartoletti at tuxfamily dot org + *************************************************************************** + * * + * 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 "qgsmaptoolellipsefoci.h" +#include "qgsgeometryrubberband.h" +#include "qgslinestring.h" +#include "qgsmapcanvas.h" +#include "qgspoint.h" +#include + +QgsMapToolEllipseFoci::QgsMapToolEllipseFoci( QgsMapToolCapture *parentTool, + QgsMapCanvas *canvas, CaptureMode mode ) + : QgsMapToolAddEllipse( parentTool, canvas, mode ) +{ +} + +QgsMapToolEllipseFoci::~QgsMapToolEllipseFoci() +{ +} + +void QgsMapToolEllipseFoci::cadCanvasReleaseEvent( QgsMapMouseEvent *e ) +{ + QgsPoint mapPoint( e->mapPoint() ); + + if ( e->button() == Qt::LeftButton ) + { + mPoints.append( mapPoint ); + + if ( !mPoints.isEmpty() ) + { + if ( !mTempRubberBand ) + { + mTempRubberBand = createGeometryRubberBand( ( mode() == CapturePolygon ) ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry, true ); + mTempRubberBand->show(); + } + } + } + else if ( e->button() == Qt::RightButton ) + { + deactivate(); + if ( mParentTool ) + { + mParentTool->canvasReleaseEvent( e ); + } + } +} + +void QgsMapToolEllipseFoci::cadCanvasMoveEvent( QgsMapMouseEvent *e ) +{ + QgsPoint mapPoint( e->mapPoint() ); + + if ( mTempRubberBand ) + { + switch ( mPoints.size() ) + { + case 1: + { + QgsLineString *line = new QgsLineString(); + line->addVertex( mPoints.at( 0 ) ); + line->addVertex( mapPoint ); + mTempRubberBand->setGeometry( line ); + } + break; + case 2: + { + mEllipse = QgsEllipse().fromFoci( mPoints.at( 0 ), mPoints.at( 1 ), mapPoint ); + mTempRubberBand->setGeometry( mEllipse.toPolygon() ); + } + break; + default: + break; + } + } +} diff --git a/src/app/qgsmaptoolellipsefoci.h b/src/app/qgsmaptoolellipsefoci.h new file mode 100644 index 000000000000..782fae3a77bc --- /dev/null +++ b/src/app/qgsmaptoolellipsefoci.h @@ -0,0 +1,33 @@ +/*************************************************************************** + qgmaptoolellipsefoci.h - map tool for adding ellipse + from foci and a point + --------------------- + begin : July 2017 + copyright : (C) 2017 by Loïc Bartoletti + email : lbartoletti at tuxfamily dot org + *************************************************************************** + * * + * 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 3 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +#ifndef QGSMAPTOOLELLIPSEFOCI_H +#define QGSMAPTOOLELLIPSEFOCI_H + +#include "qgsmaptooladdellipse.h" + +class QgsMapToolEllipseFoci: public QgsMapToolAddEllipse +{ + Q_OBJECT + + public: + QgsMapToolEllipseFoci( QgsMapToolCapture *parentTool, QgsMapCanvas *canvas, CaptureMode mode = CaptureLine ); + ~QgsMapToolEllipseFoci(); + + void cadCanvasReleaseEvent( QgsMapMouseEvent *e ) override; + void cadCanvasMoveEvent( QgsMapMouseEvent *e ) override; +}; + +#endif // QGSMAPTOOLELLIPSEFOCI_H diff --git a/src/core/geometry/qgsellipse.cpp b/src/core/geometry/qgsellipse.cpp index 5f1fcc30b4cb..39e735e3fcaf 100644 --- a/src/core/geometry/qgsellipse.cpp +++ b/src/core/geometry/qgsellipse.cpp @@ -242,6 +242,7 @@ QgsLineString *QgsEllipse::toLineString( unsigned int segments ) const QgsPointSequence pts; pts = points( segments ); + pts.append( pts.at( 0 ) ); // close linestring ext->setPoints( pts ); diff --git a/src/ui/qgisapp.ui b/src/ui/qgisapp.ui index 8f89f5ddbc75..ee5f0f18b1d1 100755 --- a/src/ui/qgisapp.ui +++ b/src/ui/qgisapp.ui @@ -272,6 +272,23 @@ + + + Add circle + + + + + + + + Add ellipse + + + + + + @@ -284,9 +301,8 @@ - - - + + @@ -2723,12 +2739,72 @@ Acts on currently active editable layer :/images/themes/default/mActionCircleCenterPoint.svg:/images/themes/default/mActionCircleCenterPoint.svg - Add Circle by a center point and another point + &Add Circle by a center point and another point Add Circle by a center point and another point + + + true + + + + :/images/themes/default/mActionEllipseCenter2Points.svg:/images/themes/default/mActionEllipseCenter2Points.svg + + + &Add Ellipse from Center and 2 Points + + + Add Ellipse from center and 2 points + + + + + true + + + + :/images/themes/default/mActionEllipseCenterPoint.svg:/images/themes/default/mActionEllipseCenterPoint.svg + + + Add Ellipse from &Center and a Point + + + Add Ellipse from center and a point + + + + + true + + + + :/images/themes/default/mActionEllipseExtent.svg:/images/themes/default/mActionEllipseExtent.svg + + + Add Ellipse from &Extent + + + Add Ellipse from extent + + + + + true + + + + :/images/themes/default/mActionEllipseFoci.svg:/images/themes/default/mActionEllipseFoci.svg + + + Add Ellipse from &Foci + + + Add Ellipse from foci + + diff --git a/tests/src/core/testqgsgeometry.cpp b/tests/src/core/testqgsgeometry.cpp index 23f64c382fd5..b3531444b2c9 100644 --- a/tests/src/core/testqgsgeometry.cpp +++ b/tests/src/core/testqgsgeometry.cpp @@ -4014,7 +4014,7 @@ void TestQgsGeometry::ellipse() QgsLineString *l = new QgsLineString(); l = QgsEllipse( QgsPoint( 0, 0 ), 5, 2, 0 ).toLineString( 4 ); - QCOMPARE( l->numPoints(), 4 ); + QCOMPARE( l->numPoints(), 5 ); // closed linestring QgsPointSequence pts_l; l->points( pts_l ); QCOMPARE( pts, pts_l );