I am attempting to recreate a compass or arrow similar to the one featured in the AroundMe Mobile App. This arrow should accurately point towards a pin on the map based on my mobile device's position and update as I move.
I have been struggling to figure out how to achieve this functionality and have not been able to find any comprehensive guides or tutorials on the topic.
My research led me to a bearing function, which I incorporated into a directive:
app.directive('arrow', function () {
function bearing(lat1, lng1, lat2, lng2) {
var dLon = (lng2 - lng1);
var y = Math.sin(dLon) * Math.cos(lat2);
var x = Math.cos(lat1) * Math.sin(lat2) - Math.sin(lat1) * Math.cos(lat2) * Math.cos(dLon);
var rad = Math.atan2(y, x);
var brng = toDeg(rad);
return (brng + 360) % 360;
}
function toRad(deg) {
return deg * Math.PI / 180;
}
function toDeg(rad) {
return rad * 180 / Math.PI;
}
return {
restrict: 'E',
link: function (scope, element, attrs) {
var arrowAngle = bearing(scope.user.position.lat, scope.user.position.lng, attrs.lat, attrs.lng);
element.parent().css('transform', 'rotate(' + arrowAngle + 'deg)');
}
};
});
Although this code updates the arrow direction, it does not take into account the mobile device's magnetic heading information.
To address this, I included the ngCordova
plugin for Device Orientation to retrieve the magneticHeading
, but I am unsure of how to incorporate it into the existing bearing
function.
$cordovaDeviceOrientation.getCurrentHeading().then(function(result) {
var magneticHeading = result.magneticHeading;
var arrowAngle = bearing(scope.user.position.lat, scope.user.position.lng, attrs.lat, attrs.lng, magneticHeading);
element.parent().css('transform', 'rotate(' + arrowAngle + 'deg)');
});
I attempted to modify the return statement as follows:
return (brng - heading) % 360;
or:
return (heading - ((brng + 360) % 360));
Despite implementing this code with a watcher, the arrow is not pointing in the correct direction; for instance, it should be facing North but instead points East.
After extensive online searches, I have not found any resources detailing how to calculate the bearing between a lat/lng point
and a magneticHeading
.
I feel like I may be close to a solution, but I am unable to progress further independently.
In my attempts to resolve the issue, I have also looked into mathematical formulas, but understanding and implementing them has proven challenging.
Your assistance would be greatly appreciated.