All files haversine.ts

100% Statements 30/30
100% Branches 0/0
100% Functions 7/7
100% Lines 30/30
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 1041x     1x   1x       9x 9x                   2x   2x                   2x   2x                   2x   2x                 4x 4x   4x 4x   4x                 8x 8x   8x 8x   8x     8x   8x                 8x 8x   8x 8x     8x 8x     8x    
import { Util } from './util';
import { GpsPoint } from './gpsPoint';
 
const wgs84 = require('wgs84');
 
export class Haversine {
    private origin: GpsPoint;
    private R: number;
    constructor(origin: GpsPoint) {
        this.R = wgs84.RADIUS;
        this.origin = origin;
    }
 
    /**
     * Get the distance of the next point relative to the origin
     * @param origin the origin gps coordinate
     * @param next next gps coordinate
     * @returns distance in meter (m)
     */
    static getDistance(origin: GpsPoint, next: GpsPoint): number {
        const haversine = new Haversine(origin);
 
        return haversine.getDistance(next);
    }
 
    /**
     * Get the bearing of the next point relative to the origin
     * @param origin the origin gps coordinate
     * @param next next gps coordinate
     * @returns bearing in degree (deg)
     */
    static getBearing(origin: GpsPoint, next: GpsPoint): number {
        const haversine = new Haversine(origin);
 
        return haversine.getBearing(next);
    }
 
    /**
     * Get the next gps coordinate position relative to the origin
     * @param origin the origin gps coordinate
     * @param next the next gps coordinate
     * @returns [x, y] in meter (m) relative to the origin
     */
    static getPosition(origin: GpsPoint, next: GpsPoint): number {
        const haversine = new Haversine(origin);
 
        return haversine.getPosition(next);
    }
 
    /**
     * Get the next gps coordinate position relative to the origin
     * @param next the next gps coordinate
     * @returns [x, y] in meter (m) relative to the origin
     */
    getPosition(next: GpsPoint): any {
        const distance = this.getDistance(next);
        const bearing = this.getBearing(next);
 
        const x = distance * Math.sin(Util.toRadian(bearing));
        const y = distance * Math.cos(Util.toRadian(bearing));
 
        return [x, y];
    }
 
    /**
     * Get the distance of the next point relative to the origin
     * @param next next gps coordinate
     * @returns distance in meter (m)
     */
    getDistance(next: GpsPoint): number {
        const dLat = Util.toRadian(next.lat - this.origin.lat);
        const dLong = Util.toRadian(next.lng - this.origin.lng);
 
        const lat1 = Util.toRadian(this.origin.lat);
        const lat2 = Util.toRadian(next.lat);
 
        const a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
                Math.sin(dLong/ 2) * Math.sin(dLong / 2) * Math.cos(lat1) * Math.cos(lat2);
 
        const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
 
        return this.R * c;
    }
 
    /**
     * Get the bearing of the next point relative to the origin
     * @param next next gps coordinate
     * @returns bearing in degree (deg)
     */
    getBearing(next: GpsPoint): number {
        const lat1 = Util.toRadian(this.origin.lat);
        const lat2 = Util.toRadian(next.lat);
 
        const long1 = Util.toRadian(this.origin.lng);
        const long2 = Util.toRadian(next.lng);
 
 
        const y = Math.sin(long2 - long1) * Math.cos(lat2);
        const x = Math.cos(lat1) * Math.sin(lat2) -
                Math.sin(lat1) * Math.cos(lat2) * Math.cos(long2 - long1);
 
        return (Util.toDegree(Math.atan2(y, x)) + 360) % 360;
    }
}