jQuery Store Locator with Google Maps API, Google Distance Matrix API, HTML5 GeoLocation & Google Maps KML file as data source
· I didn’t want to create a data file with a custom format, nor did I want to have a database to store my locations. I’ve created my own Google map and let the business guy collaborate – i.e. he added all of the stores. J So, I simply went to this map on maps.google.com and clicked on “KML” link. This let me download a file, which was basically an XML file containing all the information I needed – store information and geographical coordinates. I saved this file as stores.xml
Now let's see what is under the bonnet.
Here's a sample location inside KML file's structure:
Optimax Laser Eye Surgery - Aberdeen Optimax Laser Eye Clinic Golden Square City Centre, Aberdeen AB10 1RD Optimax Laser Eye Clinic - Aberdeen 2 Golden Square City Centre, Aberdeen AB10 1RD 0870 514 3314 -2.104521,57.145737,0.000000
You'll need a couple of script file references, preferebly at the bottom of your <body> block, place this code:
jQuery Code to read your data file:
$.ajax({ type: "GET", url: 'stores.xml', dataType: "xml", success: function (xml) { _locationset = new Array(); $(xml).find('Placemark').each(function (i) { var shop = { Name: $(this).find('name').text(), //Take the lat lng from the user, geocoded above LatLng: new google.maps.LatLng( $(this).find('coordinates').text().split(",")[1], $(this).find('coordinates').text().split(",")[0]), Description: $(this).find('description').text(), Marker: null, Distance: null }; _locationset.push(shop); });... });
Google Distance Matrix API currently has a limit of max 25 destinations per call, this method below would be called Asynchronosly for each set of 25 locations from above _locationset array. This utilises jQuery.Deferred() object introduced in jQuery 1.5. The Distance Matrix Service call looks like this:
function (startIndex, origin, destinations) { var token = $.Deferred(); var service = new google.maps.DistanceMatrixService(); service.getDistanceMatrix({ origins: [origin], destinations: destinations, travelMode: google.maps.TravelMode.DRIVING, unitSystem: google.maps.UnitSystem.IMPERIAL }, function (response, status) { if (response && response.rows.length) { var results = response.rows[0].elements; $.each(results, function (j, val) { if (results[j].status != "ZERO_RESULTS") { _locationset[startIndex + j].Distance = GoogleMapDistanceTextToNumber(results[j].distance.text); } }); token.resolve(); } }); return token.promise(); };
GeoLocation on initial page load:
$(document).ready(function () { // Try HTML5 geolocation if (navigator.geolocation) { navigator.geolocation.getCurrentPosition(function (position) { var g = new GoogleGeocode(); var latlng = new google.maps.LatLng(position.coords.latitude, position.coords.longitude); g.geocodeLatLng(latlng, function (address) { if (address) { showAddress(address); } else { //Unable to geocode handleNoGeolocation('Error: Unable to geocode address'); } }); // do the mapping stuff mapping(position.coords.latitude, position.coords.longitude); }, function () { handleNoGeolocation("Tracking of location was not allowed."); }); } else { // Browser doesn't support Geolocation handleNoGeolocation(false); } });
There's more to it, of course, but these are main functions.
You can download attached source code or pull it from my bitbucket repo:
https://bitbucket.org/ruslanss/jquery-google-maps-distance-matrix-store-locator
ssh://hg@bitbucket.org/ruslanss/jquery-google-maps-distance-matrix-store-locator
And you can also view a demo here: optimax.apphb.com/demo.html
If you have any queries, leave a comment or hit me on twitter: @funky_rus