Skip to content
Permalink
Browse files
Map rotate too display rotation unit
  • Loading branch information
domi4484 committed Sep 1, 2021
1 parent 0874a6a commit 51a945ce1bac0565cbe2f3292aef7e0d6b6e84b5
@@ -589,6 +589,15 @@ Returns an angle formatted as a friendly string.
:return: formatted angle string
%End

static QString formatAngle( double angle, QgsUnitTypes::AngleUnit unit );
%Docstring
Returns an angle formatted as a friendly string.

:param angle: angle to format
:param unit: unit of angle

:return: formatted angle string
%End

static QgsUnitTypes::DistanceValue scaledDistance( double distance, QgsUnitTypes::DistanceUnit unit, int decimals, bool keepBaseUnit = false );
%Docstring
@@ -29,18 +29,13 @@

QgsMapToolRotateLabel::QgsMapToolRotateLabel( QgsMapCanvas *canvas, QgsAdvancedDigitizingDockWidget *cadDock )
: QgsMapToolLabel( canvas, cadDock )
, mStartRotation( 0.0 )
, mCurrentRotation( 0.0 )
, mCurrentMouseAzimuth( 0.0 )
, mCtrlPressed( false )
{
mPalProperties << QgsPalLayerSettings::LabelRotation;
}

QgsMapToolRotateLabel::~QgsMapToolRotateLabel()
{
delete mRotationItem;
delete mRotationPreviewBox;
}

void QgsMapToolRotateLabel::canvasMoveEvent( QgsMapMouseEvent *e )
@@ -170,11 +165,12 @@ void QgsMapToolRotateLabel::canvasPressEvent( QgsMapMouseEvent *e )
mStartRotation = mCurrentRotation;
createRubberBands();

mRotationPreviewBox = createRotationPreviewBox();
createRotationPreviewBox();

mRotationItem = new QgsPointRotationItem( mCanvas );
mRotationItem->setOrientation( QgsPointRotationItem::Clockwise );
mRotationItem->setPointLocation( mRotationPoint );
mRotationItem->setRotationUnit( mCurrentLabel.settings.rotationUnit() );
mRotationItem->setSymbolRotation( static_cast< int >( mCurrentRotation ) );
}
}
@@ -189,8 +185,7 @@ void QgsMapToolRotateLabel::canvasPressEvent( QgsMapMouseEvent *e )
deleteRubberBands();
delete mRotationItem;
mRotationItem = nullptr;
delete mRotationPreviewBox;
mRotationPreviewBox = nullptr;
mRotationPreviewBox.reset();
return;
}

@@ -200,8 +195,7 @@ void QgsMapToolRotateLabel::canvasPressEvent( QgsMapMouseEvent *e )
deleteRubberBands();
delete mRotationItem;
mRotationItem = nullptr;
delete mRotationPreviewBox;
mRotationPreviewBox = nullptr;
mRotationPreviewBox.reset();

QgsVectorLayer *vlayer = mCurrentLabel.layer;
if ( !vlayer )
@@ -282,8 +276,7 @@ void QgsMapToolRotateLabel::keyReleaseEvent( QKeyEvent *e )
deleteRubberBands();
delete mRotationItem;
mRotationItem = nullptr;
delete mRotationPreviewBox;
mRotationPreviewBox = nullptr;
mRotationPreviewBox.reset();
vlayer->triggerRepaint();
}
}
@@ -296,8 +289,7 @@ void QgsMapToolRotateLabel::keyReleaseEvent( QKeyEvent *e )
deleteRubberBands();
delete mRotationItem;
mRotationItem = nullptr;
delete mRotationPreviewBox;
mRotationPreviewBox = nullptr;
mRotationPreviewBox.reset();
}
}
}
@@ -326,20 +318,17 @@ double QgsMapToolRotateLabel::convertAzimuth( double a )
return ( a <= -180.0 ? 360 + a : a );
}

QgsRubberBand *QgsMapToolRotateLabel::createRotationPreviewBox()
void QgsMapToolRotateLabel::createRotationPreviewBox()
{
delete mRotationPreviewBox;
mRotationPreviewBox.reset();
const QVector< QgsPointXY > boxPoints = mCurrentLabel.pos.cornerPoints;
if ( boxPoints.empty() )
{
return nullptr;
}
return;

mRotationPreviewBox = new QgsRubberBand( mCanvas, QgsWkbTypes::LineGeometry );
mRotationPreviewBox.reset( new QgsRubberBand( mCanvas, QgsWkbTypes::LineGeometry ) );
mRotationPreviewBox->setColor( QColor( 0, 0, 255, 65 ) );
mRotationPreviewBox->setWidth( 3 );
setRotationPreviewBox( mCurrentRotation - mStartRotation );
return mRotationPreviewBox;
}

