QGIS API Documentation 3.99.0-Master (2fe06baccd8)
Loading...
Searching...
No Matches
qgsmodelsnapper.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsmodelsnapper.cpp
3 --------------------
4 begin : March 2020
5 copyright : (C) 2020 by Nyall Dawson
6 email : nyall dot dawson at gmail dot com
7 ***************************************************************************/
8/***************************************************************************
9 * *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 ***************************************************************************/
16
17#include "qgsmodelsnapper.h"
18
19#include <cmath>
20
21#include "qgssettings.h"
22
24{
25 const QgsSettings s;
26 mTolerance = s.value( QStringLiteral( "/Processing/Modeler/snapTolerancePixels" ), 40 ).toInt();
27}
28
30{
31 mTolerance = snapTolerance;
32}
33
35{
36 mSnapToGrid = enabled;
37}
38
39QPointF QgsModelSnapper::snapPoint( QPointF point, double scaleFactor, bool &snapped, bool snapHorizontal, bool snapVertical ) const
40{
41 snapped = false;
42
43 bool snappedXToGrid = false;
44 bool snappedYToGrid = false;
45 const QPointF res = snapPointToGrid( point, scaleFactor, snappedXToGrid, snappedYToGrid );
46 if ( snappedXToGrid && snapVertical )
47 {
48 snapped = true;
49 point.setX( res.x() );
50 }
51 if ( snappedYToGrid && snapHorizontal )
52 {
53 snapped = true;
54 point.setY( res.y() );
55 }
56
57 return point;
58}
59
60QRectF QgsModelSnapper::snapRect( const QRectF &rect, double scaleFactor, bool &snapped, bool snapHorizontal, bool snapVertical ) const
61{
62 snapped = false;
63 QRectF snappedRect = rect;
64
65 bool snappedXToGrid = false;
66 bool snappedYToGrid = false;
67 QList<QPointF> points;
68 points << rect.topLeft() << rect.topRight() << rect.bottomLeft() << rect.bottomRight();
69 const QPointF res = snapPointsToGrid( points, scaleFactor, snappedXToGrid, snappedYToGrid );
70 if ( snappedXToGrid && snapVertical )
71 {
72 snapped = true;
73 snappedRect.translate( res.x(), 0 );
74 }
75 if ( snappedYToGrid && snapHorizontal )
76 {
77 snapped = true;
78 snappedRect.translate( 0, res.y() );
79 }
80
81 return snappedRect;
82}
83
84QRectF QgsModelSnapper::snapRectWithResize( const QRectF &rect, double scaleFactor, bool &snapped, bool snapHorizontal, bool snapVertical ) const
85{
86 snapped = false;
87 QRectF snappedRect = rect;
88
89 bool snappedXToGrid = false;
90 bool snappedYToGrid = false;
91 QPointF res = snapPointsToGrid( QList<QPointF>() << rect.topLeft(), scaleFactor, snappedXToGrid, snappedYToGrid );
92 if ( snappedXToGrid && snapVertical )
93 {
94 snapped = true;
95 snappedRect.setLeft( snappedRect.left() + res.x() );
96 }
97 if ( snappedYToGrid && snapHorizontal )
98 {
99 snapped = true;
100 snappedRect.setTop( snappedRect.top() + res.y() );
101 }
102 res = snapPointsToGrid( QList<QPointF>() << rect.bottomRight(), scaleFactor, snappedXToGrid, snappedYToGrid );
103 if ( snappedXToGrid && snapVertical )
104 {
105 snapped = true;
106 snappedRect.setRight( snappedRect.right() + res.x() );
107 }
108 if ( snappedYToGrid && snapHorizontal )
109 {
110 snapped = true;
111 snappedRect.setBottom( snappedRect.bottom() + res.y() );
112 }
113
114 return snappedRect;
115}
116
117QPointF QgsModelSnapper::snapPointToGrid( QPointF point, double scaleFactor, bool &snappedX, bool &snappedY ) const
118{
119 const QPointF delta = snapPointsToGrid( QList<QPointF>() << point, scaleFactor, snappedX, snappedY );
120 return point + delta;
121}
122
123QPointF QgsModelSnapper::snapPointsToGrid( const QList<QPointF> &points, double scaleFactor, bool &snappedX, bool &snappedY ) const
124{
125 snappedX = false;
126 snappedY = false;
127 if ( !mSnapToGrid )
128 {
129 return QPointF( 0, 0 );
130 }
131#if 0
132 const QgsLayoutGridSettings &grid = mLayout->gridSettings();
133 if ( grid.resolution().length() <= 0 )
134 return QPointF( 0, 0 );
135#endif
136
137 double deltaX = 0;
138 double deltaY = 0;
139 double smallestDiffX = std::numeric_limits<double>::max();
140 double smallestDiffY = std::numeric_limits<double>::max();
141 for ( const QPointF point : points )
142 {
143 //snap x coordinate
144 const double gridRes = 30; //mLayout->convertToLayoutUnits( grid.resolution() );
145 int xRatio = static_cast<int>( ( point.x() ) / gridRes + 0.5 ); //NOLINT
146 int yRatio = static_cast<int>( ( point.y() ) / gridRes + 0.5 ); //NOLINT
147
148 const double xSnapped = xRatio * gridRes;
149 const double ySnapped = yRatio * gridRes;
150
151 const double currentDiffX = std::fabs( xSnapped - point.x() );
152 if ( currentDiffX < smallestDiffX )
153 {
154 smallestDiffX = currentDiffX;
155 deltaX = xSnapped - point.x();
156 }
157
158 const double currentDiffY = std::fabs( ySnapped - point.y() );
159 if ( currentDiffY < smallestDiffY )
160 {
161 smallestDiffY = currentDiffY;
162 deltaY = ySnapped - point.y();
163 }
164 }
165
166 //convert snap tolerance from pixels to layout units
167 const double alignThreshold = mTolerance / scaleFactor;
168
169 QPointF delta( 0, 0 );
170 if ( smallestDiffX <= alignThreshold )
171 {
172 //snap distance is inside of tolerance
173 snappedX = true;
174 delta.setX( deltaX );
175 }
176 if ( smallestDiffY <= alignThreshold )
177 {
178 //snap distance is inside of tolerance
179 snappedY = true;
180 delta.setY( deltaY );
181 }
182
183 return delta;
184}
Contains settings relating to the appearance, spacing and offset for layout grids.
QgsLayoutMeasurement resolution() const
Returns the page/snap grid resolution.
double length() const
Returns the length of the measurement.
int snapTolerance() const
Returns the snap tolerance (in pixels) to use when snapping.
void setSnapTolerance(int snapTolerance)
Sets the snap tolerance (in pixels) to use when snapping.
QPointF snapPointsToGrid(const QList< QPointF > &points, double scaleFactor, bool &snappedX, bool &snappedY) const
Snaps a set of points to the grid.
QRectF snapRect(const QRectF &rect, double scaleFactor, bool &snapped, bool snapHorizontal=true, bool snapVertical=true) const
Snaps a layout coordinate rect.
QgsModelSnapper()
Constructor for QgsModelSnapper, attached to the specified layout.
QPointF snapPoint(QPointF point, double scaleFactor, bool &snapped, bool snapHorizontal=true, bool snapVertical=true) const
Snaps a layout coordinate point.
QRectF snapRectWithResize(const QRectF &rect, double scaleFactor, bool &snapped, bool snapHorizontal=true, bool snapVertical=true) const
Snaps a layout coordinate rect.
QPointF snapPointToGrid(QPointF point, double scaleFactor, bool &snappedX, bool &snappedY) const
Snaps a layout coordinate point to the grid.
void setSnapToGrid(bool enabled)
Sets whether snapping to grid is enabled.
Stores settings for use within QGIS.
Definition qgssettings.h:65
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.