Skip to content

Commit

Permalink
Merge pull request #8335 from m-kuhn/qgsrectangleSnappedToGrid
Browse files Browse the repository at this point in the history
Add QgsRectangle::snappedToGrid
  • Loading branch information
m-kuhn committed Oct 26, 2018
2 parents 04edcb7 + 0da210d commit a0e3c2d
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 0 deletions.
8 changes: 8 additions & 0 deletions python/core/auto_generated/geometry/qgsrectangle.sip.in
Expand Up @@ -329,6 +329,14 @@ Converts the rectangle to a 3D box, with the specified

operator QVariant() const;

QgsRectangle snappedToGrid( double spacing ) const;
%Docstring
Returns a copy of this rectangle that is snapped to a grid with
the specified ``spacing`` between the grid lines.

.. versionadded:: 3.4
%End

SIP_PYOBJECT __repr__();
%MethodCode
QString str = QStringLiteral( "<QgsRectangle: %1>" ).arg( sipCpp->asWktCoordinates() );
Expand Down
19 changes: 19 additions & 0 deletions src/core/geometry/qgsrectangle.cpp
Expand Up @@ -182,6 +182,25 @@ QgsBox3d QgsRectangle::toBox3d( double zMin, double zMax ) const
return QgsBox3d( mXmin, mYmin, zMin, mXmax, mYmax, zMax );
}

QgsRectangle QgsRectangle::snappedToGrid( double spacing ) const
{
// helper function
auto gridifyValue = []( double value, double spacing ) -> double
{
if ( spacing > 0 )
return std::round( value / spacing ) * spacing;
else
return value;
};

return QgsRectangle(
gridifyValue( mXmin, spacing ),
gridifyValue( mYmin, spacing ),
gridifyValue( mXmax, spacing ),
gridifyValue( mYmax, spacing )
);
}

QDataStream &operator<<( QDataStream &out, const QgsRectangle &rectangle )
{
out << rectangle.xMinimum() << rectangle.yMinimum() << rectangle.xMaximum() << rectangle.yMaximum();
Expand Down
8 changes: 8 additions & 0 deletions src/core/geometry/qgsrectangle.h
Expand Up @@ -547,6 +547,14 @@ class CORE_EXPORT QgsRectangle
return QVariant::fromValue( *this );
}

/**
* Returns a copy of this rectangle that is snapped to a grid with
* the specified \a spacing between the grid lines.
*
* \since QGIS 3.4
*/
QgsRectangle snappedToGrid( double spacing ) const;

#ifdef SIP_RUN
SIP_PYOBJECT __repr__();
% MethodCode
Expand Down
16 changes: 16 additions & 0 deletions tests/src/core/testqgsrectangle.cpp
Expand Up @@ -41,6 +41,7 @@ class TestQgsRectangle: public QObject
void combine();
void dataStream();
void scale();
void snappedToGrid();
};

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

void TestQgsRectangle::snappedToGrid()
{
QgsRectangle original( 10.123, 20.333, 10.788, 20.788 );
QgsRectangle snapped = original.snappedToGrid( 0.1 );

QgsRectangle control( 10.1, 20.3, 10.8, 20.8 );

QVERIFY( qgsDoubleNear( snapped.xMinimum(), control.xMinimum(), 0.000001 ) );
QVERIFY( qgsDoubleNear( snapped.xMaximum(), control.xMaximum(), 0.000001 ) );
QVERIFY( qgsDoubleNear( snapped.yMinimum(), control.yMinimum(), 0.000001 ) );
QVERIFY( qgsDoubleNear( snapped.yMaximum(), control.yMaximum(), 0.000001 ) );

QCOMPARE( QgsRectangle().snappedToGrid( 0.1 ), QgsRectangle() );
}

QGSTEST_MAIN( TestQgsRectangle )
#include "testqgsrectangle.moc"

0 comments on commit a0e3c2d

Please sign in to comment.