Skip to content

Commit 0da210d

Browse files
committed
Add QgsRectangle::snappedToGrid
Snaps a rectangle to a grid.
1 parent f0735d9 commit 0da210d

File tree

4 files changed

+51
-0
lines changed

4 files changed

+51
-0
lines changed

python/core/auto_generated/geometry/qgsrectangle.sip.in

+8
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,14 @@ Converts the rectangle to a 3D box, with the specified
329329

330330
operator QVariant() const;
331331

332+
QgsRectangle snappedToGrid( double spacing ) const;
333+
%Docstring
334+
Returns a copy of this rectangle that is snapped to a grid with
335+
the specified ``spacing`` between the grid lines.
336+
337+
.. versionadded:: 3.4
338+
%End
339+
332340
SIP_PYOBJECT __repr__();
333341
%MethodCode
334342
QString str = QStringLiteral( "<QgsRectangle: %1>" ).arg( sipCpp->asWktCoordinates() );

src/core/geometry/qgsrectangle.cpp

+19
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,25 @@ QgsBox3d QgsRectangle::toBox3d( double zMin, double zMax ) const
182182
return QgsBox3d( mXmin, mYmin, zMin, mXmax, mYmax, zMax );
183183
}
184184

185+
QgsRectangle QgsRectangle::snappedToGrid( double spacing ) const
186+
{
187+
// helper function
188+
auto gridifyValue = []( double value, double spacing ) -> double
189+
{
190+
if ( spacing > 0 )
191+
return std::round( value / spacing ) * spacing;
192+
else
193+
return value;
194+
};
195+
196+
return QgsRectangle(
197+
gridifyValue( mXmin, spacing ),
198+
gridifyValue( mYmin, spacing ),
199+
gridifyValue( mXmax, spacing ),
200+
gridifyValue( mYmax, spacing )
201+
);
202+
}
203+
185204
QDataStream &operator<<( QDataStream &out, const QgsRectangle &rectangle )
186205
{
187206
out << rectangle.xMinimum() << rectangle.yMinimum() << rectangle.xMaximum() << rectangle.yMaximum();

src/core/geometry/qgsrectangle.h

+8
Original file line numberDiff line numberDiff line change
@@ -547,6 +547,14 @@ class CORE_EXPORT QgsRectangle
547547
return QVariant::fromValue( *this );
548548
}
549549

550+
/**
551+
* Returns a copy of this rectangle that is snapped to a grid with
552+
* the specified \a spacing between the grid lines.
553+
*
554+
* \since QGIS 3.4
555+
*/
556+
QgsRectangle snappedToGrid( double spacing ) const;
557+
550558
#ifdef SIP_RUN
551559
SIP_PYOBJECT __repr__();
552560
% MethodCode

tests/src/core/testqgsrectangle.cpp

+16
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ class TestQgsRectangle: public QObject
4141
void combine();
4242
void dataStream();
4343
void scale();
44+
void snappedToGrid();
4445
};
4546

4647
void TestQgsRectangle::isEmpty()
@@ -366,5 +367,20 @@ void TestQgsRectangle::scale()
366367
QCOMPARE( rect, QgsRectangle( 10, 20, 30, 60 ).scaled( 2, &center ) );
367368
}
368369

370+
void TestQgsRectangle::snappedToGrid()
371+
{
372+
QgsRectangle original( 10.123, 20.333, 10.788, 20.788 );
373+
QgsRectangle snapped = original.snappedToGrid( 0.1 );
374+
375+
QgsRectangle control( 10.1, 20.3, 10.8, 20.8 );
376+
377+
QVERIFY( qgsDoubleNear( snapped.xMinimum(), control.xMinimum(), 0.000001 ) );
378+
QVERIFY( qgsDoubleNear( snapped.xMaximum(), control.xMaximum(), 0.000001 ) );
379+
QVERIFY( qgsDoubleNear( snapped.yMinimum(), control.yMinimum(), 0.000001 ) );
380+
QVERIFY( qgsDoubleNear( snapped.yMaximum(), control.yMaximum(), 0.000001 ) );
381+
382+
QCOMPARE( QgsRectangle().snappedToGrid( 0.1 ), QgsRectangle() );
383+
}
384+
369385
QGSTEST_MAIN( TestQgsRectangle )
370386
#include "testqgsrectangle.moc"

0 commit comments

Comments
 (0)