void QgsMapToolRotateLabel::setRotationPreviewBox( double rotation )
@@ -350,17 +339,13 @@ void QgsMapToolRotateLabel::setRotationPreviewBox( double rotation )
}

mRotationPreviewBox->reset();
const QVector< QgsPointXY > boxPoints = mCurrentLabel.pos.cornerPoints;
if ( boxPoints.empty() )
{
if ( mCurrentLabel.pos.cornerPoints.empty() )
return;
}

for ( int i = 0; i < boxPoints.size(); ++i )
{
mRotationPreviewBox->addPoint( rotatePointClockwise( boxPoints.at( i ), mRotationPoint, rotation ) );
}
mRotationPreviewBox->addPoint( rotatePointClockwise( boxPoints.at( 0 ), mRotationPoint, rotation ) );
const QVector< QgsPointXY > cornerPoints = mCurrentLabel.pos.cornerPoints;
for ( const QgsPointXY &cornerPoint : cornerPoints )
mRotationPreviewBox->addPoint( rotatePointClockwise( cornerPoint, mRotationPoint, rotation ) );
mRotationPreviewBox->addPoint( rotatePointClockwise( mCurrentLabel.pos.cornerPoints.at( 0 ), mRotationPoint, rotation ) );
mRotationPreviewBox->show();
}

@@ -20,6 +20,7 @@

#include "qgsmaptoollabel.h"
#include "qgis_app.h"
#include "qobjectuniqueptr.h"
class QgsPointRotationItem;

class APP_EXPORT QgsMapToolRotateLabel: public QgsMapToolLabel
@@ -42,21 +43,21 @@ class APP_EXPORT QgsMapToolRotateLabel: public QgsMapToolLabel
//! Converts azimuth value so that 0 is corresponds to East
static double convertAzimuth( double a );

QgsRubberBand *createRotationPreviewBox();
void createRotationPreviewBox();
void setRotationPreviewBox( double rotation );

//! Rotates input point clockwise around centerPoint
QgsPointXY rotatePointClockwise( const QgsPointXY &input, const QgsPointXY &centerPoint, double degrees ) const;

double mStartRotation; //rotation value prior to start rotating
double mCurrentRotation;
double mCurrentMouseAzimuth;
double mStartRotation = 0.0; //rotation value prior to start rotating
double mCurrentRotation = 0.0;
double mCurrentMouseAzimuth = 0.0;
QgsPointXY mRotationPoint;
QgsPointRotationItem *mRotationItem = nullptr;
QgsRubberBand *mRotationPreviewBox = nullptr;
QObjectUniquePtr<QgsRubberBand> mRotationPreviewBox;

//! True if ctrl was pressed during the last mouse move event
bool mCtrlPressed;
bool mCtrlPressed = false;
};

#endif // QGSMAPTOOLROTATELABEL_H
@@ -21,8 +21,6 @@

QgsPointRotationItem::QgsPointRotationItem( QgsMapCanvas *canvas )
: QgsMapCanvasItem( canvas )
, mOrientation( Clockwise )
, mRotation( 0.0 )
{
//setup font
mFont.setPointSize( 12 );
@@ -78,7 +76,13 @@ void QgsPointRotationItem::paint( QPainter *painter )
bufferPen.setWidthF( QgsGuiUtils::scaleIconSize( 4 ) );
const QFontMetricsF fm( mFont );
QPainterPath label;
label.addText( mPixmap.width(), mPixmap.height() / 2.0 + fm.height() / 2.0, mFont, QLocale().toString( mRotation ) );
const double rotationText = mRotation * QgsUnitTypes::fromUnitToUnitFactor( QgsUnitTypes::AngleDegrees,
mRotationUnit );
label.addText( mPixmap.width(),
mPixmap.height() / 2.0 + fm.height() / 2.0,
mFont,
QgsUnitTypes::formatAngle( rotationText,
mRotationUnit ) );
painter->setPen( bufferPen );
painter->setBrush( Qt::NoBrush );
painter->drawPath( label );
@@ -95,13 +99,18 @@ void QgsPointRotationItem::setPointLocation( const QgsPointXY &p )
setPos( transformedPoint.x() - mPixmap.width() / 2.0, transformedPoint.y() - mPixmap.height() / 2.0 );
}

void QgsPointRotationItem::setRotationUnit( const QgsUnitTypes::AngleUnit &rotationUnit )
{
mRotationUnit = rotationUnit;
}

