Skip to content

Commit bc0c3a2

Browse files
lbartolettinyalldawson
authored andcommitted
Add inclination method for QgsPointV2 (#4536)
1 parent c620c7c commit bc0c3a2

File tree

6 files changed

+66
-0
lines changed

6 files changed

+66
-0
lines changed

python/core/geometry/qgspointv2.sip

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,14 @@ class QgsPointV2: QgsAbstractGeometry
234234
:rtype: float
235235
%End
236236

237+
double inclination( const QgsPointV2 &other ) const;
238+
%Docstring
239+
Calculates inclination between this point and other one (starting from zenith = 0 to nadir = 180. Horizon = 90)
240+
Returns 90.0 if the distance between this point and other one is equal to 0 (same point).
241+
.. versionadded:: 3.0
242+
:rtype: float
243+
%End
244+
237245
QgsPointV2 project( double distance, double azimuth, double inclination = 90.0 ) const;
238246
%Docstring
239247
Returns a new point which correspond to this point projected by a specified distance

src/core/geometry/qgspointv2.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -485,6 +485,17 @@ double QgsPointV2::azimuth( const QgsPointV2 &other ) const
485485
return ( atan2( dx, dy ) * 180.0 / M_PI );
486486
}
487487

488+
double QgsPointV2::inclination( const QgsPointV2 &other ) const
489+
{
490+
double distance = distance3D( other );
491+
if ( qgsDoubleNear( distance, 0.0 ) )
492+
{
493+
return 90.0;
494+
}
495+
double dz = other.z() - mZ;
496+
497+
return ( acos( dz / distance ) * 180.0 / M_PI );
498+
}
488499

489500
QgsPointV2 QgsPointV2::project( double distance, double azimuth, double inclination ) const
490501
{

src/core/geometry/qgspointv2.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,13 @@ class CORE_EXPORT QgsPointV2: public QgsAbstractGeometry
243243
*/
244244
double azimuth( const QgsPointV2 &other ) const;
245245

246+
/**
247+
* Calculates inclination between this point and other one (starting from zenith = 0 to nadir = 180. Horizon = 90)
248+
* Returns 90.0 if the distance between this point and other one is equal to 0 (same point).
249+
* \since QGIS 3.0
250+
*/
251+
double inclination( const QgsPointV2 &other ) const;
252+
246253
/** Returns a new point which correspond to this point projected by a specified distance
247254
* with specified angles (azimuth and inclination).
248255
* M value is preserved.

src/core/qgsexpression.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2921,6 +2921,25 @@ static QVariant fcnProject( const QVariantList &values, const QgsExpressionConte
29212921
return QVariant::fromValue( QgsGeometry( new QgsPointV2( newPoint ) ) );
29222922
}
29232923

2924+
static QVariant fcnInclination( const QVariantList &values, const QgsExpressionContext *, QgsExpression *parent )
2925+
{
2926+
QgsGeometry fGeom1 = getGeometry( values.at( 0 ), parent );
2927+
QgsGeometry fGeom2 = getGeometry( values.at( 1 ), parent );
2928+
2929+
const QgsPointV2 *pt1 = dynamic_cast<const QgsPointV2 *>( fGeom1.geometry() );
2930+
const QgsPointV2 *pt2 = dynamic_cast<const QgsPointV2 *>( fGeom2.geometry() );
2931+
2932+
if ( ( fGeom1.type() != QgsWkbTypes::PointGeometry ) || ( fGeom2.type() != QgsWkbTypes::PointGeometry ) ||
2933+
!pt1 || !pt2 )
2934+
{
2935+
parent->setEvalErrorString( QStringLiteral( "Function 'inclination' requires two points as arguments." ) );
2936+
return QVariant();
2937+
}
2938+
2939+
return pt1->inclination( *pt2 );
2940+
2941+
}
2942+
29242943
static QVariant fcnExtrude( const QVariantList &values, const QgsExpressionContext *, QgsExpression *parent )
29252944
{
29262945
if ( values.length() != 3 )
@@ -3933,6 +3952,7 @@ const QList<QgsExpression::Function *> &QgsExpression::Functions()
39333952
<< new StaticFunction( QStringLiteral( "radians" ), ParameterList() << Parameter( QStringLiteral( "degrees" ) ), fcnRadians, QStringLiteral( "Math" ) )
39343953
<< new StaticFunction( QStringLiteral( "degrees" ), ParameterList() << Parameter( QStringLiteral( "radians" ) ), fcnDegrees, QStringLiteral( "Math" ) )
39353954
<< new StaticFunction( QStringLiteral( "azimuth" ), ParameterList() << Parameter( QStringLiteral( "point_a" ) ) << Parameter( QStringLiteral( "point_b" ) ), fcnAzimuth, QStringList() << QStringLiteral( "Math" ) << QStringLiteral( "GeometryGroup" ) )
3955+
<< new StaticFunction( QStringLiteral( "inclination" ), ParameterList() << Parameter( QStringLiteral( "point_a" ) ) << Parameter( QStringLiteral( "point_b" ) ), fcnInclination, QStringList() << QStringLiteral( "Math" ) << QStringLiteral( "GeometryGroup" ) )
39363956
<< new StaticFunction( QStringLiteral( "project" ), ParameterList() << Parameter( QStringLiteral( "point" ) ) << Parameter( QStringLiteral( "distance" ) ) << Parameter( QStringLiteral( "azimuth" ) ) << Parameter( QStringLiteral( "elevation" ), true, M_PI / 2 ), fcnProject, QStringLiteral( "GeometryGroup" ) )
39373957
<< new StaticFunction( QStringLiteral( "abs" ), ParameterList() << Parameter( QStringLiteral( "value" ) ), fcnAbs, QStringLiteral( "Math" ) )
39383958
<< new StaticFunction( QStringLiteral( "cos" ), ParameterList() << Parameter( QStringLiteral( "angle" ) ), fcnCos, QStringLiteral( "Math" ) )

tests/src/core/testqgsexpression.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -817,6 +817,14 @@ class TestQgsExpression: public QObject
817817
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)" );
818818
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)" );
819819
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)" );
820+
QTest::newRow( "inclination not geom first" ) << "inclination( 'a', make_point( 1, 2, 2 ) )" << true << QVariant();
821+
QTest::newRow( "inclination not geom second" ) << " inclination( make_point( 1, 2, 2 ), 'a' )" << true << QVariant();
822+
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();
823+
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();
824+
QTest::newRow( "inclination" ) << "ceil(inclination( make_point( 159, 753, 460 ), make_point( 123, 456, 789 ) ))" << false << QVariant( 43.0 );
825+
QTest::newRow( "inclination" ) << " inclination( make_point( 5, 10, 0 ), make_point( 5, 10, 5 ) )" << false << QVariant( 0.0 );
826+
QTest::newRow( "inclination" ) << " inclination( make_point( 5, 10, 0 ), make_point( 5, 10, 0 ) )" << false << QVariant( 90.0 );
827+
QTest::newRow( "inclination" ) << " inclination( make_point( 5, 10, 0 ), make_point( 5, 10, -5 ) )" << false << QVariant( 180.0 );
820828
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))" );
821829
QTest::newRow( "extrude not geom" ) << "extrude('g',5,6)" << true << QVariant();
822830
QTest::newRow( "extrude null" ) << "extrude(NULL,5,6)" << false << QVariant();

tests/src/core/testqgsgeometry.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -919,6 +919,18 @@ void TestQgsGeometry::point()
919919
QCOMPARE( p34.project( 5, 450 ), QgsPointV2( QgsWkbTypes::PointZM, 6, 2, 2, 5 ) );
920920
QCOMPARE( p34.project( 5, 450, 450 ), QgsPointV2( QgsWkbTypes::PointZM, 6, 2, 2, 5 ) );
921921

922+
// inclination
923+
QCOMPARE( QgsPointV2( 1, 2 ).inclination( QgsPointV2( 1, 2 ) ), 90.0 );
924+
QCOMPARE( QgsPointV2( QgsWkbTypes::PointZ, 1, 1, 2, 0 ).inclination( QgsPointV2( QgsWkbTypes::PointZ, 1, 1, 2, 0 ) ), 90.0 );
925+
QCOMPARE( QgsPointV2( QgsWkbTypes::PointZ, 1, 2, 2 ).inclination( QgsPointV2( QgsWkbTypes::PointZ, 1, 2, 2 ).project( 5, 90, 90 ) ), 90.0 );
926+
QCOMPARE( QgsPointV2( QgsWkbTypes::PointZ, 1, 2, 2 ).inclination( QgsPointV2( QgsWkbTypes::PointZ, 1, 2, 2 ).project( 5, 90, -90 ) ), 90.0 );
927+
QCOMPARE( QgsPointV2( QgsWkbTypes::PointZ, 1, 2, 2 ).inclination( QgsPointV2( QgsWkbTypes::PointZ, 1, 2, 2 ).project( 5, 90, 0 ) ), 0.0 );
928+
QCOMPARE( QgsPointV2( QgsWkbTypes::PointZ, 1, 2, 2 ).inclination( QgsPointV2( QgsWkbTypes::PointZ, 1, 2, 2 ).project( 5, 90, 180 ) ), 180.0 );
929+
QCOMPARE( QgsPointV2( QgsWkbTypes::PointZ, 1, 2, 2 ).inclination( QgsPointV2( QgsWkbTypes::PointZ, 1, 2, 2 ).project( 5, 90, -180 ) ), 180.0 );
930+
QCOMPARE( QgsPointV2( QgsWkbTypes::PointZ, 1, 2, 2 ).inclination( QgsPointV2( QgsWkbTypes::PointZ, 1, 2, 2 ).project( 5, 90, 720 ) ), 0.0 );
931+
QCOMPARE( QgsPointV2( QgsWkbTypes::PointZ, 1, 2, 2 ).inclination( QgsPointV2( QgsWkbTypes::PointZ, 1, 2, 2 ).project( 5, 90, 45 ) ), 45.0 );
932+
QCOMPARE( QgsPointV2( QgsWkbTypes::PointZ, 1, 2, 2 ).inclination( QgsPointV2( QgsWkbTypes::PointZ, 1, 2, 2 ).project( 5, 90, 135 ) ), 135.0 );
933+
922934
}
923935

924936
void TestQgsGeometry::lineString()

0 commit comments

Comments
 (0)