Incorrect results arrow (angle) to geolocation
Asked Answered
W

2

11

I have a question about showing an arrow to a location. This is what I have: enter image description here

You can save your current location in the localstorage. A while later when you are for example 30 meters further you can click on the second button "Show direction to previous location!" to get an arrow to your previous location. This is a mobile website, so not a native app.

Here is my code:

<!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>

What I do to set the arrow in the direction of the previous location is: - Call watchprocess function - Get lat/lon of previous location + lat/lon of current location - Calculate the angle to previous location - Check the degrees of the mobile device - I do this with the deviceorientation event, i read that the heading of the device = 360 - alpha (source: http://dev.w3.org/geo/api/spec-source-orientation.html#introduction) - The final angle is the degrees of the mobile device - the previous calculated angle - set arrow with that angle

But I always get strange results ... When my previous location is 10 meters further the arrow isn't correct for most of the times.

Does anyone knows why I get this result?

Here is a jsfiddle: jsfiddle

Thanks in advance! Niels

Wireman answered 17/5, 2013 at 8:17 Comment(1)
possible duplicate of Show arrow (angle) to a location considering the heading of the deviceRobalo
P
2

Have you tried setting the accuracy?

navigator.geolocation.getCurrentPosition(geoSucces,geoError, {enableHighAccuracy: true});
Parathyroid answered 27/5, 2013 at 11:58 Comment(1)
Yes. This are the accuracy results I get: When I click on "Save my location" I have an accuracy of 43.612.... When I click on "Show direction to previous location" I have an accuracy of 20 .... Is this the problem?Wireman
S
1

Check if position.coords.accuracy is low enough on the device your testing on. You might simply run into very inaccurate results of latitude and longitude.

Sidwel answered 25/5, 2013 at 10:53 Comment(2)
When I click on "Save my location" I have an accuracy of 43.612.... When I click on "Show direction to previous location" I have an accuracy of 20 .... Is this the problem?Wireman
You can check that fairly easy. Draw your 2 points in a map, then draw a circle with the radius of your accuracy. Your calculated angle may be any between any two points in your two circles.Sidwel

© 2022 - 2024 — McMap. All rights reserved.