How to adjust the distance between location updates (Windows Store apps using JavaScript and HTML)

Language: JavaScript and HTML | VB/C#/C++ and XAML
0 out of 1 rated this helpful - Rate this topic

. Some apps need location updates only when the user has moved a large distance. This topic shows you how to create an app that lets the user adjust the distance between location updates. This distance is known as the movement threshold, and is the minimum change in position required to raise a location update event. By implementing a movement threshold, you can create an app that provides only local information, like news or weather, and may not need location updates unless the user's location has changed to a different city.

The code in this app updates a table each time a location update event is raised, by adding a row that contains the new coordinates and the distance that the user has moved since the last update. The distance moved is calculated with the haversine formula.

If a movement threshold is entered in the input box, you'll be able to see that the distanced moved each time an event is raised is always below the movement threshold.

What you need to know

Technologies

  • Windows Runtime

Prerequisites

  • You should be familiar with HTML and JavaScript.

Instructions

Step 1: Verify that location is enabled

Open Control Panel, choose Privacy, and set Allow apps to use my location to On.

Step 2: Open Microsoft Visual Studio 2012

Open an instance of Microsoft Visual Studio 2012.

Step 3: Create a New Project

In the New Project dialog box, choose a Blank Application from the JavaScript project types.

Step 4: Declare the Location Capability

Double click on package.appxmanifest in solution explorer. Select the Capabilities tab. Check Location in the Capabilities list.

Step 5: Insert the Application JavaScript and HTML

Open your file Default.html and copy the following HTML into this file (replacing its original contents).



<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>Movement Threshold Sample</title>
    <script src="/js/default.js"></script>
    <!-- WinJS references -->
    <link rel="stylesheet" href="/winjs/css/ui-light.css" />
    <script type="text/javascript">

</script>
</head>
<body>
<span>Geolocation Event Sample</span><br />
<span id="MovementThresholdLabel">Movement Threshold in meters:</span><br />
<input id ="threshold" type="text"/><br />
<input type="button" onclick="trackloc()" value="Track Location" /><br />
<input type="button" onclick="stoptracking()" value="Stop Tracking" /><br />

<table style="border: solid; width:auto" >
  <thead><tr><th>Latitude</th><th>Longitude</th><th>Distance (meters)</th></tr></thead>    
  <tbody id="inputtable">      
    <tr>
    </tr>    
  </tbody>  
</table>
<div id="geolocatorStatus"></div> 
</body>
</html>


Step 6: Insert the code for creating the Geolocator and handling position updates

Insert the following code in the /js/Default.js file, overwriting its original contents.


var eventCount = 0; // The number of positionchanged events that have been raised.
var loc = null;

// Create the Geolocator, set movementThreshold if specified,
// and subscribe to events.
function trackloc() {
    if (loc == null) {
        loc = new Windows.Devices.Geolocation.Geolocator();
    }
    if (loc != null) {
        // Set movementThreshold
        var threshold = document.getElementById("threshold").value;
        if (threshold >= 0) {
            loc.movementThreshold = threshold;
        }
        loc.addEventListener("positionchanged", onPositionChanged);
        loc.addEventListener("statuschanged", onStatusChanged);
    }
    else {
        document.getElementById('status').innerHTML = "Geolocator not found.";
    }
}

function stoptracking() {
    if (loc != null) {
        loc.removeEventListener("positionchanged", onPositionChanged);
    }
}
function onPositionChanged(args) {
    eventCount = eventCount + 1;
    var pos = args.position;
    addLatLong(pos.coordinate.latitude, pos.coordinate.longitude);
}

Step 7: Insert the code for updating the HTML table

Paste the following code into the Default.js file, after the code you inserted in the previous step.


// Add a table row containing the coordinates and distance moved.
function addLatLong(lat, long) {
    tabBody = document.getElementById("inputtable");
    row = document.createElement("TR");

    // First cell - latitude.
    cell1 = document.createElement("TD");
    cell1.innerHTML = lat;
    cell1.id = "latitude" + eventCount;
    row.appendChild(cell1);
    // Second cell - longitude.
    cell2 = document.createElement("TD");
    cell2.innerHTML = long;
    cell2.id = "longitude" + eventCount;
    row.appendChild(cell2);
    // Third cell - distance
    cell3 = document.createElement("TD");
    cell3.id = "distance" + eventCount;
    if (eventCount < 2) {
        cell3.innerHTML = "0";
    }
    else {
        var prevLat = document.getElementById("latitude" + (eventCount - 1)).innerHTML;
        var prevLong = document.getElementById("longitude" + (eventCount - 1)).innerHTML;
        // multiply Distance by 1000 to get meters from km
        cell3.innerHTML = Distance(prevLat, prevLong, lat, long) * 1000;
    }
    row.appendChild(cell3);
    tabBody.appendChild(row);
}

