Strange Symphonies The best way to predict the future is to invent it

Related tags

13Nov/090

Geolocation with navigator.geolocation

The W3C have been working on a Geolocation API Specification to incorporate geolocation into the browser via a new variable, navigator.geolocation.

navigator.geolocation can provide us with the following details:

  • latitude
  • longitude
  • altitude
  • accuracy
  • altitudeAccuracy
  • heading
  • speed

Mozilla Firefox v3.5 introduced navigator.geolocation, and so far Mozilla Firefox has been the only browser implementing it.

Thanks to Mozilla Firefox v3.5 we now have Location-Aware Browsing! Click here for an example. A bar will drop from the top prompting you that "blog.aizatto.com wants to know your location" with options on the right hand side. Click on "Share location".

Making Your Application Location Aware

I am going to use my sample HTML file in my previous article Geolocation with Google AJAX API (uploaded file).

This allows us to reuse the Google Reverse Geocoding.

It has been reproduced here for easy reference:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:fb="http://www.facebook.com/2008/fbml">
<head>
  <title>Geolocation with Google AJAX API</title>
</head>
<script src="http://www.google.com/jsapi?key=ABCDEF" type="text/javascript"></script>
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>

<script language="Javascript" type="text/javascript">
    //<![CDATA[

    function OnLoad() {
      var geocoder = new google.maps.Geocoder();

      if (google.loader.ClientLocation) {
        document.body.innerHTML += 'google.loader.ClientLocation.latitude ' + google.loader.ClientLocation.latitude + '<br />';
        document.body.innerHTML += 'google.loader.ClientLocation.longitude ' + google.loader.ClientLocation.longitude + '<br />';
        document.body.innerHTML += 'google.loader.ClientLocation.address.city ' + google.loader.ClientLocation.address.city + '<br />';
        document.body.innerHTML += 'google.loader.ClientLocation.address.country ' + google.loader.ClientLocation.address.country + '<br />';
        document.body.innerHTML += 'google.loader.ClientLocation.address.country_code ' + google.loader.ClientLocation.address.country_code + '<br />';
        document.body.innerHTML += 'google.loader.ClientLocation.address.region ' + google.loader.ClientLocation.address.region  + '<br />';
        document.body.innerHTML += '<a href="http://maps.google.com/maps?q=' + google.loader.ClientLocation.latitude + ',+' + google.loader.ClientLocation.longitude + '>Open Location in Google Maps</a><br />';
        geocoder.geocode({'latLng': new google.maps.LatLng(google.loader.ClientLocation.latitude, google.loader.ClientLocation.longitude)}, function (results, status) {
          if (status == google.maps.GeocoderStatus.OK) {
            if (results[0]) {
              document.body.innerHTML += 'google.maps.Geocoder ' + results[0].formatted_address;
            }
          } else {
            document.body.innerHTML += 'Geocoder failed due to: ' + status;
          }
        });
      } else {
        document.body.innerHTML += 'Cannot find location';
      }
    }
    google.setOnLoadCallback(OnLoad);

    //]]>
</script>
<body>
</body>
</html>

Using navigator.geolocation

Its time to replace OnLoad again:

    function OnLoad() {
      var geocoder = new google.maps.Geocoder();

      if (navigator.geolocation) {
        document.body.innerHTML += 'Calling <code>navigator.geolocation.getCurrentPosition</code><br />';
        navigator.geolocation.getCurrentPosition(function(position) {
          document.body.innerHTML += 'position.coords.latitude ' + position.coords.latitude + '<br />';
          document.body.innerHTML += 'position.coords.longitude ' + position.coords.longitude + '<br />';
          document.body.innerHTML += 'position.coords.accuracy ' + position.coords.accuracy + '<br />';
          document.body.innerHTML += 'position.coords.altitude ' + position.coords.altitud + '<br />';
          document.body.innerHTML += 'position.coords.altitudeAccuracy ' + position.coords.altitudeAccuracy + '<br />';
          document.body.innerHTML += 'position.coords.heading ' + position.coords.heading + '<br />';
          document.body.innerHTML += 'position.coords.speed ' + position.coords.speed + '<br />';
          document.body.innerHTML += '<a href="http://maps.google.com/maps?q=' + position.coords.latitude + ',+' + position.coords.longitude + '>Open Location in Google Maps</a><br />';
          geocoder.geocode({'latLng': new google.maps.LatLng(position.coords.latitude, position.coords.longitude)}, function (results, status) {
            if (status == google.maps.GeocoderStatus.OK) {
              if (results[0]) {
                document.body.innerHTML += 'google.maps.Geocoder ' + results[0].formatted_address;
              }
            } else {
              document.body.innerHTML += 'Geocoder failed due to: ' + status;
            }
          });
        }, function() {
          document.body.innerHTML += 'Cannot find location' + '<br />';
        });
      } else {
        document.body.innerHTML += 'Cannot find location' + '<br />';
      }
    }

Similar to the Geolocation with Google AJAX APIs we have to test whether the navigator.geolocation variable exists, this is done on Line 4.