void QgsPointRotationItem::setSymbol( const QImage &symbolImage )
{
mPixmap = QPixmap::fromImage( symbolImage );
const QFontMetricsF fm( mFont );

//set item size
mItemSize.setWidth( mPixmap.width() + fm.horizontalAdvance( QStringLiteral( "360" ) ) );
//set item size: 6283 millirad arcseconds = 360°
mItemSize.setWidth( mPixmap.width() + fm.horizontalAdvance( QStringLiteral( "6283 millirad" ) ) );
const double pixmapHeight = mPixmap.height();
const double fontHeight = fm.height();
if ( pixmapHeight >= fontHeight )
@@ -17,6 +17,7 @@
#define QGSPOINTROTATIONITEM_H

#include "qgsmapcanvasitem.h"
#include "qgsunittypes.h"
#include <QFontMetricsF>
#include <QPixmap>
#include "qgis_app.h"
@@ -40,11 +41,17 @@ class APP_EXPORT QgsPointRotationItem: public QgsMapCanvasItem
void setPointLocation( const QgsPointXY &p );

/**
* Sets the rotation of the symbol and displays the new rotation number.
* Sets the rotation of the symbol.
* Units are degrees, starting from north direction, clockwise direction.
*/
void setSymbolRotation( int r ) {mRotation = r;}

/**
* Sets the rotation unit.
* \since QGIS 3.22
*/
void setRotationUnit( const QgsUnitTypes::AngleUnit &rotationUnit );

//! Sets rotation symbol from image (takes ownership)
void setSymbol( const QImage &symbolImage );

@@ -56,14 +63,14 @@ class APP_EXPORT QgsPointRotationItem: public QgsMapCanvasItem
//! Converts rotation into QPainter rotation considering mOrientation
int painterRotation( int rotation ) const;
//! Clockwise (default) or counterclockwise
Orientation mOrientation;
Orientation mOrientation = Clockwise;
//! Font to display the numerical rotation values
QFont mFont;
//! Symbol pixmap
QPixmap mPixmap;
int mRotation;
int mRotation = 0.0;
QgsUnitTypes::AngleUnit mRotationUnit = QgsUnitTypes::AngleDegrees;
QPainterPath mArrowPath;

};

#endif // QGSPOINTROTATIONITEM_H
@@ -2572,6 +2572,52 @@ QString QgsUnitTypes::formatAngle( double angle, int decimals, QgsUnitTypes::Ang
return QStringLiteral( "%L1%2" ).arg( angle, 0, 'f', decimals ).arg( unitLabel );
}

QString QgsUnitTypes::formatAngle( double angle, AngleUnit unit )
{
QString unitLabel;
int decimals = 0;

switch ( unit )
{
case AngleDegrees:
unitLabel = QObject::tr( "°", "angle" );
decimals = 0;
break;
case AngleRadians:
unitLabel = QObject::tr( " rad", "angle" );
decimals = 2;
break;
case AngleGon:
unitLabel = QObject::tr( " gon", "angle" );
decimals = 0;
break;
case AngleMinutesOfArc:
unitLabel = QObject::tr( "", "angle minutes" );
decimals = 0;
break;
case AngleSecondsOfArc:
unitLabel = QObject::tr( "", "angle seconds" );
decimals = 0;
break;
case AngleTurn:
unitLabel = QObject::tr( " tr", "angle turn" );
decimals = 3;
break;
case AngleMilliradiansSI:
unitLabel = QObject::tr( " millirad", "angular mil SI" );
decimals = 0;
break;
case AngleMilNATO:
unitLabel = QObject::tr( " mil", "angular mil NATO" );
decimals = 0;
break;
case AngleUnknownUnit:
break;
}

return QStringLiteral( "%L1%2" ).arg( angle, 0, 'f', decimals ).arg( unitLabel );
}


QgsUnitTypes::DistanceValue QgsUnitTypes::scaledDistance( double distance, QgsUnitTypes::DistanceUnit unit, int decimals, bool keepBaseUnit )
{
@@ -563,6 +563,13 @@ class CORE_EXPORT QgsUnitTypes
*/
Q_INVOKABLE static QString formatAngle( double angle, int decimals, QgsUnitTypes::AngleUnit unit );

/**
* Returns an angle formatted as a friendly string.
* \param angle angle to format
* \param unit unit of angle
* \returns formatted angle string
*/
Q_INVOKABLE static QString formatAngle( double angle, QgsUnitTypes::AngleUnit unit );

/**
* Will convert a \a distance with a given \a unit to a distance value which is nice to display.

0 comments on commit 51a945c

Please sign in to comment.