diff --git a/src/getAngle.test.js b/src/getAngle.test.js new file mode 100644 index 0000000..25f6b9c --- /dev/null +++ b/src/getAngle.test.js @@ -0,0 +1,23 @@ +import getAngle from './getAngle'; + +describe('getRhumbLineBearing is not the same as Angle', () => { + it('should return a bearing between two points in degrees', () => { + expect( + getAngle( + { latitude: 39.778889, longitude: -104.9825 }, + { latitude: 43.778889, longitude: -102.9825 } + ) + ).not.toEqual(20.438617005368314); // will return 19 + }); +}); + +describe('getAngle is not the same as Angle', () => { + it('should return a bearing between two points in degrees', () => { + expect( + getAngle( + { latitude: -2.584148, longitude: -44.243597 }, + { latitude: -2.584136, longitude: -44.243574 } + ) + ).toEqual(62); + }); +}); diff --git a/src/getAngle.ts b/src/getAngle.ts new file mode 100644 index 0000000..ec478db --- /dev/null +++ b/src/getAngle.ts @@ -0,0 +1,36 @@ +import getLatitude from './getLatitude'; +import getLongitude from './getLongitude'; +import { GeolibInputCoordinates } from './types'; + +// Converts from degrees to radians. +function toRadians(degrees) { + return degrees * Math.PI / 180; +}; +// Converts from radians to degrees. +function toDegrees(radians) { + return radians * 180 / Math.PI; +}; + +// Calculates the angle based on the line of two points. +const getAngle = ( + from: GeolibInputCoordinates, + to: GeolibInputCoordinates, + accuracy: number = 1 +) => { + + const fromLat = toRadians(getLatitude(from)); + const fromLon = toRadians(getLongitude(from)); + const toLat = toRadians(getLatitude(to)); + const toLon = toRadians(getLongitude(to)); + + let y = Math.sin(toLon - fromLon) * Math.cos(toLat); + let x = Math.cos(fromLat) * Math.sin(toLat) - + Math.sin(fromLat) * Math.cos(toLat) * Math.cos(toLon - fromLon); + let bearing = Math.atan2(y, x); + bearing = toDegrees(bearing); + bearing = (bearing + 360) % 360; + return parseInt(bearing || 0); + +}; + +export default getAngle;