Book Image

Instant HTML5 Geolocation How-to

By : Benjamin Otto Werdmulle
Book Image

Instant HTML5 Geolocation How-to

By: Benjamin Otto Werdmulle

Overview of this book

We don't just surf the Web from our desktops any more – we take it with us, everywhere we go. Modern devices contain sophisticated hardware and software to determine the user's location. Apps such as Foursquare and Google Maps use this to create new kinds of functionality. Now, you can do this too with the HTML5 Geolocation API. "Instant HTML5 Geolocation How-to" is a simple guide to adding location information to your web applications. The practical, easy-to-follow recipes are designed to help you learn the ins and outs of the API. You'll learn how to use it, how it works, and how to save and display geographic information on the web. Beginning with a solid grounding in how the Geolocation API works and when to use it, you will learn how to determine, store, display, and track the user's location via a series of clear recipes. You will learn the different ways location is determined on different devices, including desktops and laptops that don't have GPS units. You'll also learn how to selectively use these different behaviours, based on the speed, accuracy, and battery life requirements of your application. You'll also get some hints about using MySQL databases to store sets of location data. "Instant HTML5 Geolocation How-to" will teach you everything you need to know about retrieving the location information your application needs, across multiple devices and platforms.
Table of Contents (7 chapters)

Displaying the user's location using a KML feed (Intermediate)


The Keyhole Markup Language (KML) is an XML-based markup language suitable for defining geographic data. Alongside GeoRSS, it's one of two main XML-based standards that Google Maps supports. It was originally developed for using with Google Earth, which was known as Keyhole Earth Viewer until Google acquired it. Because multiple applications support KML files, it's a good way to easily export your geographic data.

Getting ready

Perform the following steps:

  1. Ensure that you have a recent version of PHP installed.

  2. Check that DOM extension of PHP 5 is installed. Specifically, this will use the XML DOMDocument class. For most installations of PHP 5, this will be installed by default, but it's worth checking, as not all installations are the same. You can read information about the DOM extension at http://php.net/manual/en/book.dom.php.

  3. You may also wish to install Google Earth in order to test your KML feed. The website for Google Earth is listed at the end of this section.

How to do it…

Perform the following steps to display the user's location using a KML feed:

  1. Set up feed.php as follows. This will retrieve the location items using the getPreviousLocations($user_id) function that we created in the Displaying the user's location using the Google Maps API (Intermidiate) recipe. Using the PHP DOM extension, it will create an XML feed in Keyhole Markup Language, which will encode the locations and timestamps of each saved point.

    <?php 
    
    // Load our common library file, and fail if it isn't present
    require_once('lib.php');
    
    // PHP's date function requires that the timezone is set. As I'm located on
    // America's west coast, I'm setting this to America/Los_Angeles. You can
    // also set this in your php.ini.
    date_default_timezone_set('America/Los_Angeles');
    
    // Create a new XML file using PHP's DOM extension.
    $feed = new DOMDocument('1.0','UTF-8');
    $feed->formatOutput = true;
    
    // Create a root node for the XML document.
    $rootNode = $feed->appendChild($feed->createElementNS('http://earth.google.com/kml/2.2', 'kml'));
    
    // Create a document node inside the root node.
    $documentNode = $rootNode->appendChild($feed->createElement('Document'));
    $documentNameNode = $documentNode->appendChild($feed->createElement('name','Location detector feed'));
    
    // Attempt to retrieve previous map points - and if they exist, iterate
    // through them. Note that we're hardcoding $user_id to 1; in more complex
    // implementations with user management, we might get $user_id from the
    // current user session.
    if ($points = getPreviousLocations(1)) {
      foreach($points as $point) {
        // Each place is stored inside a Placemark tag
        $placeNode = $documentNode->appendChild
        ($feed->createElement('Placemark'));
        // We're going to use the timestamp of the saved 
        // location as its title
        $nameNode = $placeNode->appendChild
        ($feed->createElement('name',date('r',$point->time)));
        // The actual coordinates are stored inside a Point tag
        $pointNode = $placeNode->appendChild
        ($feed->createElement('Point'));
        // Note that KML coordinates are longitude 
        // then latitude!
        $coordinatesNode = $pointNode->appendChild
        ($feed->createElement('coordinates',
        $point->longitude . ',' . $point->latitude));
        // Each place also has an actual TimeStamp tag
        $timeNode = $placeNode->appendChild
        ($feed->createElement('TimeStamp', date('c',$point->time)));
      }
    }
    
    // Make sure browsers know to render the feed as XML
    header('Content-type: text/xml');
    
    // Write the feed content to the page
    echo $feed->saveXML();
  2. Ensure that the resulting feed looks something like this in your browser:

  3. If your feed is accessible to the public Internet, test it by entering its URL into the Google Maps search bar:

  4. Select File | Save in your web browser while viewing the feed, and save it with a filename ending in .kml.

  5. You will be able to open the resulting KML file in Google Earth. If you have Google Earth installed, test the feed by double-clicking on the file.

