Arrow pointing from a gps position to another not pointing in right direction in JavaScript

StackOverflow https://stackoverflow.com/questions/14651060

  •  06-03-2022
  •  | 
  •  

Question

I searched a lot on internet and also on stackoverflow, but somehow I cannot seem to get it right! I am trying to get an arrow to point from 1 GPS direction to another.

I have attached a test HTML which exactly explains my problem. I cannot get the arrow to point in the right direction, and I have no clue what I am doing wrong. It calculates the angle, and the arrow rotates in that angle, but it's not the correct angle, I do not get the result I am expecting.

Any help would be much appreciated.

map.png

arrow.png

<!DOCTYPE HTML>
<html>
<head>
    <title>Point to a direction test</title>
    <script>
        function getLocation() {
            var info = document.getElementById("info");
            if (navigator.geolocation) {
                navigator.geolocation.getCurrentPosition(calculateArrowRotation);
            }
            else {
                info.innerHTML = "Geolocation is not supported by this browser.";
            }
        }   

        function calculateArrowRotation(location) {
            // Point from here (Arc de Triomph, Paris)
            // var phoneLatitude = 48.873934;
            // var phoneLongitude = 2.2949;

            // Point from here (Gare du Nord, Paris)
            var phoneLatitude = 48.87977;
            var phoneLongitude = 2.355752;

            // Point to here (Musée du Louvre, Place du Carrousel, Paris, France)
            var destinationLatitude =  48.861519;
            var destinationLongitude = 2.3345495;

            var arrowAngle = bearing(phoneLatitude, phoneLongitude, destinationLatitude, destinationLongitude);

            var element = document.getElementById('arrow');
            element.style['transform'] = 'rotate(' + arrowAngle + 'deg)';

            var info = document.getElementById("info");
            info.innerHTML = "Longitude = " + phoneLongitude + "<br/>Latitude = " + phoneLatitude + "<br/>Arrow angle = " + arrowAngle;
        }

        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 360 - ((brng + 360) % 360);
        }

        function toRad(deg) {
             return deg * Math.PI / 180;
        }

        function toDeg(rad) {
            return rad * 180 / Math.PI;
        }           
    </script>
</head>
<body onload="getLocation()">
    <img id="map" src="map.png" style="position: absolute; top: 20; left: 20px;">
    <img id="arrow" src="arrow.png" style="position: absolute; top: 80px; left: 105px;">
    <div id="info" style="position: absolute; top: 340px; left: 20px; font-family:sans-serif; font-size:11px;"></div>       
</body>

Was it helpful?

Solution

Your final line in bearing serves to change the direction of the bearing from clockwise to anticlockwise.

You should just use

return (brng + 360) % 360;

In addition, you do realise that you're using hard-coded values in calculateArrowRotation() and that the input parameter location is never used, right?

Finally, your implementation of bearing is incorrect. That's not your fault though, the sites that list the implementations can be hazy on one important detail: Everything that you feed into the trig functions must have been converted to radians first:

function bearing(lat1,lng1,lat2,lng2) {
    var dLon = toRad(lng2-lng1);
    lat1 = toRad(lat1);
    lat2 = toRad(lat2);
    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;
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top