Step 8: Insert code for calculating distance

Insert this code in Default.js, after the code you inserted in the previous step. It calculates distance using the haversine formula.


// Calculates distance between two latitude/longitude coordinates in km,
// based on the haversine formula.
function Distance(prevLat, prevLong, currLat, currLong) {
    // KNOWN CONSTANTS
    var degreesToRadians = Math.PI / 180;
    var earthRadius = 6371; // approximation in kilometers assuming earth to be spherical
    // CONVERT LATITUDE AND LONGITUDE VALUES TO RADIANS
    var previousRadianLat = prevLat * degreesToRadians;
    var previousRadianLong = prevLong * degreesToRadians;
    var currentRadianLat = currLat * degreesToRadians;
    var currentRadianLong = currLong * degreesToRadians;
    // CALCULATE RADIAN DELTA BETWEEN THE TWO POSITIONS
    var latitudeRadianDelta = currentRadianLat - previousRadianLat;
    var longitudeRadianDelta = currentRadianLong - previousRadianLong;
    var expr1 = (Math.sin(latitudeRadianDelta / 2) * Math.sin(latitudeRadianDelta / 2)) +
                (Math.cos(previousRadianLat) * Math.cos(currentRadianLat) * Math.sin(longitudeRadianDelta / 2) * Math.sin(longitudeRadianDelta / 2));
    var expr2 = 2 * Math.atan2(Math.sqrt(expr1), Math.sqrt(1 - expr1));
    var distanceValue = earthRadius * expr2;
    return distanceValue;
}



Step 9: Insert code to display status messages

Insert the following code for displaying status messages in Default.js, after the code you inserted in the previous step.


// Handle change in status to display an appropriate message.
function onStatusChanged(args) {
    var newStatus = args.status;
    document.getElementById('geolocatorStatus').innerHTML =
                getStatusString(newStatus);
}

function getStatusString(locStatus) {
    switch (locStatus) {
        case Windows.Devices.Geolocation.PositionStatus.ready:
            // Location data is available
            return "Location is available.";
            break;
        case Windows.Devices.Geolocation.PositionStatus.initializing:
            // This status indicates that a GPS is still acquiring a fix
            return "A GPS device is still initializing.";
            break;
        case Windows.Devices.Geolocation.PositionStatus.noData:
            // No location data is currently available
            return "Data from location services is currently unavailable.";
            break;
        case Windows.Devices.Geolocation.PositionStatus.disabled:
            // The app doesn't have permission to access location,
            // either because location has been turned off.
            return "Your location is currently turned off. " +
                        "Change your settings through the Settings charm " +
                        " to turn it back on.";
            break;
        case Windows.Devices.Geolocation.PositionStatus.notInitialized:
            // This status indicates that the app has not yet requested
            // location data by calling GetGeolocationAsync() or
            // registering an event handler for the positionChanged event.
            return "Location status is not initialized because " +
                        "the app has not requested location data.";
        case Windows.Devices.Geolocation.PositionStatus.notAvailable:
            // Location is not available on this version of Windows
            return "You do not have the required location services " +
                        "present on your system.";
            break;
        default:
            return "Unknown status";
    }
}

Step 10: Build the App

Click Build > Build Solution to build the project.

Step 11: Test the App

  1. Click Debug > Start Debugging to test the solution.
  2. Click the Get Location button to get the current location.

Remarks

Note  The Windows Location Provider uses Wi-Fi information to determine location. If Wi-Fi is not available, it will use the IP Address instead. If your computer is not Wi-Fi enabled, you might not get any location update events, since IP Address data is not updated frequently.

Complete example

Related topics

Geolocation Sample
Windows.Devices.Geolocation
Guidelines for Location-Aware Applications

 

 

Build date: 11/29/2012

Did you find this helpful?
(1500 characters remaining)
© 2013 Microsoft. All rights reserved.