HTML5 Tutorial: Geolocation - 2014
Before anything else, let's check where we are now.
If we click the following link "Where am I?" (Mozilla Firefox 3.5+ only), it will popup a web page in a new tab. If we press "Share Location" button, it will locate our position in a Google Map.
This works for Mozilla Firefox 3.5+ only. Just click this-> Where am I?. Then, press "Share Location" button.
Geolocation is the art of figuring out where we are in the world and optionally sharing that information with people we trust. There are many ways to figure out where we are - our IP address, our wireless network connection, which cell tower our phone is talking to, or dedicated GPS hardware that receives latitude and longitude information from satellites in the sky.
- GPS
The most accurate of the three, and it reads microwave signals from multiple satellites to determine the current location. - Cell Tower Triangulation
It determines the current location by doing a calculation based on the locations of the cell towers in the phone's rang. Cell tower triangulation can be fairly accurate in cities with a high cell tower density but becomes less accurate in areas where there is a greater distance between towers. is a g - Wi-Fi Positioning Service (WPS)
WPS uses the IP address from iPhone's Wi-Fi connection to make a guess at our location by referencing a large database of known service providers and the areas they service. It is imprecise and can be off by many miles.
The geolocation API lets us share our location with trusted web sites. The latitude and longitude are available to JavaScript on the page, which in turn can send it back to the remote web server and do fancy location-aware things like finding local businesses or showing our location on a map.
The geolocation API centers around a new property on the global navigator object:
navigator.geolocation.
The simplest use of the geolocation API looks like this:
function get_location() { navigator.geolocation.getCurrentPosition(show_map); }
That has no detection, no error handling, and no options. Our web application should probably include at least the first two of those. To detect support for geolocation API, we can use Modernizr:
function get_location() { if (Modernizr.geolocation) { navigator.geolocation.getCurrentPosition(show_map); } else { // no native support; maybe try Gears? } }
What we do without geolocation support is up to us. I'll explain the Gears fallback option in a minute, but first I want to talk about what happens during that call to getCurrentPosition(). Geolocation support is opt-in. That means our browser will never force us to reveal our current physical location to a remote server. The user experience differs from browser to browser. In Mozilla Firefox, calling the getCurrentPosition() function of the geolocation API will cause the browser to pop up an infobar at the top of the browser window.
We just saw the JavaScript code that causes this infobar to appear. It's a single function call which takes a callback function (which I called show_map). The call to getCurrentPosition() will return immediately, but that doesn't mean that we have access to the user's location. The first time we are guaranteed to have location information is in the callback function. The callback function looks like this:
function show_map(position) { var latitude = position.coords.latitude; var longitude = position.coords.longitude; // let's show a map or do something interesting! }
The callback function will be called with a single parameter, an object with two properties: coords and timestamp. The timestamp is just that, the date and time when the location was calculated. (Since this is all happening asynchronously, we can't really know when that will happen in advance. It might take some time for the user to read the infobar and agree to share their location. Devices with dedicated GPS hardware may take some more time to connect to a GPS satellite. And so on.) The coords object has properties like latitude and longitude which are exactly what they sound like: the user's physical location in the world.
Only three of the properties are guaranteed to be there (coords.latitude, coords.longitude, and coords.accuracy). The rest might come back null, depending on the capabilities of our device and the backend positioning server that it talks to. The heading and speed properties are calculated based on the user's previous position, if possible.
geo.js is an open source, MIT-licensed JavaScript library that smoothes over the differences between the W3C geolocation API, the Gears API, and the various APIs provided by mobile platforms. To use it, we'll need to add two <script> elements at the bottom of our page. (Technically, we could put them anywhere, but scripts in our <head> will make our page load more slowly. So don't do that!)
The first script is gears_init_js, which initializes Gears if it's installed. The second script is geo.js.
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Dive Into HTML 5</title> </head> <body> ... <script src="gears_init.js"></script> <script src="geo.js"></script> </body> </html>
Now we're ready to use whichever geolocation API is installed.
if (geo_position_js.init()) { geo_position_js.getCurrentPosition(geo_success, geo_error); }
Let's take that one step at a time. First, we need to explicitly call an init() function. The init() function returns true if a supported geolocation API is available.
if (geo_position_js.init()) {
Calling the init() function does not actually find our location. It just verifies that finding our location is possible. To actually find our location, we need to call the getCurrentPosition() function.
geo_position_js.getCurrentPosition(geo_success, geo_error);
The getCurrentPosition() function will trigger our browser to ask for our permission to find and share our location. If geolocation is being provided by Gears, this will pop up a dialog asking if our trust the web site to use Gears. If our browser natively supports the geolocation API, the dialog will look different. For example, Firefox 3.5 natively supports the geolocation API. If we try to find our location in Firefox 3.5, it will display an infobar at the top of the page asking whether we want to share our location with this web site.
The getCurrentPosition() function takes two callback functions as arguments. If the getCurrentPosition() function was successful in finding our location - that is, we gave our permission and the geolocation API actually worked its magic - it will call the function passed in as the first argument. In this example, the success callback function is called geo_success.
geo_position_js.getCurrentPosition(geo_success, geo_error);
The success callback function takes a single argument, which contains the position information.
function geo_success(p) { alert("Found you at latitude " + p.coords.latitude + ", longitude " + p.coords.longitude); }
If the getCurrentPosition() function could not find our location - either because we declined to give our permission, or the geolocation API failed for some reason - it will call the function passed in as the second argument. In this example, the failure callback function is called geo_error.
geo_position_js.getCurrentPosition(geo_success, geo_error);
The failure callback function takes no arguments.
function geo_error() { alert("Could not find you!"); }
geo.js does not currently support the watchPosition() function. If we need continuous location information, we'll need to actively poll getCurrentPosition().
Ph.D. / Golden Gate Ave, San Francisco / Seoul National Univ / Carnegie Mellon / UC Berkeley / DevOps / Deep Learning / Visualization