How it works...

It's not a good idea to hand-code an XML-based file, or to use a static template to do so. Various tools and libraries are available, and the DOM extension that was introduced with PHP 5 is an easy way to get started.

Our KML file consists of a Document node, which in turn contains a series of Placemark nodes. We could include a large amount of data here, but our minimum viable KML file will list name, timestamp, and geographic point information inside each Placemark. These are contained within name, TimeStamp, and Point nodes respectively. The Point node in turn contains a coordinates node, which lists the geographic coordinates of the point. Note that KML coordinates list the latitude first, followed by a comma, followed by the longitude. Spaces should not be used.

Placemarks can include more than one Point, as well as a selection of other geographic elements, but for the purposes of this example, we'll stick to one Point per Placemark.

TimeStamps are listed in ISO 8601 format. The TimeStamp for 7:30 p.m. Pacific Time on March 11, 2013 would appear as follows:

Mon, 11 Mar 2013 19:30:00 -0700

Create a new XML file in PHP by instantiating a DOMDocument object, specifying XML Version 1.0 and the UTF-8 character set:

$feed = new DOMDocument('1.0','UTF-8');

Define it as being a KML file by including the KML namespace, and establishing a root node:

$rootNode = $feed->appendChild($feed->createElementNS('http://earth.google.com/kml/2.2', 'kml'));

New child nodes are added to a DOMDocument through use of the appendChild method; elements are created inside them using createElement. Now you have your root node, you can add the Document node:

$documentNode = $rootNode->appendChild($feed->createElement('Document'));

Using the getPreviousLocations function we created earlier, we can nest a series of Placemark nodes with the features as described in the preceding code line, using more calls to appendChild and createElement. The complete code is available in feed.php for you to peruse.

All of your data is now loaded into the feed. All that's left is to write it to the browser. First, you must tell it that this is an XML file, by setting the HTTP header appropriately:

header('Content-type: text/xml');

Finally, then, you can write it to the browser:

echo $feed->saveXML();

This is all you need to create a fully functional KML feed. There's much more available in the KML specification, including details about how to style map points, and other information that can be included inside the feed as a whole, as well as each individual Placemark. A link to the KML specification is included at the end of this section.

Because Google Maps natively supports KML, once you've made your system live on the web, you can simply paste the URL to your feed.php file into the Google Maps search box, and your geographic points will be displayed.

Additionally, you can choose to load your KML file into the map you created in index.php. This has the same effect as entering the address of your KML file into the Google Maps search bar, but on the map embedded in your own application.

You may remember that we created a global variable referencing the map called window.googleMap. Directly underneath, you can create a KmlLayer object as follows:

window.kmlLayer = new google.maps.KmlLayer('http://your/kml/feed.php');
window.kmlLayer.setMap(window.googleMap);

Of course, http://your/kml/feed.php must be replaced with the URL of your feed.

See also