HTML5 Apps: Positioning with Geolocation

HTML5 Apps: Positioning with Geolocation

Tutorial Details
  • Technology: HTML5
  • Difficulty: Beginner
  • Estimated completion time: 45 - 60 minutes
Share

At the heart of every location-based application is positioning and geolocation. In this tutorial you will learn the geolocation capabilities of HTML5 and the basic principles needed to take advantage of them in your next HTML5 app!

Introduction

Three years ago, the smartphone “boom” was still an uncertain possibility. Today, we are surrounded by a society of smart phone addicts who live as if their lives cannot continue without instant, mobile access to the web, e-mail, and apps for every occasion. Mobile devices have come a long way in just three short years, and now support a wide range of useful features beyond making phone calls. For location-challenged individuals like myself, geolocation is one of the most useful additions. Many iPhone and Android devices have been fitted with GPS hardware that can produce reliable geographical data, and in this article we will discuss the geolocation capabilities of HTML5. My aim is to help you take advantage of geolocation technology in your next project by walking you through the following topics:

  • Browser geolocation and how it works
  • How Asynchronous function calls work
  • How to use the getCurrentPosition API
  • What’s in geolocation data
  • How to fall back on IP address based geolocation when browsers don’t provide native support
  • How to display a map using geolocation data
  • How to use the watchPosition and clearWatch APIs

Browser geolocation and how it works

To detect the location of a client device in the past, one would typically have to inspect the client IP address and make a reasonable guess as to the where that device was located. However, as part of the HTML5 efforts, the W3C has developed a set of APIs to effectively allow the client-side device (i.e. your iPhone 3G+, Android 2.0+ phones, or even your conventinal desktop browsers) to retrieve geographic positioning information with JavaScript. When we look at the web browsers landscape, the native support for geolocation is beginning to find its way into mainstream applications at a slow and steady pace. One substantial application that uses geolocation is Google Maps. As I’m writting this article, the geolocation support is fully available in only a few browsers (see below), but it looks like most modern browsers are adopting this useful functionality:

  • Firefox 3.5+: Yes
  • Chrome 5 beta: Yes
  • iPhone Safari: Yes
  • Opera 10.5 dev build: Yes
  • Safari: No
  • Internet Explorer: No

For those that are interested in reading on W3C geolocation specs here is the link to follow. One section worth talking about here is section 6.2.8 titled: “The geolocation API must be agnostic to the underlying sources of location information”. It’s suggesting that the underlying technology on the device may achieve geolocation via either GPS, cell tower triangulation or possibly other techniques. The geolocation API won’t identify how location information was determined. Not knowing how geolocation was achieved is usually not a problem, but you may notice that the accuracy of location information may vary greatly depending on the technique used.

Asynchronous functions

An Asynchronous function is one that is executed outside of the main program flow. In the context of JavaScript, it means our code will call a function and then continue to execute statements before the function returns. When following this model, our code should look something like this:

// the function we want to call
do_something(handle_response_to_do_something);

// the function that will handle the response of the above function call
function handle_response_to_do_something(response)
{
    alert(response);
}

Since the response to do_something() function is given to us asynchronously, we must nominate a function that will receive a response and use it. Therefore we must define another function, handle_response_to_do_something(), that displays the result in a dialog.

You may now be asking why we need to know this? Well, because when our application tries to query its location, the user of the device must agree to share his location information with our application. If this action was not an asynchronous one, then everything inside the browser would freeze until the user responds, and that is obviously less than dersirable.

html5 geolocation API

getCurrentPosition API

Let’s talk about the geolocation API. The first API that we are interested in working with is the getCurrentPosition() API. When called, it must immediately return and then asynchronously acquire a new Position object. If successful, this method must invoke its associated successCallback argument with a Position object as an argument. If the attempt fails, and the method was invoked with a non-null errorCallback argument, this method must invoke the errorCallback with a PositionError object as an argument.

So let’s start by creating our HTML5 page which is nice and easier than setting up an XHTML 1.0 page. All we need to start with is this:

<!DOCTYPE html>
<html>
  <body>
    <div>

    </div>
  </body>
</html>

On line 1, we use the new <!DOCTYPE html> DTD to define this as an HTML5 page. Next, we will place a button on our page for users to initiate the process of detecting their location.