If it exists. We proceed to call the navigator.geolocation.getCurrentPosition method. getCurrentPosition takes 3 arguments, with the last 2 being optional. For more details about the navigator.geolocation.getCurrentPosition visit the W3C Geolocation API Specification. The first two arguments accept a function to callback.

The first argument specifies whether the it was successful in finding the location.
The second argument handles any errors that may occur. For example, time outs.

Reverse Geocoding

          geocoder.geocode({'latLng': new google.maps.LatLng(position.coords.latitude, position.coords.longitude)}, function (results, status) {
            if (status == google.maps.GeocoderStatus.OK) {
              if (results[0]) {
                document.body.innerHTML += 'google.maps.Geocoder ' + results[0].formatted_address;
              }
            } else {
              document.body.innerHTML += 'Geocoder failed due to: ' + status;
            }
          });

Once again on lines 15 to 23, I use the Google Maps API to reverse geocode the address based on the supposed latitude and longitude of the user.

I changed line 15 to use variables used for latitude and longitdue. Otherwise, its exactly the same as the Geolocation with Google AJAX API.

Conclusion

That wasn't so hard now was it? Why don't you give your location aware browser a try?

13Nov/092

Geolocation with Google AJAX API

Note: I'm not so sure what the name of the Google AJAX API is. It seems to be very inconsistent, and on the Google site it goes by various names: Google AJAX API, Google AJAX Search API, or Google API.

Google has been a great provider of services, and it never disappoints. Likewise they are also a provider of geolocation services. If you use the Google AJAX APIs, they provide you with access to a variable called google.loader.ClientLocation which stores your geolocated information.

google.loader.ClientLocation as described on the Google AJAX APIs Developer's Guide:

When an application makes use of the AJAX API loader, the loader attempts to geo locate the client based on it's IP address. If this process succeeds, the client's location, scoped to the metro level, is made available in the google.loader.ClientLocation property. If the process fails to find a match, this property is set to null.

ClientLocation provides you with information about the user's:

  • latitude
  • longitude
  • city
  • country
  • country code
  • region

Click here for an example.

Making Your Application Location Aware

Sign up for Google AJAX Search API Key

First of all, make sure you sign up for a Google AJAX Search API Key.

Note: You can use http://localhost/ as your "web site URL" so you can experiment locally

After you have submitted the form you will be presented 3 things:

  • Your key
  • The directory that will work for the provided key
  • An example web page to get you started. Copy this. Feel free to test using this file.

Here is the sample web page reproduced:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title>My Google AJAX Search API Application</title>
    <script src="http://www.google.com/jsapi?key=ABCDEF" type="text/javascript"></script>
    <script language="Javascript" type="text/javascript">
    //<![CDATA[

    google.load("search", "1");

    function OnLoad() {
      // Create a search control
      var searchControl = new google.search.SearchControl();

      // Add in a full set of searchers
      var localSearch = new google.search.LocalSearch();
      searchControl.addSearcher(localSearch);
      searchControl.addSearcher(new google.search.WebSearch());
      searchControl.addSearcher(new google.search.VideoSearch());
      searchControl.addSearcher(new google.search.BlogSearch());

      // Set the Local Search center point
      localSearch.setCenterPoint("New York, NY");

      // Tell the searcher to draw itself and tell it where to attach
      searchControl.draw(document.getElementById("searchcontrol"));

      // Execute an inital search
      searchControl.execute("Google");
    }
    google.setOnLoadCallback(OnLoad);

    //]]>
    </script>
  </head>
  <body>
    <div id="searchcontrol">Loading...</div>
  </body>
</html>

Note: Forgot your Google AJAX Search API Key? Don't worry, when you can sign up with the same domain twice, and it'll give you the same API key

Loading Google AJAX API

If you look at your sample HTML file Google provided. You will see that they load the Google AJAX API on line 5:

<script src="http://www.google.com/jsapi?key=ABCDEFG"
        type="text/javascript"></script>

Using google.location.ClientLocation

Lets trim the file, and cut the cruft.

  • You can remove line 9 as we don't need to use the Google AJAX Search API.
  • You can remove the content of OnLoad, this is lines 12-29.

Now replace OnLoad with the following:

function OnLoad() {
  if (google.loader.ClientLocation) {
        document.body.innerHTML += 'google.loader.ClientLocation.latitude ' + google.loader.ClientLocation.latitude + '<br />';
        document.body.innerHTML += 'google.loader.ClientLocation.longitude ' + google.loader.ClientLocation.longitude + '<br />';
        document.body.innerHTML += 'google.loader.ClientLocation.address.city ' + google.loader.ClientLocation.address.city + '<br />';
        document.body.innerHTML += 'google.loader.ClientLocation.address.country ' + google.loader.ClientLocation.address.country + '<br />';
        document.body.innerHTML += 'google.loader.ClientLocation.address.country_code ' + google.loader.ClientLocation.address.country_code + '<br />';
        document.body.innerHTML += 'google.loader.ClientLocation.address.region ' + google.loader.ClientLocation.address.region  + '<br />';
        document.body.innerHTML += '<a href="http://maps.google.com/maps?q=' + google.loader.ClientLocation.latitude + ',+' + google.loader.ClientLocation.longitude + '>Open Location in Google Maps</a><br />';
  } else {
    document.write('Cannot find location');
  }
}

