Skip to content

Commit

Permalink
Add Rectangle from 3 points
Browse files Browse the repository at this point in the history
  • Loading branch information
lbartoletti committed Sep 6, 2017
1 parent 46e66c3 commit 37b6052
Show file tree
Hide file tree
Showing 8 changed files with 264 additions and 14 deletions.
2 changes: 2 additions & 0 deletions src/app/CMakeLists.txt
Expand Up @@ -144,6 +144,7 @@ SET(QGIS_APP_SRCS
qgsmaptooladdregularpolygon.cpp qgsmaptooladdregularpolygon.cpp
qgsmaptoolrectanglecenter.cpp qgsmaptoolrectanglecenter.cpp
qgsmaptoolrectangleextent.cpp qgsmaptoolrectangleextent.cpp
qgsmaptoolrectangle3points.cpp
qgsmaptoolsquarecenter.cpp qgsmaptoolsquarecenter.cpp
qgsmaptoolregularpolygon2points.cpp qgsmaptoolregularpolygon2points.cpp
qgsmaptoolregularpolygoncenterpoint.cpp qgsmaptoolregularpolygoncenterpoint.cpp
Expand Down Expand Up @@ -317,6 +318,7 @@ SET (QGIS_APP_MOC_HDRS
qgsmaptooladdregularpolygon.h qgsmaptooladdregularpolygon.h
qgsmaptoolrectanglecenter.h qgsmaptoolrectanglecenter.h
qgsmaptoolrectangleextent.h qgsmaptoolrectangleextent.h
qgsmaptoolrectangle3points.h
qgsmaptoolsquarecenter.h qgsmaptoolsquarecenter.h
qgsmaptoolregularpolygon2points.h qgsmaptoolregularpolygon2points.h
qgsmaptoolregularpolygoncenterpoint.h qgsmaptoolregularpolygoncenterpoint.h
Expand Down
14 changes: 14 additions & 0 deletions src/app/qgisapp.cpp
Expand Up @@ -342,6 +342,7 @@ Q_GUI_EXPORT extern int qt_defaultDpiX();
#include "qgsmaptoolellipsefoci.h" #include "qgsmaptoolellipsefoci.h"
#include "qgsmaptoolrectanglecenter.h" #include "qgsmaptoolrectanglecenter.h"
#include "qgsmaptoolrectangleextent.h" #include "qgsmaptoolrectangleextent.h"
#include "qgsmaptoolrectangle3points.h"
#include "qgsmaptoolsquarecenter.h" #include "qgsmaptoolsquarecenter.h"
#include "qgsmaptoolregularpolygon2points.h" #include "qgsmaptoolregularpolygon2points.h"
#include "qgsmaptoolregularpolygoncenterpoint.h" #include "qgsmaptoolregularpolygoncenterpoint.h"
Expand Down Expand Up @@ -1407,6 +1408,7 @@ QgisApp::~QgisApp()
delete mMapTools.mEllipseFoci; delete mMapTools.mEllipseFoci;
delete mMapTools.mRectangleCenterPoint; delete mMapTools.mRectangleCenterPoint;
delete mMapTools.mRectangleExtent; delete mMapTools.mRectangleExtent;
delete mMapTools.mRectangle3Points;
delete mMapTools.mSquareCenter; delete mMapTools.mSquareCenter;
delete mMapTools.mRegularPolygon2Points; delete mMapTools.mRegularPolygon2Points;
delete mMapTools.mRegularPolygonCenterPoint; delete mMapTools.mRegularPolygonCenterPoint;
Expand Down Expand Up @@ -1866,6 +1868,7 @@ void QgisApp::createActions()
connect( mActionEllipseFoci, &QAction::triggered, this, &QgisApp::ellipseFoci ); connect( mActionEllipseFoci, &QAction::triggered, this, &QgisApp::ellipseFoci );
connect( mActionRectangleCenterPoint, &QAction::triggered, this, &QgisApp::rectangleCenterPoint ); connect( mActionRectangleCenterPoint, &QAction::triggered, this, &QgisApp::rectangleCenterPoint );
connect( mActionRectangleExtent, &QAction::triggered, this, &QgisApp::rectangleExtent ); connect( mActionRectangleExtent, &QAction::triggered, this, &QgisApp::rectangleExtent );
connect( mActionRectangle3Points, &QAction::triggered, this, &QgisApp::rectangle3Points );
connect( mActionSquareCenter, &QAction::triggered, this, &QgisApp::squareCenter ); connect( mActionSquareCenter, &QAction::triggered, this, &QgisApp::squareCenter );
connect( mActionRegularPolygon2Points, &QAction::triggered, this, &QgisApp::regularPolygon2Points ); connect( mActionRegularPolygon2Points, &QAction::triggered, this, &QgisApp::regularPolygon2Points );
connect( mActionRegularPolygonCenterPoint, &QAction::triggered, this, &QgisApp::regularPolygonCenterPoint ); connect( mActionRegularPolygonCenterPoint, &QAction::triggered, this, &QgisApp::regularPolygonCenterPoint );
Expand Down Expand Up @@ -2153,6 +2156,7 @@ void QgisApp::createActionGroups()
mMapToolGroup->addAction( mActionEllipseFoci ); mMapToolGroup->addAction( mActionEllipseFoci );
mMapToolGroup->addAction( mActionRectangleCenterPoint ); mMapToolGroup->addAction( mActionRectangleCenterPoint );
mMapToolGroup->addAction( mActionRectangleExtent ); mMapToolGroup->addAction( mActionRectangleExtent );
mMapToolGroup->addAction( mActionRectangle3Points );
mMapToolGroup->addAction( mActionSquareCenter ); mMapToolGroup->addAction( mActionSquareCenter );
mMapToolGroup->addAction( mActionRegularPolygon2Points ); mMapToolGroup->addAction( mActionRegularPolygon2Points );
mMapToolGroup->addAction( mActionRegularPolygonCenterPoint ); mMapToolGroup->addAction( mActionRegularPolygonCenterPoint );
Expand Down Expand Up @@ -2693,6 +2697,7 @@ void QgisApp::createToolBars()
tbAddRectangle->setPopupMode( QToolButton::MenuButtonPopup ); tbAddRectangle->setPopupMode( QToolButton::MenuButtonPopup );
tbAddRectangle->addAction( mActionRectangleCenterPoint ); tbAddRectangle->addAction( mActionRectangleCenterPoint );
tbAddRectangle->addAction( mActionRectangleExtent ); tbAddRectangle->addAction( mActionRectangleExtent );
tbAddRectangle->addAction( mActionRectangle3Points );
tbAddRectangle->addAction( mActionSquareCenter ); tbAddRectangle->addAction( mActionSquareCenter );
tbAddRectangle->setDefaultAction( mActionRectangleCenterPoint ); tbAddRectangle->setDefaultAction( mActionRectangleCenterPoint );
connect( tbAddRectangle, &QToolButton::triggered, this, &QgisApp::toolButtonActionTriggered ); connect( tbAddRectangle, &QToolButton::triggered, this, &QgisApp::toolButtonActionTriggered );
Expand Down Expand Up @@ -3296,6 +3301,8 @@ void QgisApp::createCanvasTools()
mMapTools.mRectangleCenterPoint->setAction( mActionRectangleCenterPoint ); mMapTools.mRectangleCenterPoint->setAction( mActionRectangleCenterPoint );
mMapTools.mRectangleExtent = new QgsMapToolRectangleExtent( dynamic_cast<QgsMapToolAddFeature *>( mMapTools.mAddFeature ), mMapCanvas ); mMapTools.mRectangleExtent = new QgsMapToolRectangleExtent( dynamic_cast<QgsMapToolAddFeature *>( mMapTools.mAddFeature ), mMapCanvas );
mMapTools.mRectangleExtent->setAction( mActionRectangleExtent ); mMapTools.mRectangleExtent->setAction( mActionRectangleExtent );
mMapTools.mRectangle3Points = new QgsMapToolRectangle3Points( dynamic_cast<QgsMapToolAddFeature *>( mMapTools.mAddFeature ), mMapCanvas );
mMapTools.mRectangle3Points->setAction( mActionRectangle3Points );
mMapTools.mSquareCenter = new QgsMapToolSquareCenter( dynamic_cast<QgsMapToolAddFeature *>( mMapTools.mAddFeature ), mMapCanvas ); mMapTools.mSquareCenter = new QgsMapToolSquareCenter( dynamic_cast<QgsMapToolAddFeature *>( mMapTools.mAddFeature ), mMapCanvas );
mMapTools.mSquareCenter->setAction( mActionSquareCenter ); mMapTools.mSquareCenter->setAction( mActionSquareCenter );
mMapTools.mRegularPolygon2Points = new QgsMapToolRegularPolygon2Points( dynamic_cast<QgsMapToolAddFeature *>( mMapTools.mAddFeature ), mMapCanvas ); mMapTools.mRegularPolygon2Points = new QgsMapToolRegularPolygon2Points( dynamic_cast<QgsMapToolAddFeature *>( mMapTools.mAddFeature ), mMapCanvas );
Expand Down Expand Up @@ -7917,6 +7924,11 @@ void QgisApp::rectangleExtent()
mMapCanvas->setMapTool( mMapTools.mRectangleExtent ); mMapCanvas->setMapTool( mMapTools.mRectangleExtent );
} }


void QgisApp::rectangle3Points()
{
mMapCanvas->setMapTool( mMapTools.mRectangle3Points );
}

void QgisApp::squareCenter() void QgisApp::squareCenter()
{ {
mMapCanvas->setMapTool( mMapTools.mSquareCenter ); mMapCanvas->setMapTool( mMapTools.mSquareCenter );
Expand Down Expand Up @@ -11397,6 +11409,8 @@ void QgisApp::activateDeactivateLayerRelatedActions( QgsMapLayer *layer )
&& ( vlayer->geometryType() == QgsWkbTypes::LineGeometry || vlayer->geometryType() == QgsWkbTypes::PolygonGeometry ) ); && ( vlayer->geometryType() == QgsWkbTypes::LineGeometry || vlayer->geometryType() == QgsWkbTypes::PolygonGeometry ) );
mActionRectangleExtent->setEnabled( isEditable && ( canAddFeatures || canChangeGeometry ) mActionRectangleExtent->setEnabled( isEditable && ( canAddFeatures || canChangeGeometry )
&& ( vlayer->geometryType() == QgsWkbTypes::LineGeometry || vlayer->geometryType() == QgsWkbTypes::PolygonGeometry ) ); && ( vlayer->geometryType() == QgsWkbTypes::LineGeometry || vlayer->geometryType() == QgsWkbTypes::PolygonGeometry ) );
mActionRectangle3Points->setEnabled( isEditable && ( canAddFeatures || canChangeGeometry )
&& ( vlayer->geometryType() == QgsWkbTypes::LineGeometry || vlayer->geometryType() == QgsWkbTypes::PolygonGeometry ) );
mActionSquareCenter->setEnabled( isEditable && ( canAddFeatures || canChangeGeometry ) mActionSquareCenter->setEnabled( isEditable && ( canAddFeatures || canChangeGeometry )
&& ( vlayer->geometryType() == QgsWkbTypes::LineGeometry || vlayer->geometryType() == QgsWkbTypes::PolygonGeometry ) ); && ( vlayer->geometryType() == QgsWkbTypes::LineGeometry || vlayer->geometryType() == QgsWkbTypes::PolygonGeometry ) );
mActionRegularPolygon2Points->setEnabled( isEditable && ( canAddFeatures || canChangeGeometry ) mActionRegularPolygon2Points->setEnabled( isEditable && ( canAddFeatures || canChangeGeometry )
Expand Down
4 changes: 4 additions & 0 deletions src/app/qgisapp.h
Expand Up @@ -1235,6 +1235,8 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
void rectangleCenterPoint(); void rectangleCenterPoint();
//! activates the add rectangle from extent tool //! activates the add rectangle from extent tool
void rectangleExtent(); void rectangleExtent();
//! activates the add rectangle from 3 points tool
void rectangle3Points();
//! activates the add square from center tool //! activates the add square from center tool
void squareCenter(); void squareCenter();
//! activates the add regular polygon from 2 points tool //! activates the add regular polygon from 2 points tool
Expand Down Expand Up @@ -1819,6 +1821,7 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
, mEllipseFoci( nullptr ) , mEllipseFoci( nullptr )
, mRectangleCenterPoint( nullptr ) , mRectangleCenterPoint( nullptr )
, mRectangleExtent( nullptr ) , mRectangleExtent( nullptr )
, mRectangle3Points( nullptr )
, mSquareCenter( nullptr ) , mSquareCenter( nullptr )
, mRegularPolygon2Points( nullptr ) , mRegularPolygon2Points( nullptr )
, mRegularPolygonCenterPoint( nullptr ) , mRegularPolygonCenterPoint( nullptr )
Expand Down Expand Up @@ -1878,6 +1881,7 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
QgsMapTool *mEllipseFoci = nullptr; QgsMapTool *mEllipseFoci = nullptr;
QgsMapTool *mRectangleCenterPoint = nullptr; QgsMapTool *mRectangleCenterPoint = nullptr;
QgsMapTool *mRectangleExtent = nullptr; QgsMapTool *mRectangleExtent = nullptr;
QgsMapTool *mRectangle3Points = nullptr;
QgsMapTool *mSquareCenter = nullptr; QgsMapTool *mSquareCenter = nullptr;
QgsMapTool *mRegularPolygon2Points = nullptr; QgsMapTool *mRegularPolygon2Points = nullptr;
QgsMapTool *mRegularPolygonCenterPoint = nullptr; QgsMapTool *mRegularPolygonCenterPoint = nullptr;
Expand Down
56 changes: 46 additions & 10 deletions src/app/qgsmaptooladdrectangle.cpp
Expand Up @@ -42,6 +42,26 @@ QgsMapToolAddRectangle::QgsMapToolAddRectangle( QgsMapCanvas *canvas )
clean(); clean();
} }


