Chap 4. Geolocation API
About Location Information You can request users to share their location and, if they agree, you can provide them with instructions on how to get to a nearby store to pick up a new pair of shoes at a discounted rate. The position is provided to the browser by the underlying device (for example, a laptop or a mobile phone) on which the HTML5 Geolocation–enabled browser is running. IP Address Global Positioning System (GPS) Wi-Fi with MAC addresses from RFID, Wi-Fi, and Bluetooth GSM or CDMA cell phone IDs Geolocation API Removed from Unsecured Origins in Chrome 50
The pros and cons of geolocation data GPS Very accurate Take a long time, can drain a user’s device’s batteries Does not work well indoors May require additional hardware Wi-Fi Accurate Works indoors Fix quickly & cheaply Not good in rural areas with few wireless access points Cell Phone Fairly accurate Requires a device with access to a cell phone or cell modem Not good in rural areas with fewer cell phone towers User-Defined May have more accurate location data Allows services for alternate locations User entry might be faster than detection Can also be very inaccurate, especially if the location changes
Arachitecture & Privacy The browser intercepts and requests user permission at step 2.
Browser Support Browser support for HTML5 Geolocation Browser Details Chrome Supported in Google Chrome version 2 with Gears Firefox Supported in version 3.5 and greater Internet Explorer Supported via the Gears plugin Opera Planned support version 10, experimental support in nightly builds Safari Supported in version 4 for the iPhone
Checking for Browser Support if(navigator.geolocation) { document.getElementById("support").innerHTML = "HTML5 Geolocation supported."; } else { document.getElementById("support").innerHTML = "HTML5 Geolocation is not supported in your browser."; }
Positions requests Theres are two type of position requests One-shot position request Repeated position updates
One-Shot Position Requests Usage void getCurrentPosition(in PositionCallback successCallback, in optional PositionErrorCallback errorCallback, in optional PositionOptions options); Example navigator.geolocation.getCurrentPosition(updateLocation, handleLocationError, {timeout:10000}); updateLocation is a PositionCallback function will implement later handleLocationError is a PositionErrorCallback function will implement later
Implement Position Callback function updateLocation(position) { var latitude = position.coords.latitude; var longitude = position.coords.longitude; var accuracy = position.coords.accuracy; document.getElementById("latitude").innerHTML = latitude; document.getElementById("longitude").innerHTML = longitude; document.getElementById(“accuracy”).innerHTML = “This location is accurate within “ + accuracy + “ meters.” }
Implement Position Error Callback function handleLocationError(error) { switch(error.code) { case 0: updateStatus(“Retrieving location error: " + error.message); break; case 1: updateStatus("The user prevented retrieving location."); case 2: updateStatus(“Unable to determine your location: " + error.message); case 3: updateStatus(“Retrieving timed."); }
REPEAT Position updates Usage long watchPosition(in PositionCallback successCallback, in optional PositionErrorCallback errorCallback, in optional PositionOptions options); Example navigator.geolocation.watchPosition(updateLocation, handleLocationError); updateLocation is a PositionCallback function same as getCurrentPosition implemented above. handleLocationError is a PositionErrorCallback function same as getCurrentPosition implemented above.
Cancel position updates Usage navigator.geolocation.clearWatch(watchId); Example var watchId = navigator.geolocation.watchPosition(updateLocation, handleLocationError);
Show me on a google map Require Google Map JavaScript API <script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?sensor=true"></script> Put Div for Google Map <div id="map_canvas" style="width: 500px; height: 500px;"></div>
Show me on a google map (Cont.) Google Map Example var map; function initialize() { var div = document.getElementById('map_canvas'); map = new google.maps.Map(div, {zoom: 15, mapTypeId: google.maps.MapTypeId.ROADMAP}); navigator.geolocation.getCurrentPosition( function(pos) { var latlng = new google.maps.LatLng(pos.coords.latitude, pos.coords.longitude); var infowindow = new google.maps.InfoWindow({ map: map, position: latlng, content: 'Location found using HTML5.‘ }); map.setCenter(latlng); }, function(error) { alert('Cannot get Location data: ' + error.code); } ); } window.addEventListener("load", initialize, true); 加入 InfoWindow 設定地圖中心點
Longitude And Latitude
Get Distance between locations // 用 Haversine 公式計算距離 function getDistance(lat1, lon1, lat2, lon2) { // 角度轉徑度 function Deg2Rad(deg) { return deg * Math.PI / 180; } lat1 = Deg2Rad(lat1); lat2 = Deg2Rad(lat2); lon1 = Deg2Rad(lon1); lon2 = Deg2Rad(lon2); var R = 6371; // km var x = (lon2 - lon1) * Math.cos((lat1 + lat2) / 2); var y = (lat2 - lat1); var d = Math.sqrt(x * x + y * y) * R; return d;
Get Nearest Locations var pois = [ ["台北", 25.0329636, 121.5654268], ["台中", 24.1477358, 120.6736482], ["台南", 22.99793, 120.2126007], ["台東", 22.7972447, 121.0713702] ]; function getNearestCity(latitude, longitude) { var mindif = 99999; var closest; for (index = 0; index < pois.length; ++index) { var dif = getDistance(latitude, longitude, pois[index][1], pois[index][2]); if (dif < mindif) { closest = index; mindif = dif; } // echo the nearest city alert(pois[closest]);
Drawing MARKER var latlng = new google.maps.LatLng(lat, lng); var marker = new google.maps.Marker({ position: latlng, map: map });
Drawing Route var firstCord = {lat: 25.0329636, lng: 121.5654268}; var secondCord = {lat: 24.1477358, lng: 120.6736482}; var coordinates = [firstCord, secondCord]; var routePath = new google.maps.Polyline({ path: coordinates, geodesic: true, strokeColor: '#FF0000', strokeOpacity: 1.0, strokeWeight: 2 }); routePath.setMap(map);
Google map event google.maps.event.addListener(map, 'click', function (event) { var myLatLng = event.latLng; var lat = myLatLng.lat(); var lng = myLatLng.lng(); addMarker(lat, lng); pois.push(["Position Name", lat, lng]); }); 取得點選的經度/緯度
exercise: Drawing Nearest Marker