Неверные результаты стрелка (угол) к геолокации

У меня возник вопрос о том, как стрелка указывать на место. Это то, что у меня есть: enter image description here

Вы можете сохранить свое текущее местоположение в localstorage. Некоторое время спустя, когда вы, например, на 30 метров дальше, вы можете нажать на вторую кнопку "Показать направление в предыдущее место!" чтобы получить стрелку в предыдущее место. Это мобильный сайт, а не родное приложение.

Вот мой код:

<!DOCTYPE html>
<html>
    <head> 
        <!-- JQUERY SCRIPT AND COMPASS SCRIPT AND MODERNIZR SCRIPT -->
        <script src="http://code.jquery.com/jquery-1.8.3.js"></script>      
    </head>
    <body>
        <div class="container">
            <h1>Find your location</h1>
            <div class="row">
                <div class="span12">
                    <!-- Save your current location -->
                    <button class="grey" id="btnFindLocation">Save my current location!</button> <br>
                    <!-- Show direction to previous location -->
                    <button class="grey" id="btnShowDirection">Show direction to previous location!</button> <br><br>

                    <!-- Arrow in direction to location -->
                    <img id="myarrow" class="deviceorientation" src="http://nielsvroman.be/tapcrowd/arrow.png" />
            </div>
        </div>
        <script>
        $(window).ready(function(){
            // orientation object to save heading of the device 
            var orientation = {};
            /* Find location button */ 
            $("#btnFindLocation").click(findLocation);
            /* Show direction button */ 
            $("#btnShowDirection").click(showDirection);

            // Device orientation
            if (window.DeviceOrientationEvent) {
                window.addEventListener("deviceorientation", handleOrientation, false);
            }
            else{
                alert("Device Orientation is not available");
            }

            function handleOrientation(orientData)
            {
                var alpha = orientData.alpha;

                // To get the compass heading, one would simply subtract alpha from 360 degrees.
                var heading = 360 - alpha;
                orientation.value = heading;

            }

            function findLocation(){
                // Check if geolocation is supported in browser
                if (navigator.geolocation)
                {
                    // Succes function: geoSucces       Error function: geoError
                    navigator.geolocation.getCurrentPosition(geoSucces,geoError);  
                }
                else
                {
                    alert("Geolocation is not supported!");
                }
            }

            function geoSucces(position)
            {
                // Check if localstorage is supported in browser
                if (Modernizr.localstorage) 
                {   
                    // Object declaration in localStorage   
                    localStorage.setItem('position', '{}');
                    // Save position object in localstorage
                    localStorage.setItem('position', JSON.stringify(position));
                } 
                else 
                {   
                    alert("localStorage is not available!");
                }
            }

            var watchProcess = null;  
            function showDirection(){
                if (navigator.geolocation)
                {
                    if (watchProcess == null) {
                        // Succes function: geoWatchSucces      Error function: geoError
                        navigator.geolocation.watchPosition(geoWatchSucces,geoError);  
                    }
                }
                else
                {
                    alert("Geolocation is not supported!");
                }
            }

            function geoWatchSucces(position)
            {
                // Check if localStorage is supported in browser
                if (Modernizr.localstorage) 
                {   
                    // Get previous location out of localstorage
                    var location = JSON.parse(localStorage.getItem('position'));
                } 
                else 
                {   
                    alert("localStorage is not available!");
                }
                // lat/lon of location in localstorage and current location
                var lat1 = location.coords.latitude;
                var lon1 = location.coords.longitude;
                var lat2 = position.coords.latitude;
                var lon2 = position.coords.longitude;

                // angle to location
                var angle = Math.atan2(lon2 - lon1, lat2 - lat1);

                // degrees device 
                var degrees = orientation.value;

                // degrees of device - angle
                var result = degrees - angle;

                // Set arrow to direction location
                setArrowRotation(result);
            }

            // Stop monitoring location
            function stopShowDirection() {  
                if (navigator.geolocation)
                {
                    if (watchProcess != null)  
                    {  
                        navigator.geolocation.clearWatch(watchProcess);  
                        watchProcess = null;  
                    }  
                }
                else
                {
                    alert("Geolocation is not supported!");
                }
            }


            // Error function geolocation
            function geoError(error)
            {  
                switch(error.code)  
                {  
                    case error.PERMISSION_DENIED: alert("user did not share geolocation data");  
                    break;  
                    case error.POSITION_UNAVAILABLE: alert("could not detect current position");  
                    break;  
                    case error.TIMEOUT: alert("retrieving position timed out");  
                    break;  
                    default: alert("unknown error");  
                    break; 
                }  
            }

            // Functions to set direction arrow
            function getsupportedprop(proparray){
                var root=document.documentElement;
                for (var i=0; i<proparray.length; i++){
                    if (proparray[i] in root.style){
                        return proparray[i];
                    }
                }
                return false;
            }

            var cssTransform;
            function setArrowRotation(x){
                if(cssTransform===undefined){
                    cssTransform=getsupportedprop(['transform','webkitTransform','MozTransform','OTransform','msTransform']);
                }
                if(cssTransform){
                    document.getElementById('myarrow').style[cssTransform]='rotate('+x+'deg)';
                }
            }
        }); // END OF DOCUMENT READY

        </script>
    </body>
</html>

Что я делаю, чтобы установить стрелку в направлении предыдущего местоположения: - Функция вызова watchprocess - Получить lat/lon предыдущего местоположения + lat/lon текущего местоположения - Рассчитать угол до предыдущего местоположения - Проверьте степень мобильного устройства      - Я делаю это с событием deviceorientation, я читаю, что заголовок устройства = 360 - альфа (источник: http://dev.w3.org/geo/api/spec-source-orientation.html#introduction) - Конечный угол - это градусы мобильного устройства - предыдущий расчетный угол - установите стрелку с этим углом

Но я всегда получаю странные результаты... Когда мое предыдущее местоположение находится на расстоянии 10 метров, стрелка не подходит в большинстве случаев.

Кто-нибудь знает, почему я получаю этот результат?

Вот jsfiddle: jsfiddle

Спасибо заранее! Niels

Ответ 1

Вы пытались установить точность?

navigator.geolocation.getCurrentPosition(geoSucces,geoError, {enableHighAccuracy: true});

Ответ 2

Проверьте, достаточно ли достаточно, чтобы position.coords.accuracy была достаточно низкой на тестируемом устройстве. Вы можете просто столкнуться с очень неточными результатами широты и долготы.