void QgsMapToolAddRectangle::setAzimuth( const double azimuth )
{
mAzimuth = azimuth;
}

void QgsMapToolAddRectangle::setDistance1( const double distance1 )
{
mDistance1 = distance1;
}

void QgsMapToolAddRectangle::setDistance2( const double distance2 )
{
mDistance2 = distance2;
}

void QgsMapToolAddRectangle::setSide( const int side )
{
mSide = side;
}

QgsMapToolAddRectangle::~QgsMapToolAddRectangle() QgsMapToolAddRectangle::~QgsMapToolAddRectangle()
{ {
clean(); clean();
Expand Down Expand Up @@ -70,45 +90,61 @@ void QgsMapToolAddRectangle::keyReleaseEvent( QKeyEvent *e )
} }
} }


QgsLineString *QgsMapToolAddRectangle::rectangleToLinestring( ) const QgsLineString *QgsMapToolAddRectangle::rectangleToLinestring( const bool isOriented ) const
{ {
std::unique_ptr<QgsLineString> ext( new QgsLineString() ); std::unique_ptr<QgsLineString> ext( new QgsLineString() );
if ( mRectangle.isEmpty() ) if ( mRectangle.isEmpty() )
{ {
return ext.release(); return ext.release();
} }


ext->addVertex( QgsPoint( mRectangle.xMinimum(), mRectangle.yMinimum() ) ); QgsPoint x0( mRectangle.xMinimum(), mRectangle.yMinimum() );
ext->addVertex( QgsPoint( mRectangle.xMinimum(), mRectangle.yMaximum() ) );
ext->addVertex( QgsPoint( mRectangle.xMaximum(), mRectangle.yMaximum() ) ); QgsPoint x1, x2, x3;
ext->addVertex( QgsPoint( mRectangle.xMaximum(), mRectangle.yMinimum() ) ); if ( isOriented )
ext->addVertex( QgsPoint( mRectangle.xMinimum(), mRectangle.yMinimum() ) ); {
double perpendicular = 90.0 * mSide;
x1 = x0.project( mDistance1, mAzimuth );
x3 = x0.project( mDistance2, mAzimuth + perpendicular );
x2 = x1.project( mDistance2, mAzimuth + perpendicular );
}
else
{
x1 = QgsPoint( mRectangle.xMinimum(), mRectangle.yMaximum() );
x2 = QgsPoint( mRectangle.xMaximum(), mRectangle.yMaximum() );
x3 = QgsPoint( mRectangle.xMaximum(), mRectangle.yMinimum() );
}
ext->addVertex( x0 );
ext->addVertex( x1 );
ext->addVertex( x2 );
ext->addVertex( x3 );
ext->addVertex( x0 );


return ext.release(); return ext.release();
} }


