I wish to create the compass / arrow exactly like the one we see in AroundMe Mobile App that point exactly to a pin to the map accordingly with my mobile position and update the arrow when I move the phone.
I'm getting crazy to understand exactly how to do that and I can not find any guide or tutorial that explain a bit it.
What I found online is a bearing function and I created a directive around it:
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)');
}
};
});
It seems to update the arrow in a direction but unfortunately it is not the right direction because it is not calculated using also the mobile magneticHeading
position.
So I added the ngCordova
plugin for Device Orientation to get the magneticHeading
and now I don't know exactly how to use it and where in the 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 tried to add it in the return statement:
return (brng - heading) % 360;
or:
return (heading - ((brng + 360) % 360));
Implementing this code with a watcher I see the arrow moving but not in the exact position... For example from my position and the pin the arrow should point to N and it is pointing to E.
Always looking online I can not find any tutorial / question to find the bearing between a lat/lng point
and a magnetingHeading
.
Maybe I'm close to the solution but I can not go ahead alone.
I also tried to search for a mathematical formulas but even there is a huge pain to understand and implement it.
I hope you can help.
navigator.geolocation.watchPosition(function(position){ var heading = position.coords.heading;});
– Gratianareturn (brng - heading - 90) % 360;
– Casto