Skip to content

Commit

Permalink
[feature] When interactively moving a callout line, holding shift
Browse files Browse the repository at this point in the history
will cause the callouti line angle to snap to 15 degree increments

This allows for easier creation of nicely parallel callout lines
  • Loading branch information
nyalldawson committed Mar 15, 2021
1 parent 6daeebc commit 7550fbe
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 3 deletions.
57 changes: 54 additions & 3 deletions src/app/labeling/qgsmaptoolmovelabel.cpp
Expand Up @@ -25,6 +25,7 @@
#include "qgsadvanceddigitizingdockwidget.h"
#include "qgsvectorlayerlabeling.h"
#include "qgscallout.h"
#include "qgsstatusbar.h"

QgsMapToolMoveLabel::QgsMapToolMoveLabel( QgsMapCanvas *canvas, QgsAdvancedDigitizingDockWidget *cadDock )
: QgsMapToolLabel( canvas, cadDock )
Expand Down Expand Up @@ -67,7 +68,15 @@ void QgsMapToolMoveLabel::cadCanvasMoveEvent( QgsMapMouseEvent *e )
else if ( mCalloutMoveRubberBand )
{
const int index = mCurrentCalloutMoveOrigin ? 0 : 1;
mCalloutMoveRubberBand->movePoint( index, e->mapPoint() );

QgsPointXY mapPoint = e->mapPoint();
if ( e->modifiers() & Qt::ShiftModifier )
{
// shift modifier = snap to common angles
mapPoint = snapCalloutPointToCommonAngle( mapPoint, true );
}

mCalloutMoveRubberBand->movePoint( index, mapPoint );
mCalloutMoveRubberBand->update();
}
else
Expand Down Expand Up @@ -231,17 +240,23 @@ void QgsMapToolMoveLabel::cadCanvasPressEvent( QgsMapMouseEvent *e )
case Qt::LeftButton:
{
// second click drops label/callout
const bool isCalloutMove = !mCurrentCallout.layerID.isEmpty();
QgsPointXY releaseCoords = e->mapPoint();
if ( isCalloutMove && e->modifiers() & Qt::ShiftModifier )
{
// shift modifier = snap to common angles
releaseCoords = snapCalloutPointToCommonAngle( releaseCoords, false );
}

deleteRubberBands();

const bool isCalloutMove = !mCurrentCallout.layerID.isEmpty();
QgsVectorLayer *vlayer = !isCalloutMove ? mCurrentLabel.layer : QgsProject::instance()->mapLayer<QgsVectorLayer *>( mCurrentCallout.layerID );
if ( !vlayer )
{
return;
}
const QgsFeatureId featureId = !isCalloutMove ? mCurrentLabel.pos.featureId : mCurrentCallout.featureId;

QgsPointXY releaseCoords = e->mapPoint();
double xdiff = releaseCoords.x() - mStartPointMapCoords.x();
double ydiff = releaseCoords.y() - mStartPointMapCoords.y();

Expand Down Expand Up @@ -549,5 +564,41 @@ bool QgsMapToolMoveLabel::currentCalloutDataDefinedPosition( double &x, bool &xS
return true;
}

QgsPointXY QgsMapToolMoveLabel::snapCalloutPointToCommonAngle( const QgsPointXY &mapPoint, bool showStatusMessage ) const
{
const int index = mCurrentCalloutMoveOrigin ? 0 : 1;

QgsPointXY start = *mCalloutMoveRubberBand->getPoint( 0, index == 0 ? 1 : 0 );
const double cursorDistance = start.distance( mapPoint );

// snap to common angles (15 degree increments)
double closestDist = std::numeric_limits< double >::max();
double closestX = 0;
double closestY = 0;
int bestAngle = 0;

const double angleOffset = -canvas()->rotation();

for ( int angle = 0; angle < 360; angle += 15 )
{
const QgsPointXY end = start.project( cursorDistance * 2, angle + angleOffset );
double minDistX = 0;
double minDistY = 0;
const double angleDist = QgsGeometryUtils::sqrDistToLine( mapPoint.x(), mapPoint.y(), start.x(), start.y(), end.x(), end.y(), minDistX, minDistY, 4 * std::numeric_limits<double>::epsilon() );
if ( angleDist < closestDist )
{
closestDist = angleDist;
closestX = minDistX;
closestY = minDistY;
bestAngle = angle;
}
}

if ( showStatusMessage )
QgisApp::instance()->statusBarIface()->showMessage( tr( "Callout angle: %1°" ).arg( bestAngle ), 2000 );

return QgsPointXY( closestX, closestY );
}



2 changes: 2 additions & 0 deletions src/app/labeling/qgsmaptoolmovelabel.h
Expand Up @@ -57,6 +57,8 @@ class APP_EXPORT QgsMapToolMoveLabel: public QgsMapToolLabel
private:
bool currentCalloutDataDefinedPosition( double &x, bool &xSuccess, double &y, bool &ySuccess, int &xCol, int &yCol );

QgsPointXY snapCalloutPointToCommonAngle( const QgsPointXY &mapPoint, bool showStatusMessage ) const;

};

#endif // QGSMAPTOOLMOVELABEL_H

0 comments on commit 7550fbe

Please sign in to comment.