<!DOCTYPE html>
<html>
  <body>
    <div>
      <button id=”btnInit” >Find my location</button>
    </div>
  </body>
</html>

Now we will wire the button up with JavaScript to initiate the process of querying the current location. Note how the script tags do not require type attribute thanks to some new HTML5 sugar.

<!DOCTYPE html>
<html>
  <head>
    <script src="js/jquery-1.4.2.min.js"></script>
    <script>
        jQuery(window).ready(function(){
            jQuery("#btnInit").click(initiate_geolocation);
        });

        function initiate_geolocation() {
            navigator.geolocation.getCurrentPosition(handle_geolocation_query);
        }

        function handle_geolocation_query(position){
            alert('Lat: ' + position.coords.latitude + ' ' +
                  'Lon: ' + position.coords.latitude);
        }
    </script>
  </head>
  <body>
    <div>
      <button id="btnInit" >Find my location</button>
    </div>

  </body>
</html>

In the above code we should note the use of the jQuery JavaScript framework to help us get started quickly, otherwise we’d have to write extra code to detect page readiness that has nothing to do with geolocation. With the first script tag, we load jQuery framework and then use it immediately at the start of the second script tag to assign a click event to the button we defined earlier. We also wrote the initiate_geolocation() function to execute when the button is pressed and the handle_geolocation_query(position) function to asynchronously get the geolocation data through the position argument.

At this point if you run the above code in a browser that supports geolocation (namely Firefox 3.5+ and iPhone Safari) you should see your Latitude and Longitude coordinates displayed to you. This works if the user agrees to share his location information with the website/web application, but what if he doesn’t what to share that information? or what if there is a problem getting that information?

It would be nice to be notified of such problems. Fortunately, our code can detect these issues by defining another function that is executed only when there is a problem retrieving geolocation data. So, let’s look at how our code will need to change in order to detect problems:

<!DOCTYPE html>
<html>
  <head>

    <script src="js/jquery-1.4.2.min.js"></script>
    <script>
        jQuery(window).ready(function(){
            jQuery("#btnInit").click(initiate_geolocation);
        });

        function initiate_geolocation() {
            navigator.geolocation.getCurrentPosition(handle_geolocation_query,handle_errors);
        }

        function handle_errors(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;
            }
        }

        function handle_geolocation_query(position){
            alert('Lat: ' + position.coords.latitude +
                  ' Lon: ' + position.coords.latitude);
        }
    </script>
  </head>
  <body>
    <div>
      <button id="btnInit" >Find my location</button>
    </div>
  </body>
</html>

In the above code we have now introduced a new function, handle_errors that takes in an error argument. By inspecting the error argument, we can check for the kind of error that has occurred. Normally, the browser will identify one of these three errors as the cause:

  • User chose to not share location data
  • Device was unable to obtain position data
  • Device timedout while waiting to retrieve position data

Geolocation data

If we inspect what we received from the geolocation API, we’ll see the coords and timestamp fields. The timestamp field simply denotes the time at which the instance of geolocation data was created. The coords attribute contains a set of geographic coordinates together with their associated accuracy, as well as a set of other optional attributes such as altitude and speed. The following is the description of them according to the W3C specs:

  • The latitude and longitude attributes are geographic coordinates specified in decimal degrees.
  • The accuracy attribute denotes the accuracy level of the latitude and longitude coordinates. It is specified in meters and must be supported by all implementations.
  • The altitude attribute denotes the height of the position, specified in meters above the WGS84 ellipsoid. If the implementation cannot provide altitude information, the value of this attribute must be null.
  • The altitudeAccuracy attribute is specified in meters. If the implementation cannot provide altitude information, the value of this attribute must be null.
  • The heading attribute denotes the direction of travel of the hosting device and is specified in degrees counting clockwise relative to the true north. If the implementation cannot provide heading information, the value of this attribute must be null.
  • The speed attribute denotes the current ground speed of the hosting device and is specified in meters per second. If the implementation cannot provide speed information, the value of this attribute must be null.

You may only access some of these fields if the target device actually supports them according to the above description, but it’s still important to know they are there. The accuracy attribute in particular may be useful in your application to detect reliability.

IP address based Geolocation

So now the obvious question is what about those browsers that don’t support geolocation at all? The answer is that we must use an external geolocation service. These services do their best to map the IP address of a device to geographic locations using large geolocation databases. Usually they do a good job, but at times they may suffer from the following issues:

  • IP addresses may be associated with the wrong location (e.g., the wrong postal code, city or suburb within a metropolitan area).
  • Addresses may be associated only with a very broad geographic area (e.g., a large city, or a state). Many addresses are associated only with a city, not with a street address or latitude/longitude location.
  • Some addresses will not appear in the database and therefore cannot be mapped (often true for IP numbers not commonly used on the Internet).

The important thing to remember is that when an external geolocation service is used, the accuracy is not as good as geolocation native to the device, and in some scenarios it may be completely off. Additionally, such services do not provide any information regarding the altitude, speed or heading of the device. Regardless, when GPS or triangulation are not available, they are a good fallback.

YQL Geo Library is a dedicated and lightweight library that lets you perform geolocation using good old Yahoo services. This library can do other things which I’ll leave to you to discover, but for now let’s look at how we should modify our code to successfully detect the location on both supporting and non-supporting browsers:

<!DOCTYPE html>
<html>

  <head>
  <script src="js/jquery-1.4.2.min.js"></script>
  <script src="js/yqlgeo.js"></script>
  <script>
    jQuery(window).ready(function(){
        jQuery("#btnInit").click(initiate_geolocation);
    })

    function initiate_geolocation() {
        if (navigator.geolocation)
        {
            navigator.geolocation.getCurrentPosition(handle_geolocation_query, handle_errors);
        }
        else
        {
            yqlgeo.get('visitor', normalize_yql_response);
        }
    }

    function handle_errors(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 timedout");
            break;

            default: alert("unknown error");
            break;
        }
    }

    function normalize_yql_response(response)
    {
        if (response.error)
        {
            var error = { code : 0 };
            handle_error(error);
            return;
        }

        var position = {
            coords :
            {
                latitude: response.place.centroid.latitude,
                longitude: response.place.centroid.longitude
            },
            address :
            {
                city: response.place.locality2.content,
                region: response.place.admin1.content,
                country: response.place.country.content
            }
        };

        handle_geolocation_query(position);
    }

    function handle_geolocation_query(position){
        alert('Lat: ' + position.coords.latitude + ' ' +
              'Lon: ' + position.coords.latitude);
        }
    </script>

  </head>
  <body>
    <div>
      <button id="btnInit" >Find my location</button>
    </div>

  </body>
</html>

So what’s new in the above code? Three things:

  1. We are importing the YQL Geolocation Library into the page
  2. Inside the initiate_geolocation() function, the code checks to make sure geolocation is natively supported. If not it makes use of the YQL Geolocation Library.
  3. Finally we’ve defined the normalize_yql_response(response) function to turn the result of the YQL Geolocation Library into an output format similar to the W3C geolocation API specs.

Display a map using Geolocation

So far we have been able to retrieve the latitude and longitude coordinates of the device but when one is lost in the middle of a big city, latitude and longitude coordinates alone aren’t going to be all that helpful. We must convert these coordinates into some form that relates to users more naturally, like a map. Let’s display a map of the current location, using Google’s Static Map API as shown in the following code section:

function handle_geolocation_query(position)
{
    var image_url = "http://maps.google.com/maps/api/staticmap?sensor=false&center=" + position.coords.latitude + "," +
                    position.coords.longitude + "&zoom=14&size=300x400&markers=color:blue|label:S|" +
                    position.coords.latitude + ',' + position.coords.longitude;

    jQuery("#map").remove();
    jQuery(document.body).append(
        jQuery(document.createElement("img")).attr("src", image_url).attr('id','map')
    );
}

With the help of jQuery, we modified the handle_geolocation_query(position) function to create an image element and add it to the page. The src attribute of the image element is set to a constructed URI which Google Static Map API will inspect and generate a map image for.

HTML5 Geolocation Maps API

watchPosition and clearWatch APIs

Now that we know how getCurrentPosition API works lets quickly look at the watchPosition API. When called, it must immediately return and then asynchronously start a watch process defined by the following set of steps:

  1. Acquire a new Position object. If successful, invoke the associated successCallback with a Position object as an argument. If the attempt fails, and the method was invoked with a non-null errorCallback argument, this method must invoke the errorCallback with a PositionError object as an argument.
  2. Invoke the appropriate callback with a new Position object every time the implementation determines that the position of the hosting device has changed.

This method returns an integer value that uniquely identifies the watch process. When the clearWatch() function is called with this identifier, the watch process must stop acquiring any new position fixes and must cease invoking any callbacks.

So in other words this API enables our code to repeatedly receive location information as the device location changes. Let’s look at the scaffolding page we need to start with:

<!DOCTYPE html>
<html>
  <head>
    <script src="js/jquery-1.4.2.min.js"></script>
    <script>

        jQuery(window).ready(function(){
            jQuery("#btnInit").click(initiate_watchlocation);
            jQuery("#btnStop").click(stop_watchlocation);
        });

        var watchProcess = null;

        function initiate_watchlocation() {
        }

        function stop_watchlocation() {
        }

        function handle_errors(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 timedout");
                break;

                default: alert("unknown error");
                break;
            }
        }

        function handle_geolocation_query(position) {
        }
    </script>
  </head>
  <body>
    <div>
      <button id="btnInit" >Monitor my location</button>

      <button id="btnStop" >Stop monitoring</button>
    </div>
    <div id=”info”></div>
  </body>
</html>

As you can see the code is very much the same as the code we used in the “getCurrentPostion API” section earlier. There are a couple of additions however.

  1. First we have added a new button to allow us to stop the watch process with the stop_watchlocation() function to handle its click.
  2. We have a watchProcess variable to keep track of the watch process.

To start the process we need to add the code that calls the watchPosition() API like the code below:

function initiate_watchlocation() {
    if (watchProcess == null) {
        watchProcess = navigator.geolocation.watchPosition(handle_geolocation_query, handle_errors);
    }
}

To stop the process we need to add the code that calls the clearWatch() API like the code below:

function stop_watchlocation() {
    if (watchProcess != null)
    {
        navigator.geolocation.clearWatch(watchProcess);
        watchProcess = null;
    }
}

Finally, we handle displaying the map and additional data (e.g. position, accuracy) like this:

function handle_geolocation_query(position) {
    var text = "Latitude: "  + position.coords.latitude  + "<br/>" +
               "Longitude: " + position.coords.longitude + "<br/>" +
               "Accuracy: "  + position.coords.accuracy  + "m<br/>" +
               "Time: " + new Date(position.timestamp);
    jQuery("#info").html(text);

    var image_url = "http://maps.google.com/maps/api/staticmap?sensor=false&center=" + position.coords.latitude + ',' + position.coords.longitude +
                    "&zoom=14&size=300x400&markers=color:blue|label:S|" + position.coords.latitude + ',' + position.coords.longitude;

    jQuery("#map").remove();
    jQuery(document.body).append(
        jQuery(document.createElement("img")).attr("src", image_url).attr('id','map')
    );
}
HTML5 Geolocation no data

Conclusion

I hope that this tutorial has given you a head start into the world of geolocation APIs. Good luck and try to make your next project take advantage of geolocation benefits!

Related Posts

Add Comment

