Skip to content

Commit

Permalink
Add inclination method for QgsPointV2 (#4536)
Browse files Browse the repository at this point in the history
  • Loading branch information
lbartoletti authored and nyalldawson committed May 13, 2017
1 parent c620c7c commit bc0c3a2
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 0 deletions.
8 changes: 8 additions & 0 deletions python/core/geometry/qgspointv2.sip
Expand Up @@ -234,6 +234,14 @@ class QgsPointV2: QgsAbstractGeometry
:rtype: float
%End

double inclination( const QgsPointV2 &other ) const;
%Docstring
Calculates inclination between this point and other one (starting from zenith = 0 to nadir = 180. Horizon = 90)
Returns 90.0 if the distance between this point and other one is equal to 0 (same point).
.. versionadded:: 3.0
:rtype: float
%End

QgsPointV2 project( double distance, double azimuth, double inclination = 90.0 ) const;
%Docstring
Returns a new point which correspond to this point projected by a specified distance
Expand Down
11 changes: 11 additions & 0 deletions src/core/geometry/qgspointv2.cpp
Expand Up @@ -485,6 +485,17 @@ double QgsPointV2::azimuth( const QgsPointV2 &other ) const
return ( atan2( dx, dy ) * 180.0 / M_PI );
}

double QgsPointV2::inclination( const QgsPointV2 &other ) const
{
double distance = distance3D( other );
if ( qgsDoubleNear( distance, 0.0 ) )
{
return 90.0;
}
double dz = other.z() - mZ;

return ( acos( dz / distance ) * 180.0 / M_PI );
}

QgsPointV2 QgsPointV2::project( double distance, double azimuth, double inclination ) const
{
Expand Down
7 changes: 7 additions & 0 deletions src/core/geometry/qgspointv2.h
Expand Up @@ -243,6 +243,13 @@ class CORE_EXPORT QgsPointV2: public QgsAbstractGeometry
*/
double azimuth( const QgsPointV2 &other ) const;

/**
* Calculates inclination between this point and other one (starting from zenith = 0 to nadir = 180. Horizon = 90)
* Returns 90.0 if the distance between this point and other one is equal to 0 (same point).
* \since QGIS 3.0
*/
double inclination( const QgsPointV2 &other ) const;

/** Returns a new point which correspond to this point projected by a specified distance
* with specified angles (azimuth and inclination).
* M value is preserved.
Expand Down
20 changes: 20 additions & 0 deletions src/core/qgsexpression.cpp
Expand Up @@ -2921,6 +2921,25 @@ static QVariant fcnProject( const QVariantList &values, const QgsExpressionConte
return QVariant::fromValue( QgsGeometry( new QgsPointV2( newPoint ) ) );
}

static QVariant fcnInclination( const QVariantList &values, const QgsExpressionContext *, QgsExpression *parent )
{
QgsGeometry fGeom1 = getGeometry( values.at( 0 ), parent );
QgsGeometry fGeom2 = getGeometry( values.at( 1 ), parent );

const QgsPointV2 *pt1 = dynamic_cast<const QgsPointV2 *>( fGeom1.geometry() );
const QgsPointV2 *pt2 = dynamic_cast<const QgsPointV2 *>( fGeom2.geometry() );

if ( ( fGeom1.type() != QgsWkbTypes::PointGeometry ) || ( fGeom2.type() != QgsWkbTypes::PointGeometry ) ||
!pt1 || !pt2 )
{
parent->setEvalErrorString( QStringLiteral( "Function 'inclination' requires two points as arguments." ) );
return QVariant();
}

return pt1->inclination( *pt2 );

}

static QVariant fcnExtrude( const QVariantList &values, const QgsExpressionContext *, QgsExpression *parent )
{
if ( values.length() != 3 )
Expand Down Expand Up @@ -3933,6 +3952,7 @@ const QList<QgsExpression::Function *> &QgsExpression::Functions()
<< new StaticFunction( QStringLiteral( "radians" ), ParameterList() << Parameter( QStringLiteral( "degrees" ) ), fcnRadians, QStringLiteral( "Math" ) )
<< new StaticFunction( QStringLiteral( "degrees" ), ParameterList() << Parameter( QStringLiteral( "radians" ) ), fcnDegrees, QStringLiteral( "Math" ) )
<< new StaticFunction( QStringLiteral( "azimuth" ), ParameterList() << Parameter( QStringLiteral( "point_a" ) ) << Parameter( QStringLiteral( "point_b" ) ), fcnAzimuth, QStringList() << QStringLiteral( "Math" ) << QStringLiteral( "GeometryGroup" ) )
<< new StaticFunction( QStringLiteral( "inclination" ), ParameterList() << Parameter( QStringLiteral( "point_a" ) ) << Parameter( QStringLiteral( "point_b" ) ), fcnInclination, QStringList() << QStringLiteral( "Math" ) << QStringLiteral( "GeometryGroup" ) )
<< new StaticFunction( QStringLiteral( "project" ), ParameterList() << Parameter( QStringLiteral( "point" ) ) << Parameter( QStringLiteral( "distance" ) ) << Parameter( QStringLiteral( "azimuth" ) ) << Parameter( QStringLiteral( "elevation" ), true, M_PI / 2 ), fcnProject, QStringLiteral( "GeometryGroup" ) )
<< new StaticFunction( QStringLiteral( "abs" ), ParameterList() << Parameter( QStringLiteral( "value" ) ), fcnAbs, QStringLiteral( "Math" ) )
<< new StaticFunction( QStringLiteral( "cos" ), ParameterList() << Parameter( QStringLiteral( "angle" ) ), fcnCos, QStringLiteral( "Math" ) )
Expand Down
8 changes: 8 additions & 0 deletions tests/src/core/testqgsexpression.cpp
Expand Up @@ -817,6 +817,14 @@ class TestQgsExpression: public QObject
QTest::newRow( "project m value preserved" ) << "geom_to_wkt(project( make_point( 1, 2, 2, 5), 1, 0.0, 0.0 ) )" << false << QVariant( "PointZM (1 2 3 5)" );
QTest::newRow( "project 2D Point" ) << "geom_to_wkt(project( point:=make_point( 1, 2), distance:=1, azimuth:=radians(0), elevation:=0 ) )" << false << QVariant( "PointZ (1 2 1)" );
QTest::newRow( "project 3D Point" ) << "geom_to_wkt(project( make_point( 1, 2, 2), 5, radians(450), radians (450) ) )" << false << QVariant( "PointZ (6 2 2)" );
QTest::newRow( "inclination not geom first" ) << "inclination( 'a', make_point( 1, 2, 2 ) )" << true << QVariant();
QTest::newRow( "inclination not geom second" ) << " inclination( make_point( 1, 2, 2 ), 'a' )" << true << QVariant();
QTest::newRow( "inclination not point first" ) << "inclination( geom_from_wkt('LINESTRING(2 0,2 2, 3 2, 3 0)'), make_point( 1, 2, 2) )" << true << QVariant();
QTest::newRow( "inclination not point second" ) << " inclination( make_point( 1, 2, 2 ), geom_from_wkt('LINESTRING(2 0,2 2, 3 2, 3 0)') )" << true << QVariant();
QTest::newRow( "inclination" ) << "ceil(inclination( make_point( 159, 753, 460 ), make_point( 123, 456, 789 ) ))" << false << QVariant( 43.0 );
QTest::newRow( "inclination" ) << " inclination( make_point( 5, 10, 0 ), make_point( 5, 10, 5 ) )" << false << QVariant( 0.0 );
QTest::newRow( "inclination" ) << " inclination( make_point( 5, 10, 0 ), make_point( 5, 10, 0 ) )" << false << QVariant( 90.0 );
QTest::newRow( "inclination" ) << " inclination( make_point( 5, 10, 0 ), make_point( 5, 10, -5 ) )" << false << QVariant( 180.0 );
QTest::newRow( "extrude geom" ) << "geom_to_wkt(extrude( geom_from_wkt('LineString( 1 2, 3 2, 4 3)'),1,2))" << false << QVariant( "Polygon ((1 2, 3 2, 4 3, 5 5, 4 4, 2 4, 1 2))" );
QTest::newRow( "extrude not geom" ) << "extrude('g',5,6)" << true << QVariant();
QTest::newRow( "extrude null" ) << "extrude(NULL,5,6)" << false << QVariant();
Expand Down
12 changes: 12 additions & 0 deletions tests/src/core/testqgsgeometry.cpp
Expand Up @@ -919,6 +919,18 @@ void TestQgsGeometry::point()
QCOMPARE( p34.project( 5, 450 ), QgsPointV2( QgsWkbTypes::PointZM, 6, 2, 2, 5 ) );
QCOMPARE( p34.project( 5, 450, 450 ), QgsPointV2( QgsWkbTypes::PointZM, 6, 2, 2, 5 ) );

// inclination
QCOMPARE( QgsPointV2( 1, 2 ).inclination( QgsPointV2( 1, 2 ) ), 90.0 );
QCOMPARE( QgsPointV2( QgsWkbTypes::PointZ, 1, 1, 2, 0 ).inclination( QgsPointV2( QgsWkbTypes::PointZ, 1, 1, 2, 0 ) ), 90.0 );
QCOMPARE( QgsPointV2( QgsWkbTypes::PointZ, 1, 2, 2 ).inclination( QgsPointV2( QgsWkbTypes::PointZ, 1, 2, 2 ).project( 5, 90, 90 ) ), 90.0 );
QCOMPARE( QgsPointV2( QgsWkbTypes::PointZ, 1, 2, 2 ).inclination( QgsPointV2( QgsWkbTypes::PointZ, 1, 2, 2 ).project( 5, 90, -90 ) ), 90.0 );
QCOMPARE( QgsPointV2( QgsWkbTypes::PointZ, 1, 2, 2 ).inclination( QgsPointV2( QgsWkbTypes::PointZ, 1, 2, 2 ).project( 5, 90, 0 ) ), 0.0 );
QCOMPARE( QgsPointV2( QgsWkbTypes::PointZ, 1, 2, 2 ).inclination( QgsPointV2( QgsWkbTypes::PointZ, 1, 2, 2 ).project( 5, 90, 180 ) ), 180.0 );
QCOMPARE( QgsPointV2( QgsWkbTypes::PointZ, 1, 2, 2 ).inclination( QgsPointV2( QgsWkbTypes::PointZ, 1, 2, 2 ).project( 5, 90, -180 ) ), 180.0 );
QCOMPARE( QgsPointV2( QgsWkbTypes::PointZ, 1, 2, 2 ).inclination( QgsPointV2( QgsWkbTypes::PointZ, 1, 2, 2 ).project( 5, 90, 720 ) ), 0.0 );
QCOMPARE( QgsPointV2( QgsWkbTypes::PointZ, 1, 2, 2 ).inclination( QgsPointV2( QgsWkbTypes::PointZ, 1, 2, 2 ).project( 5, 90, 45 ) ), 45.0 );
QCOMPARE( QgsPointV2( QgsWkbTypes::PointZ, 1, 2, 2 ).inclination( QgsPointV2( QgsWkbTypes::PointZ, 1, 2, 2 ).project( 5, 90, 135 ) ), 135.0 );

}

void TestQgsGeometry::lineString()
Expand Down

0 comments on commit bc0c3a2

Please sign in to comment.