HTML5 Geo-location API and Google Maps API

In this weeks tutorial we’ll be creating a jQuery plugin that serves as an introduction to the HTML5 Geo-location API to request your current location. Once we have the location, we will then draw a route from there to Dublin, Ireland (or wherever you tell it to) using the Google Maps API. This could be used in a HTML5 web application or on a site to tell your customers how to get to you.

Getting Started

First of all we’ll need to create our jQuery plugin wrapper. The $.extend function will allow us to provide default settings that can be overridden by the options passed to it and we use the this.each function to make sure we can maintain chaining in jQuery.

(function ( $ ) {
    $.fn.GeoLocation = function( options ) {
        var settings = $.extend({        
        }, options );
        
        return this.each(function() {    
        });
    };
}( jQuery ));

The Geo-location API

The first thing we will do is display a message telling the user that we are trying to get their location. Not all older browsers implement the HTML5 Geo-location API, so we’ll need to make sure that we can access it before we do anything. To do this we check to see if the navigator.geolocation property is defined, if it’s not we’ll display a message informing the user as much.

(function ( $ ) {
    $.fn.GeoLocation = function( options ) {
        var settings = $.extend({        
        }, options );
        
        return this.each(function() {    
            var element = $(this);
            element.text('Attempting to find your location');
            
            if(navigator.geolocation) {
            } else {
                element.text('Geolocation is not supported by this browser, please upgrade to a more recent version');
            }
        });
 
    };
 
}( jQuery ));

finding

By accessing the Geo-location API, the browser will automatically prompt the user (if needed) to allow access to the API. If the user declines, we’ll have to display an error message. The getCurrentPosition function of the API actually supports the passing of two functions to it, a success and a failure function. Depending on if we are granted access and can determine the location, one or the other function will be called. If the call is a success, we will get a data object that contains location based information (this can include direction and speed) passed to our displayCurrentPosition function. If the call fails, we will get an error object with a general error code for us to interpret in the onError function.

request

(function ( $ ) {
    $.fn.GeoLocation = function( options ) {
        var settings = $.extend({
        }, options );
             
        return this.each(function() {    
            var element = $(this);
            element.text('Attempting to find your location');
            
            function displayCurrentPosition(data) {
                element.text('Current location is latitude: ' + data.coords.latitude + ', longitude: ' + data.coords.longitude);                        
            }
            
            function onError(error) {
                switch(error.code) {
                    case error.PERMISSION_DENIED:
                        element.text('Access to location API denied by user');
                        break;
                    case error.POSITION_UNAVAILABLE:
                        element.text('Unable to determine location');
                        break;
                    case error.TIMEOUT:
                        element.text('Unable to determine location, the request timed out');
                        break;
                    case error.UNKNOWN_ERROR:
                        element.text('An unknown error occurred!');
                        break;
                }
            }
            
            if(navigator.geolocation) {
                navigator.geolocation.getCurrentPosition(displayCurrentPosition, onError);
            } else {
                element.text('Geolocation is not supported by this browser, please upgrade to a more recent version');
            }
        });
    };
}( jQuery ));

Adding the Google Maps API

Now that we have our location we can add in a Google map, first we’re going to update our default settings with a home latitude and longitude object. This can be overridden on initialization, but a default should be provided. We also need to add a reference to the Google Maps API, we can do this by adding the script tag below to our head tag. If you have a Google Maps API key, you can specify the second script tag. You can get a free key from Google here


<script src="https://maps.googleapis.com/maps/api/js?sensor=false">

or

<script src="https://maps.googleapis.com/maps/api/js?key=<GOOGLE API KEY>&sensor=false">
$.fn.GeoLocation = function( options ) {
    var settings = $.extend({
        home: { latitude: 53.339381, longitude: -6.260533 }
    }, options );

    var home = new google.maps.LatLng(settings.home.latitude, settings.home.longitude);
...
...

   };
}( jQuery ));

Next we have to update our displayCurrentPosition function to add a div element for the map itself, and provide all of the settings we want for the map. First up we need to create a new LatLng object for the current location, then using it we can center the map on this location.

function displayCurrentPosition(data) {
    element.html('<div class="map-canvas"></div>');
    
    var current = new google.maps.LatLng(data.coords.latitude, data.coords.longitude);
    
    var options = {
        center: current,
        mapTypeId: google.maps.MapTypeId.HYBRID,
        zoom: 10,
    };
    
    var map = new google.maps.Map(element[0], options);    
}

Now that we have our map, we can add our route. To do this we need to specify our start point (origin), our destination and our method of transport. The directions object below mimics the DirectionsRequest class, so it is possible to specify any of its properties such as avoidHighways and waypoints. Waypoints are specific locations the route should take in.

