Created
October 8, 2019 15:48
-
-
Save mattbontrager/5517cfc5b1b427f9eb514f40feb839a3 to your computer and use it in GitHub Desktop.
Calculate heading from progression of latitude and longitude.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Azimuth { | |
constructor() { | |
this.watchId = null; | |
this.latitude = null; | |
this.longitude = null; | |
this.latLon = (lat, lon) => { | |
this.latitude = lat; | |
this.longitude = lon; | |
}; | |
this.loc = { | |
origin: new this.latLon(null, null), | |
destination: new this.latLon(null, null) | |
}; | |
this.calculateBearing = () => { | |
// origination point latitude | |
const ϕ1 = this.loc.origin.latitude.toRadians(); | |
// origin point longitude | |
const λ1 = this.loc.origin.longitude; | |
// destination point latitude | |
const ϕ2 = this.loc.destination.latitude.toRadians(); | |
// destination point longitude | |
const λ2 = this.loc.destination.longitude; | |
// diff between longitudes (longitudinal delta) | |
const Δλ = (λ2 - λ1).toRadians(); | |
// y-axis angle in radians | |
const y = Math.sin(Δλ) * Math.cos(ϕ2); | |
// x-axis angle in radians | |
const x = Math.cos(ϕ1) * Math.sin(ϕ2) - Math.sin(ϕ1) * Math.cos(ϕ2) * Math.cos(Δλ); | |
// bearing in degrees (arc angle) | |
const θ = Math.atan2(y, x).toDegrees(); | |
// bearing - adjusted to translate positive and negative bearing/heading to the degrees of a compass/circle. | |
const β = (θ + 360) % 360; | |
return β; | |
}; | |
this.setCoords = data => { | |
const { coords } = data; | |
// set previous lat/lon as current (stored) lat/lon | |
this.loc.origin.latitude = this.loc.destination.latitude; | |
this.loc.origin.longitude = this.loc.destination.longitude; | |
// set current lat/lon with current system-provided location data | |
this.loc.destination.latitude = coords.latitude; | |
this.loc.destination.longitude = coords.longitude; | |
!!this.loc.origin.latitude && this.calculateBearing(); | |
}; | |
this.doLocation = () => { | |
// location is a reserved keyword | |
navigator.geolocation.getCurrentPosition(lokation => { | |
if (!lokation.corrds) { | |
this.stopWatchingLocation(); | |
} | |
this.setCoords(lokation); | |
}, this.stopWatchingLocation); | |
}; | |
this.startWatchingLocation = () => { | |
this.watchID = setInterval(doLocation, 2000); | |
}; | |
this.stopWatchingLocation = err => { | |
clearInterval(this.watchID); | |
if (err && err.error && err.error.code && err.error.message) { | |
console.error(err.error.code + ' ' + err.error.message); | |
} | |
return false; | |
}; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment