Skip to content

Instantly share code, notes, and snippets.

@mattbontrager
Created October 8, 2019 15:48
Show Gist options
  • Save mattbontrager/5517cfc5b1b427f9eb514f40feb839a3 to your computer and use it in GitHub Desktop.
Save mattbontrager/5517cfc5b1b427f9eb514f40feb839a3 to your computer and use it in GitHub Desktop.
Calculate heading from progression of latitude and longitude.
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