Discussion 39 Comments

  1. Hi,

    this is great tutorial. Always wanted to start building geolocation based sites. Thanks.
    What is your opinion on using http://cloudmade.com/ as maps provider? They have pretty good api and customizable map designs.

    • I’m with you on Cloudemade. Its very snappy and simple. There is also an open source map rendering engine I saw a while ago which I can’t remember the name for. All other free maps like Google Map, Yahoo Maps and Microsoft Maps are also good places to start with.

      • They really are good, I worked a lot with Google maps and it has is qualities. But Cloudmade looks pretty interesting with that map style changer and other great features (navigation, rerouting, vector view). Hope you find that missing map rendering engine.

  2. Dazydude says:

    Is there any way to download the full source code?

  3. Wow, great tutorial. Just finished it up, works perfect on my iPhone.

    One question though, why don’t they work in regular desktop browsers? I get the “unknown error” everytime.

    • In the example I’ve given, when IP address based Geolocation fails, the script simply gives an unknown error message because we really can’t tell what actually failed. Again this is a downfall of Geolocation via IP address.

      I mentioned IP address Geolocation in this tutorial because it relates to what we are discussing here, but it’s easy to foresee that in the next couple years most mobile devices will fully support Geolocation.

  4. mufti says:

    Great tutorials, this is unique tutorial im looking for. I cant wait to try this tuts.

  5. Shane McBreen says:

    FYI, in your script you have it alerting the latitude for both that latitude and longitude.

  6. baroquedub says:

    Very informative thank you.

    This has led me on to a few other resources which may be of interest:

    Intro to geo hacking using (amongst others) Yahoo technology
    http://www.slideshare.net/cheilmann/introduction-to-geo-hacking-with-amongst-others-yahoo-technology-3388374

    Yahoo! Geo technologies
    http://developer.yahoo.com/geo/

    GeoMaker – decode text strings into locations
    http://icant.co.uk/geomaker/

    Mapstraction – all the major Map APIs simplified
    http://www.mapstraction.com/

    ———-

    ps. I’ve tried to incorporate the yqlgeo.js/geo location by IP address example into the final watchPosition example but it isn’t updating. I’ve included the normalize_yql_response() method, and here’s my modified initiate_watchlocation():

    function initiate_watchlocation() {

    if (navigator.geolocation) {
    if (watchProcess == null) {
    watchProcess = navigator.geolocation.watchPosition(handle_geolocation_query, handle_errors);
    }
    } else {
    if (watchProcess == null) {
    watchProcess = navigator.geolocation.watchPosition(yqlgeo.get(‘visitor’, normalize_yql_response), handle_errors);
    }
    }

    }

    But it’s not updating on Firefox; navigator.geolocation is always true.

    Anyone got any ideas?:

    • If its always true then its suggesting that your browser in fact does support Geolocation. Thus it will use its own geolocation for working out your position.

      If you are testing this on your desktop/laptop then it will appear like its not changing because your desktop/laptop can’t be notified of location changes unless it’s fitted with a GPS device or something that prompts it to check its position again. In contrast, a mobile device is constantly polling its position automatically without us needing to program it.

      A side effect of watching your position via YQL Geo Location is that for it to give you a new position, your IP address will need to change. With your cellphone this happens due to roaming as you move about the city. Roaming is when your cellphone hops from one telecommunication tower to another thus changing it address. In short, watching your position using YQL Gelo Location requires a your device to travel a large distance for a change to appear and most likely it won’t be very accurate.

  7. what about Symbian built-in browsers ? anyone try this on some on Nokia devices ??

    • I personally wasn’t able to run it on my N97. I tried built in browser and Opera Mini 5 beta 2. But don’t know where is the problem, because it returns absolutely no result, not even lat, lng that should return at least from yql. Will try to make it work.

      • I’m sorry I’m not familiar with N97 Nokia devices. It may have to do with its JavaScript capabilities. Can it run jQuery? Also some browsers are absolutely pedantic about wellformedness and semicolons which I may have missed in the code. I’d start debugging using alerts.

      • Yes, it can run jQuery. Problem is to access the GPS in device as it is possible to access only through a special nokia phone object that looks to be functional only as a part of plugin, not in a website. But I am not sure.

        On the other hand, if this script can’t get position based on GPS data, that it should try YQL that should provide something.

      • So as far as I can tell, it looks like nokia can’t work with yql and gps data are available only to nokia applications or web widgets through mobile object from their library.

  8. Tanmay Joshi says:

    Hi, Nice tutorial.
    Need some help on this

    navigator.geolocation.getCurrentPosition(handle_geolocation_query,handle_errors);
    above line gives me error on desktop firefox3.6.3.

    Firebug shows : location is undefined – this.coords = new WifiGeoCoordsObject(location.latitude,

    Please let me know.

    Thanks,
    Tanmay

  9. David Phillips says:

    Does this work with Android as well?

  10. lafncow says:

    Is it just me or are the YQL results completely inaccurate? For example, doing yqlgeo.get(’69.60.7.195′,function(o){console.log(o);})

    (the above is gizmodo’s IP) results in a country code and lat/long in Nigeria!? Likewise for a server I know exists and is registered in the US I got “Nigeria”. Meanwhile tests on servers that I know exist in other countries and server content in other languages have consistently been wrong on both counts. What’s going on here?

    • This goes to show that IP address based Geolocation is prone to man made errors like that. Its also possible for this kind of Geolocation service to return strange results when an intercepting service masks/spoof your IP address to make it seem you are coming from a different location.

  11. Carlos says:

    i am assuming this works with Android too since it is HTML 5 and Javascript based and no Coco. As long as you have an updated HTML5 capable and Javascript enabled browser you should be able to do this. It is just a web page pushing jQuery.

    Nice tutorial. I just found out the Plus group made this mobile section. Awesome stuff. Much appreciated.

    Would love to see more Appcelerator tutorials. Titanium’s site does not have too many well thought out tutorials. Just the example code and project and then you are left in the dark on how to do a lot of stuff.
    This is the perfect place for it if they are no going to take the initiative and do it.

    Thanks again!

  12. ADrian says:

    I really need to learn javascript.

    Great tutorial, thanks!

  13. Okay, I have a working code for everyone to look at. This next code section uses the YQL Geo Library as backup for browsers that don’t support Geo. For your information:

    <!DOCTYPE html>
    <html>
    <head>
    <meta name = “viewport” content = “width = device-width”>
    <script src=”http://code.jquery.com/jquery-1.4.2.min.js”></script>
    <script src=”http://isithackday.com/hacks/geo/yql-geo-library/yqlgeo.js”></script>
    <script>
    function initiate_geolocation() {
    if (navigator.geolocation)
    {
    navigator.geolocation.getCurrentPosition(handle_geolocation_query, handle_error);
    }
    else
    {
    yqlgeo.get(‘visitor’, normalize_yql_response);
    }
    }

    function handle_error(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 timedout”);
    break;
    default: alert(“unknown error”);
    break;
    }
    }

    function normalize_yql_response(response)
    {
    if (response.error)
    {
    var error = { code : 0 };
    handle_error(error);
    return;
    }

    var position = {
    coords : {
    latitude: response.place.centroid.latitude,
    longitude: response.place.centroid.longitude
    },
    address : {
    city: response.place.locality2.content,
    region: response.place.admin1.content,
    country: response.place.country.content
    }
    };

    handle_geolocation_query(position);
    }

    function handle_geolocation_query(position){
    var image_url = “http://maps.google.com/maps/api/staticmap?sensor=false&center=” + position.coords.latitude + ‘,’ + position.coords.longitude +
    “&zoom=14&size=300×400&markers=color:blue|label:S|” + position.coords.latitude + ‘,’ + position.coords.longitude;

    jQuery(“#map”).remove();
    jQuery(document.body).append(
    jQuery(document.createElement(“img”)).attr(“src”, image_url).attr(‘id’,'map’)
    );
    }

    jQuery(window).ready(function(){
    jQuery(“#btnInit”).click(initiate_geolocation);
    })
    </script>
    </head>

    <body>
    <div>
    <button id=”btnInit” >Find my location</button>
    </div>
    </body>
    </html>

    This next code section performs the watch action. It doesn’t rollback to YQL Geo Library as we learned how to use that in the previous example:

    <!DOCTYPE html>
    <html>
    <head>
    <script src=”http://code.jquery.com/jquery-1.4.2.min.js”></script>
    <script>
    jQuery(window).ready(function(){
    jQuery(“#btnInit”).click(initiate_watchlocation);
    jQuery(“#btnStop”).click(stop_watchlocation);
    });

    var watchProcess = null;

    function initiate_watchlocation() {
    if (watchProcess == null) {
    watchProcess = navigator.geolocation.watchPosition(handle_geolocation_query, handle_errors);
    }
    }

    function stop_watchlocation() {
    if (watchProcess != null)
    {
    navigator.geolocation.clearWatch(watchProcess);
    watchProcess = null;
    }
    }

    function handle_errors(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 timedout”);
    break;

    default: alert(“unknown error”);
    break;
    }
    }

    function handle_geolocation_query(position) {
    var text = “Latitude: ” + position.coords.latitude + “<br/>” +
    “Longitude: ” + position.coords.longitude + “<br/>” +
    “Accuracy: ” + position.coords.accuracy + “m<br/>” +
    “Time: ” + new Date(position.timestamp);
    jQuery(“#info”).html(text);

    var image_url = “http://maps.google.com/maps/api/staticmap?sensor=false&center=” + position.coords.latitude + ‘,’ + position.coords.longitude +
    “&zoom=14&size=300×400&markers=color:blue|label:S|” + position.coords.latitude + ‘,’ + position.coords.longitude;

    jQuery(“#map”).remove();
    jQuery(document.body).append(
    jQuery(document.createElement(“img”)).attr(“src”, image_url).attr(‘id’,'map’)
    );
    }
    </script>
    </head>
    <body>
    <div>
    <button id=”btnInit” >Monitor my location</button>

    <button id=”btnStop” >Stop monitoring</button>
    </div>
    <div id=”info”>
    </div>
    </body>
    </html>

    I’ve quickly imported the jQuery and Yql Geo Library off their websites. In production its safer to have a copy of the stored on your server to serve along with the rest of the page.

  14. As a suggestion, since not everyone who uses your site will be familiar with JQuery, perhaps you could replace your relative link to JQuery with http://code.jquery.com/jquery-1.4.2.min.js (or elswhere with JQuery).

    For the naive user, who would simply copy/paste your example into Notepad, and create a .html file, he’s not going to find a local JQuery file.

  15. Here’s a puzzler (to me, at least).

    I put the code into geo.html. When I open it with Chrome 5 via a file URI, the page comes up, I click the button, and the call to “navigator.geolocation.getCurrentPosition(handle_geolocation_query, handle_error) does not result in either handle_geolocation_query or handle_error getting called.

    I served up the exact same file via a trivial HTTP server, and I get my lat/lon via the alert.

    I checked the JavaScript console, and the file flavor doesn’t show an error — it just doesn’t do anything.

    Why?
    TIA

  16. Firefox, on the other hand, doesn’t care whether the file is reached via a file URI or an http URI. It shows the location via an alert.

    It looks like Chrome 5 has a problem with file URIs. Chrome does show the let-the-page-use-location prompt, and it shows its sharing-location icon, but it never fires the callback.

    • I noticed that chrome only recently added Geolocation, having said that I tested this scenario with Chrome 5.0.375.55 on my MackBook and it worked fine. Maybe take a look at your code one more time and see if you’ve missed a var keyword, semicolon or something that is throwing Chrome.

  17. Maor says:

    Works great both on iPhone and Chrome! Thanks, Arman!

  18. Joaquin says:

    Hey, thanks for the tut!

    I tried clicking on the button on my Blackberry but just couldn’t.. it won’t “press” it. Any ideas?

    J

  19. Dale Hurley says:

    Whoops! In the first two code snippets there is a typo. You have latitude for the longitude.!

  20. HP Hioolen says:

    Just installed Safari 5, seems like geolocation is now supported in safari as well!

  21. Not that was really interesting !
    MobileTuts rocks !

  22. Meredith says:

    This tutorial was perfect. I struggled through some others that just didn’t work and didn’t explain what was going on in the code well at all. So Arman, thank you.

    Here’s a question though. I think it’s possible to take the lat and long and turn that into a place name, but how? So for example, the alert box could come up and say, you’re in Manhatten, NY instead of telling you your lat and long.

  23. Derek says:

    Great! I love HTML5 but I think if IE didn’t support it, it won’t be popular.

  24. kuldeep says:

    hi, i have adroid htc magic i visit http://demos.denonstudio.net/geo/watch.html demo page but it wont give me the exact location i am using wi-fi for connection , i try same location from my ipod touch and throught my dell laptop it give me exact location.
    i try google local from my android phone it give me exact location any idea what google local uses?

  25. L1 says:

    I solved the ‘location is undefined’ problem in FireFox.
    If you turn of Wifi the routine WifiGeoPositionObject gets stuck on the location variable.
    Just turn on your Wifi and problem solved

Add a Comment

To add a code snippet to your comment, please wrap your code like so: <pre name="code" class="html">YOUR CODE</pre>. You can replace the class name with "js," "css," "sql," or "php." If there are any "<" or ">" within your code, please search and replace them with: &lt; and &gt; respectively.