Animated directional arrows "aroundMe" style using ngCordova
<p>I wish to create the compass / arrow exactly like the one we see in <strong><a href="http://www.aroundmeapp.com/">AroundMe Mobile App</a></strong> that point exactly to a pin to the map accordingly with my mobile position and update the arrow when I move the phone.</p>

<p>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.</p>

<p>What I found online is a bearing function and I created a directive around it: </p>

<pre><code>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)');
    }
  };

});
</code></pre>

<p>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 <code>magneticHeading</code> position.</p>

<p>So I added the <code>ngCordova</code> plugin for <strong>Device Orientation</strong> to get the <code>magneticHeading</code> and now I don't know exactly how to use it and where in the <code>bearing</code> function.</p>

<pre><code>  $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)');
  });
</code></pre>

<p>I tried to add it in the return statement:</p>

<pre><code>return (brng - heading) % 360;
</code></pre>

<p>or:</p>

<pre><code>return (heading - ((brng + 360) % 360));
</code></pre>

<p>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 <strong>N</strong> and it is pointing to <strong>E</strong>.</p>

<p>Always looking online I can not find any tutorial / question to find the bearing between a <code>lat/lng point</code> and a <code>magnetingHeading</code>.</p>

<p>Maybe I'm close to the solution but I can not go ahead alone.</p>

<p>I also tried to search for a mathematical formulas but even there is a huge pain to understand and implement it.</p>

<p>I hope you can help.</p>