QgsPolygonV2 *QgsMapToolAddRectangle::rectangleToPolygon() const QgsPolygonV2 *QgsMapToolAddRectangle::rectangleToPolygon( const bool isOriented ) const
{ {
std::unique_ptr<QgsPolygonV2> polygon( new QgsPolygonV2() ); std::unique_ptr<QgsPolygonV2> polygon( new QgsPolygonV2() );
if ( mRectangle.isEmpty() ) if ( mRectangle.isEmpty() )
{ {
return polygon.release(); return polygon.release();
} }


polygon->setExteriorRing( rectangleToLinestring( ) ); polygon->setExteriorRing( rectangleToLinestring( isOriented ) );


return polygon.release(); return polygon.release();
} }


void QgsMapToolAddRectangle::deactivate() void QgsMapToolAddRectangle::deactivate( const bool isOriented )
{ {
if ( !mParentTool || mRectangle.isEmpty() ) if ( !mParentTool || mRectangle.isEmpty() )
{ {
return; return;
} }


mParentTool->clearCurve( ); mParentTool->clearCurve( );
mParentTool->addCurve( rectangleToLinestring() ); mParentTool->addCurve( rectangleToLinestring( isOriented ) );
clean(); clean();


QgsMapToolCapture::deactivate(); QgsMapToolCapture::deactivate();
Expand Down
37 changes: 34 additions & 3 deletions src/app/qgsmaptooladdrectangle.h
Expand Up @@ -24,6 +24,7 @@ class QgsPolygonV2;
class QgsMapToolAddRectangle: public QgsMapToolCapture class QgsMapToolAddRectangle: public QgsMapToolCapture
{ {
Q_OBJECT Q_OBJECT

//! convenient method to clean members //! convenient method to clean members
void clean(); void clean();
public: public:
Expand All @@ -33,7 +34,7 @@ class QgsMapToolAddRectangle: public QgsMapToolCapture
void keyPressEvent( QKeyEvent *e ) override; void keyPressEvent( QKeyEvent *e ) override;
void keyReleaseEvent( QKeyEvent *e ) override; void keyReleaseEvent( QKeyEvent *e ) override;


void deactivate() override; void deactivate( const bool isOriented = false );


void activate() override; void activate() override;


Expand All @@ -51,8 +52,38 @@ class QgsMapToolAddRectangle: public QgsMapToolCapture
//! Rectangle //! Rectangle
QgsRectangle mRectangle; QgsRectangle mRectangle;


QgsLineString *rectangleToLinestring() const; //! Convenient method to export a QgsRectangle to a LineString
QgsPolygonV2 *rectangleToPolygon() const; QgsLineString *rectangleToLinestring( const bool isOriented = false ) const;
//! Convenient method to export a QgsRectangle to a Polygon
QgsPolygonV2 *rectangleToPolygon( const bool isOriented = false ) const;

//! Sets the azimuth. \see mAzimuth
void setAzimuth( const double azimuth );
//! Sets the first distance. \see mDistance1
void setDistance1( const double distance1 );
//! Sets the second distance. \see mDistance2
void setDistance2( const double distance2 );
//! Sets the side. \see mSide
void setSide( const int side );

//! Returns the azimuth. \see mAzimuth
double azimuth( ) const { return mAzimuth; }
//! Returns the first distance. \see mDistance1
double distance1( ) const { return mDistance1; }
//! Returns the second distance. \see mDistance2
double distance2( ) const { return mDistance2; }
//! Returns the side. \see mSide
int side( ) const { return mSide; }

private:
//! Convenient member for the azimuth of the rotated rectangle. \see QgsMapToolRectangle3Points
double mAzimuth = 0.0;
//! Convenient member for the first distance of the rotated rectangle. \see QgsMapToolRectangle3Points
double mDistance1 = 0.0;
//! Convenient member for the second distance of the rotated rectangle. \see QgsMapToolRectangle3Points
double mDistance2 = 0.0;
//! Convenient member for the side where the second distance is drawn. \see QgsMapToolRectangle3Points
int mSide = 1;
}; };




Expand Down
109 changes: 109 additions & 0 deletions src/app/qgsmaptoolrectangle3points.cpp
@@ -0,0 +1,109 @@
/***************************************************************************
qgsmaptoolrectangle3points.cpp - map tool for adding rectangle
from 3 points
---------------------
begin : September 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. *
* *
***************************************************************************/
#include "qgsmaptoolrectangle3points.h"
#include "qgsgeometryrubberband.h"
#include "qgsgeometryutils.h"
#include "qgslinestring.h"
#include "qgsmapcanvas.h"
#include "qgspoint.h"
#include <QMouseEvent>
#include <memory>

QgsMapToolRectangle3Points::QgsMapToolRectangle3Points( QgsMapToolCapture *parentTool,
QgsMapCanvas *canvas, CaptureMode mode )
: QgsMapToolAddRectangle( parentTool, canvas, mode )
{
}

QgsMapToolRectangle3Points::~QgsMapToolRectangle3Points()
{
}

void QgsMapToolRectangle3Points::cadCanvasReleaseEvent( QgsMapMouseEvent *e )
{
QgsPoint mapPoint( e->mapPoint() );

if ( e->button() == Qt::LeftButton )
{
if ( mPoints.size() < 2 )
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( true );
if ( mParentTool )
{
mParentTool->canvasReleaseEvent( e );
}
}
}

void QgsMapToolRectangle3Points::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 );
setAzimuth( mPoints.at( 0 ).azimuth( mapPoint ) );
setDistance1( mPoints.at( 0 ).distance( mapPoint ) );
}
break;
case 2:
{

setDistance2( mPoints.at( 1 ).distance( mapPoint ) );
double side = QgsGeometryUtils::leftOfLine( mapPoint.x(), mapPoint.y(),
mPoints.at( 0 ).x(), mPoints.at( 0 ).y(),
mPoints.at( 1 ).x(), mPoints.at( 1 ).y() );

setSide( side < 0 ? -1 : 1 );

double xMin = mPoints.at( 0 ).x();
double xMax = mPoints.at( 0 ).x() + distance2( );

double yMin = mPoints.at( 0 ).y();
double yMax = mPoints.at( 0 ).y() + distance1();

mRectangle = QgsRectangle( xMin, yMin,
xMax, yMax );


mTempRubberBand->setGeometry( QgsMapToolAddRectangle::rectangleToPolygon( true ) );
}
break;
default:
break;
}
}

}

0 comments on commit 37b6052

Please sign in to comment.