# Source code for turf.rhumb_bearing._rhumb_bearing

```from math import fmod
from typing import Dict, Sequence, Union

import numpy as np

from turf.helpers import Feature
from turf.invariant import get_coords_from_features

[docs]def rhumb_bearing(
origin: Union[Sequence, Dict, Feature],
destination: Union[Sequence, Dict, Feature],
options: Dict = None,
) -> float:
"""
Takes two {Point|points} and finds the bearing angle between them along a
Rhumb line
* i.e. the angle measured in degrees start the north line (0 degrees)

https://en.wikipedia.org/wiki/Rhumb_line

:param start: starting point [lng, lat] or Point feature
:param end: ending point [lng, lat] or Point feature
:param options: Optional parameters
[options["final"]]: Calculates the final bearing if True

:return: bearing from north in decimal degrees
"""
if not isinstance(options, dict):
options = {}

origin = get_coords_from_features(origin, ["Point"])
destination = get_coords_from_features(destination, ["Point"])
final = options.get("final", False)

if final:
bearing = calculate_rhumb_bearing(destination, origin)
else:
bearing = calculate_rhumb_bearing(origin, destination)

return bearing

def calculate_rhumb_bearing(origin: Sequence, destination: Sequence) -> float:
"""
Calculates the bearing from origin to destination point along a rhumb line.
http://www.edwilliams.org/avform.htm#Rhumb
"""
delta_lambda = degrees_to_radians(destination - origin)

# if delta_lambda over 180° take shorter rhumb line across the anti-meridian:
if abs(delta_lambda) > np.pi:
if delta_lambda > 0:
delta_lambda = -(2 * np.pi - delta_lambda)
if delta_lambda < 0:
delta_lambda = 2 * np.pi + delta_lambda

delta_psi = np.log(np.tan(phi_2 / 2 + np.pi / 4) / np.tan(phi_1 / 2 + np.pi / 4))
theta = np.arctan2(delta_lambda, delta_psi)

return fmod(radians_to_degrees(theta) + 360, 360)
```