. 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
- Click Debug > Start Debugging to test the solution.
- 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
Build date: 11/29/2012