Now its time to test the file. If Google can find your location, it populates google.loader.ClientLocation, else congratulations, you have managed to evade the eyes of Google.

Once we know the variable exists we can simply inspect it for data about the user. Its that simple.

Reverse Geocoding

But that information isn't specific enough. In fact, I don't even know where the latitude and longitude point to without opening Google Maps. Once again, thanks to Google we can reverse geocode a location.

Loading Google Maps

The Google Maps API allows us to locate the address (reverse geocode) given a latitude or longitude.

After the JavaScript to load the Google AJAX API, enter:

<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>

Note: google.load does not support Google Maps API v3.

Using google.maps.Geocoder

It's time to replace OnLoad again:

    function OnLoad() {
      var geocoder = new google.maps.Geocoder();

      if (google.loader.ClientLocation) {
        document.body.innerHTML += 'google.loader.ClientLocation.latitude ' + google.loader.ClientLocation.latitude + '<br />';
        document.body.innerHTML += 'google.loader.ClientLocation.longitude ' + google.loader.ClientLocation.longitude + '<br />';
        document.body.innerHTML += 'google.loader.ClientLocation.address.city ' + google.loader.ClientLocation.address.city + '<br />';
        document.body.innerHTML += 'google.loader.ClientLocation.address.country ' + google.loader.ClientLocation.address.country + '<br />';
        document.body.innerHTML += 'google.loader.ClientLocation.address.country_code ' + google.loader.ClientLocation.address.country_code + '<br />';
        document.body.innerHTML += 'google.loader.ClientLocation.address.region ' + google.loader.ClientLocation.address.region  + '<br />';
        document.body.innerHTML += '<a href="http://maps.google.com/maps?q=' + google.loader.ClientLocation.latitude + ',+' + google.loader.ClientLocation.longitude + '>Open Location in Google Maps</a><br />';
        geocoder.geocode({'latLng': new google.maps.LatLng(google.loader.ClientLocation.latitude, google.loader.ClientLocation.longitude)}, function (results, status) {
          if (status == google.maps.GeocoderStatus.OK) {
            if (results[0]) {
              document.body.innerHTML += 'google.maps.Geocoder ' + results[0].formatted_address;
            }
          } else {
            document.body.write += 'Geocoder failed due to: ' + status;
          }
        });
      } else {
        document.body.write += 'Cannot find location';
      }
    }

Instantiating the Geocoder

      var geocoder = new google.maps.Geocoder();

On line 2 we instantiate a google.maps.Geocoder and store it in the geocoder variable. This Geocoder instance will manage all our Geocoding needs.

Reverse Geocoding with google.maps.Geocoder

        geocoder.geocode({'latLng': new google.maps.LatLng(google.loader.ClientLocation.latitude, google.loader.ClientLocation.longitude)}, function (results, status) {
          if (status == google.maps.GeocoderStatus.OK) {
            if (results[0]) {
              document.body.innerHTML += 'google.maps.Geocoder ' + results[0].formatted_address;
            }
          } else {
            document.body.write += 'Geocoder failed due to: ' + status;
          }
        });

On line 12 to 20 is where the magic begins. On the variable geocoder, we call the geocode method. The geocode method accepts 2 arguments. An Object hash to describe the method arguments, and a callback function which will be called once the geocoding is done.

We call geocoder.geocode with an Object hash. We have to instantiate a google.maps.LatLng, and provide the latitude and longitude as arguments to it, as the LatLng key only accepts a type of google.maps.LatLng. See the Google Maps API Reference on the GeocoderRequest object specification.

The callback function provides us with the interface to test success of the geolocation. Two arguments are required in the function. The first argument is the result, and the second one is the status.

As we are concerned on whether the geocoding was successful, we only test for the status on line 13. Otherwise if it wasn't, we'll display the error message.

There are other GeocoderStatuses available, and you can find them on the Google Maps API Reference on the GeocoderStatus class.

After testing for success, on line 14 we test to see if the results array has been populated. Following that, Google provides us with a nicely formatted address of the discovered location stored in the formatted_address variable. For information about the results format, refer to the Google Maps API Reference on the GeocoderResponse object specification

Conclusion

Now go forth and test the application. You should now have a fully functional Location Aware application! Have funs!

13Nov/090

Geolocation in Your Browser

Geolocation is the ability to locate your location via using the Internet. This is done by guessing where you are based on your IP Adress. Normally the accuracy of geolocation has been limited to country, or at best city. But the technology has improved over the past few years, and has been very accurate. Even spot on.

See here for a sample.

Note: It may not be accurate.

Geolocation using: