Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge pull request #2367 from manisandro/qgsround
Introduce qgsRound since std::round is available only in C++11 onwards
  • Loading branch information
nyalldawson committed Oct 13, 2015
2 parents 3daa57f + 2ddc071 commit ff43a5d
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 6 deletions.
12 changes: 6 additions & 6 deletions src/core/geometry/qgsgeos.cpp
Expand Up @@ -1422,11 +1422,11 @@ GEOSCoordSequence* QgsGeos::createCoordinateSequence( const QgsCurveV2* curve, d
for ( int i = 0; i < numPoints; ++i )
{
QgsPointV2 pt = line->pointN( i ); //todo: create method to get const point reference
GEOSCoordSeq_setX_r( geosinit.ctxt, coordSeq, i, std::round( pt.x() / precision ) * precision );
GEOSCoordSeq_setY_r( geosinit.ctxt, coordSeq, i, std::round( pt.y() / precision ) * precision );
GEOSCoordSeq_setX_r( geosinit.ctxt, coordSeq, i, qgsRound( pt.x() / precision ) * precision );
GEOSCoordSeq_setY_r( geosinit.ctxt, coordSeq, i, qgsRound( pt.y() / precision ) * precision );
if ( hasZ )
{
GEOSCoordSeq_setOrdinate_r( geosinit.ctxt, coordSeq, i, 2, std::round( pt.z() / precision ) * precision );
GEOSCoordSeq_setOrdinate_r( geosinit.ctxt, coordSeq, i, 2, qgsRound( pt.z() / precision ) * precision );
}
if ( hasM )
{
Expand Down Expand Up @@ -1474,11 +1474,11 @@ GEOSGeometry* QgsGeos::createGeosPoint( const QgsAbstractGeometryV2* point, int
GEOSCoordSequence* coordSeq = GEOSCoordSeq_create_r( geosinit.ctxt, 1, coordDims );
if ( precision > 0. )
{
GEOSCoordSeq_setX_r( geosinit.ctxt, coordSeq, 0, std::round( pt->x() / precision ) * precision );
GEOSCoordSeq_setY_r( geosinit.ctxt, coordSeq, 0, std::round( pt->y() / precision ) * precision );
GEOSCoordSeq_setX_r( geosinit.ctxt, coordSeq, 0, qgsRound( pt->x() / precision ) * precision );
GEOSCoordSeq_setY_r( geosinit.ctxt, coordSeq, 0, qgsRound( pt->y() / precision ) * precision );
if ( pt->is3D() )
{
GEOSCoordSeq_setOrdinate_r( geosinit.ctxt, coordSeq, 0, 2, std::round( pt->z() / precision ) * precision );
GEOSCoordSeq_setOrdinate_r( geosinit.ctxt, coordSeq, 0, 2, qgsRound( pt->z() / precision ) * precision );
}
}
else
Expand Down
8 changes: 8 additions & 0 deletions src/core/qgis.h
Expand Up @@ -289,6 +289,14 @@ inline bool qgsDoubleNearSig( double a, double b, int significantDigits = 10 )
qRound( ar * pow( 10.0, significantDigits ) ) == qRound( br * pow( 10.0, significantDigits ) );
}

//
// a round function which returns a double to guard against overflows
//
inline double qgsRound( double x )
{
return x < 0.0 ? std::ceil( x - 0.5 ) : std::floor( x + 0.5 );
}

bool qgsVariantLessThan( const QVariant& lhs, const QVariant& rhs );

bool qgsVariantGreaterThan( const QVariant& lhs, const QVariant& rhs );
Expand Down
15 changes: 15 additions & 0 deletions tests/src/core/testqgis.cpp
Expand Up @@ -36,6 +36,7 @@ class TestQGis : public QObject
void permissiveToDouble();
void permissiveToInt();
void doubleToString();
void qgsround();

private:
QString mReport;
Expand Down Expand Up @@ -136,5 +137,19 @@ void TestQGis::doubleToString()
QCOMPARE( qgsDoubleToString( 12345, -1 ), QString( "12345" ) );
}

void TestQGis::qgsround()
{
QCOMPARE( qgsRound( 3.141592653589793 ), 3. );
QCOMPARE( qgsRound( 2.718281828459045 ), 3. );
QCOMPARE( qgsRound( -3.141592653589793 ), -3. );
QCOMPARE( qgsRound( -2.718281828459045 ), -3. );
QCOMPARE( qgsRound( 314159265358979.3 ), 314159265358979. );
QCOMPARE( qgsRound( 2718281828459.045 ), 2718281828459. );
QCOMPARE( qgsRound( -314159265358979.3 ), -314159265358979. );
QCOMPARE( qgsRound( -2718281828459.045 ), -2718281828459. );
QCOMPARE( qgsRound( 1.5 ), 2. );
QCOMPARE( qgsRound( -1.5 ), -2. );
}

QTEST_MAIN( TestQGis )
#include "testqgis.moc"

0 comments on commit ff43a5d

Please sign in to comment.