var directions = {
    origin: current,
    destination: home,
    travelMode: google.maps.DirectionsTravelMode.DRIVING
};

Then we initialize an instance of the DirectionsRender class, passing our map as a parameter. We also need to create an instance of the DirectionsService class. The DirectionsService is the class that actually performs the route calculation, it passes its results to the DirectionsRender to actually draw the route.

function displayCurrentPosition(data) {
    element.html('<div class="map-canvas"></div>');
    
    var current = new google.maps.LatLng(data.coords.latitude, data.coords.longitude);
    
    var options = {
        center: current,
        mapTypeId: google.maps.MapTypeId.HYBRID,
        zoom: 10,
    };
    
    var map = new google.maps.Map(element[0], options);
    
    var directions = {
        origin: current,
        destination: home,
        travelMode: google.maps.DirectionsTravelMode.DRIVING
    };
    
    display = new google.maps.DirectionsRenderer({ map: map });
    
    service = new google.maps.DirectionsService();
    service.route(directions, function(response, status) {
        if (status == google.maps.DirectionsStatus.OK) {
            display.setDirections(response);
        }
        else
            alert ('failed to get directions');
    });
}

Don’t forget to style!

If you don’t specify at least a height for the parent div the map won’t be visible

div.location {
    width: 100%;
    height: 400px;
}

Using the plugin

To actually use the plugin, simply use the jQuery .ready event to initialize your instance.

<div id="page">
    <div class="location"></div>
</div>
<script> 
    jQuery(document).ready(function() {
        jQuery('div.location').GeoLocation();
    });
</script>

map

The full sample page looks like this. Here I’ve embedded the jQuery plugin in the HTML, I have however included it as a separate file in the source download below.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8">
    <title>HTML5 Geo Location API</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
    <script src="https://maps.googleapis.com/maps/api/js&sensor=false"></script>
    

    <style>
        div.location {
             width: 100%;
             height: 400px;
        }
    </style>    
</head>
<body>
    <div id="page">
        <div class="location"></div>
    </div>
    <!-- [/page] -->
    <script> 
        
        (function ( $ ) {
            $.fn.GeoLocation = function( options ) {
                var settings = $.extend({
                    home: { latitude: 53.339381, longitude: -6.260533 },
                }, options );
                
                var home = new google.maps.LatLng(settings.home.latitude, settings.home.longitude);
                     
                return this.each(function() {    
                    var element = $(this);
                    element.text('Attempting to find your location');
                    
                    function displayCurrentPosition(data) {
                        element.html('<div class="map-canvas"></div>');
                        
                        var current = new google.maps.LatLng(data.coords.latitude, data.coords.longitude);
                        
                        var options = {
                            center: current,
                            mapTypeId: google.maps.MapTypeId.HYBRID,
                            zoom: 10,
                        };
                        
                        var map = new google.maps.Map(element[0], options);
                            
                        var directions = {
                            origin: current,
                            destination: home,
                            travelMode: google.maps.DirectionsTravelMode.DRIVING
                        };
                        
                        display = new google.maps.DirectionsRenderer({ map: map });
                        
                        service = new google.maps.DirectionsService();
                        service.route(directions, function(response, status) {
                            if (status == google.maps.DirectionsStatus.OK) {
                                display.setDirections(response);
                            }
                            else
                                alert ('failed to get directions');
                        });
                    }
                    
                    function onError(error) {
                        switch(error.code) {
                            case error.PERMISSION_DENIED:
                                element.text('Access to location API denied by user');
                                break;
                            case error.POSITION_UNAVAILABLE:
                                element.text('Unable to determine location');
                                break;
                            case error.TIMEOUT:
                                element.text('Unable to determine location, the request timed out');
                                break;
                            case error.UNKNOWN_ERROR:
                                element.text('An unknown error occurred!');
                                break;
                        }
                    }
                    
                    if(navigator.geolocation) {
                        navigator.geolocation.getCurrentPosition(displayCurrentPosition, onError);
                    } else {
                        element.text('Geolocation is not supported by this browser, please upgrade to a more recent version');
                    }
                });
         
            };
         
        }( jQuery ));

        jQuery(document).ready(function() {
            jQuery('div.location').GeoLocation();
        });
        
    </script>

</body>
</html>

Feel free to use this code in whatever way you need to. You could easily replace the Google Maps API with one of several weather APIs (Weather Underground and Open Weather Map both have free access) to display the weather forecast for a user.

A battle hardened software developer with a mixed and colorful background, who can't come up with a decent author bio More articles by Jonny Schnittger
Home CSS Deals DesignBombs HTML HTML5 JavaScript jQuery Miscellaneous Mobile MySQL News PHP Resources Security Snippet Tools Tutorial Web Development Web Services WordPress