@@ -2082,6 +2082,77 @@ static QVariant fcnGeomToWKT( const QVariantList& values, const QgsExpressionCon
2082
2082
return QVariant ( wkt );
2083
2083
}
2084
2084
2085
+ static QVariant fcnAzimuth ( const QVariantList& values, const QgsExpressionContext *, QgsExpression* parent )
2086
+ {
2087
+ if ( values.length () != 2 )
2088
+ {
2089
+ parent->setEvalErrorString ( QObject::tr ( " Function `azimuth` requires exactly two parameters. %1 given." ).arg ( values.length () ) );
2090
+ return QVariant ();
2091
+ }
2092
+
2093
+ QgsGeometry fGeom1 = getGeometry ( values.at ( 0 ), parent );
2094
+ QgsGeometry fGeom2 = getGeometry ( values.at ( 1 ), parent );
2095
+
2096
+ const QgsPointV2* pt1 = dynamic_cast <const QgsPointV2*>( fGeom1 .geometry () );
2097
+ const QgsPointV2* pt2 = dynamic_cast <const QgsPointV2*>( fGeom2 .geometry () );
2098
+
2099
+ if ( !pt1 || !pt2 )
2100
+ {
2101
+ parent->setEvalErrorString ( QObject::tr ( " Function `azimuth` requires two points as arguments." ) );
2102
+ return QVariant ();
2103
+ }
2104
+
2105
+ // Code from postgis
2106
+ if ( pt1->x () == pt2->x () )
2107
+ {
2108
+ if ( pt1->y () < pt2->y () )
2109
+ return 0.0 ;
2110
+ else if ( pt1->y () > pt2->y () )
2111
+ return M_PI;
2112
+ else return 0 ;
2113
+ return 1 ;
2114
+ }
2115
+
2116
+ if ( pt1->y () == pt2->y () )
2117
+ {
2118
+ if ( pt1->x () < pt2->x () )
2119
+ return M_PI / 2 ;
2120
+ else if ( pt1->x () > pt2->x () )
2121
+ return M_PI + ( M_PI / 2 );
2122
+ else return 0 ;
2123
+ return 1 ;
2124
+ }
2125
+
2126
+ if ( pt1->x () < pt2->x () )
2127
+ {
2128
+ if ( pt1->y () < pt2->y () )
2129
+ {
2130
+ return atan ( fabs ( pt1->x () - pt2->x () ) / fabs ( pt1->y () - pt2->y () ) );
2131
+ }
2132
+ else /* ( pt1->y() > pt2->y() ) - equality case handled above */
2133
+ {
2134
+ return atan ( fabs ( pt1->y () - pt2->y () ) / fabs ( pt1->x () - pt2->x () ) )
2135
+ + ( M_PI / 2 );
2136
+ }
2137
+ }
2138
+
2139
+ else /* ( pt1->x() > pt2->x() ) - equality case handled above */
2140
+ {
2141
+ if ( pt1->y () > pt2->y () )
2142
+ {
2143
+ return atan ( fabs ( pt1->x () - pt2->x () ) / fabs ( pt1->y () - pt2->y () ) )
2144
+ + M_PI;
2145
+ }
2146
+ else /* ( pt1->y() < pt2->y() ) - equality case handled above */
2147
+ {
2148
+ return atan ( fabs ( pt1->y () - pt2->y () ) / fabs ( pt1->x () - pt2->x () ) )
2149
+ + ( M_PI + ( M_PI / 2 ) );
2150
+ }
2151
+ }
2152
+
2153
+ return QVariant ();
2154
+ }
2155
+
2085
2156
static QVariant fcnRound ( const QVariantList& values, const QgsExpressionContext *, QgsExpression* parent )
2086
2157
{
2087
2158
if ( values.length () == 2 )
@@ -2700,6 +2771,7 @@ const QList<QgsExpression::Function*>& QgsExpression::Functions()
2700
2771
<< new StaticFunction ( " sqrt" , 1 , fcnSqrt, " Math" )
2701
2772
<< new StaticFunction ( " radians" , 1 , fcnRadians, " Math" )
2702
2773
<< new StaticFunction ( " degrees" , 1 , fcnDegrees, " Math" )
2774
+ << new StaticFunction ( " azimuth" , 2 , fcnAzimuth, " Math" )
2703
2775
<< new StaticFunction ( " abs" , 1 , fcnAbs, " Math" )
2704
2776
<< new StaticFunction ( " cos" , 1 , fcnCos, " Math" )
2705
2777
<< new StaticFunction ( " sin" , 1 , fcnSin, " Math" )
0 commit comments