• Create a Store Locator With Google Maps

    Posted on June 10, 2012 by in Javascript, Jquery, Other Programming

    Finding a store within 10 miles or any given radius for that matter is one of the regularly asked questions in forums now a days, this article explains how to get this done using Google Maps API using PHP and MySQL. If you have new to google maps and have not created any maps i suggest you go through Creating a Basic Map using Google Maps API and Calculating Distance between two locations before you proceed further.

    The articles assumes you have table with address of stores and it’s co-ordinates (latitude,longitude) and some other fields, like location name, the store timings etc as required. You would need to longitude and latitude coordinates to find the stores within certain radius, since most user would know the address but not latitude and longitude, we use the google maps geocoding api to find the coordinates as below

    	function convertAddressToLatLng(address){
    	 	var geocoder = new google.maps.Geocoder();
    
    		geocoder.geocode({ 'address': address }, function (results, status) {
    			if (status == google.maps.GeocoderStatus.OK) {
    			    var location = results[0].geometry.location;
    			    var latlng = new google.maps.LatLng(location.lat(),location.lng());
    			} else {
    			    $("#divAddress").html('Invalid Addresss');
    			}
    		});
    	}
    

    Once we have the coordinates, we pass the location to searchStores function. The function first places a marker at the address provided by the user, and then we use Jquery AJAX to retrieve the locations with in given radius by providing latitude,lonngitude and radius as parameters.

    NOTE : The radius is hard coded to 10 miles in this example you can change it to user provided value if you wish.

    	function searchStores(location){
    		var latlng = new google.maps.LatLng(location.lat(),location.lng());
    	    var myOptions = {
    	    	zoom: 13,
    	        center: latlng,
    	        mapTypeId: google.maps.MapTypeId.ROADMAP
    	    };
    	    map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
    
    		//Marker at the address typed in
    		var image = 'images/townhouse.png'
            var marker = new google.maps.Marker({
                    position: latlng,
                    map: map,
    				icon: image
            });
    
    		//hard coded the radius to 10 miles, if you get the value from a field if required
    		var parameters = 'lat='+ location.lat() + '&lng=' + location.lng() + '&radius=10';
    
    		$.ajax({
    			type: "POST",
    			dataType: 'json',
    			url: "store_locator.php",
    			data: parameters,
    			success: function(msg) {
    				//alert(msg);
    				displayStores(msg);
    			},
    			error:function (xhr, ajaxOptions, thrownError){
                	alert(thrownError);
                }
    		});  /* $.ajax  */
    	}
    

    The Php code is pretty basic, it reads the Server, Username, Password, Database Name from the config file and connects to the database. Then we retrieve the parameters we provided by jquery, that is, latitude and longitude that we calculated from the address provided by the user using Geocoding API and radius. We pass the variables to the query and use the Haversine Formula to find the stores within the provided radius

    NOTE : Change the 3959 in the query to 6371 to change the radius to KM.

    <?php
    	include 'config.php';
    
    	//connect to db
      	$oLink = mysql_pconnect($host, $user, $pswd) or die("Can't connect to MySQL server!");
    	mysql_select_db($db) or die("Can't select database!");
    
    	// Get parameters
    	$mlat = $_POST["lat"];
    	$mlng = $_POST["lng"];
    	$radius = $_POST["radius"];
    
    	// Search the rows in the markers table
    	//change 3959 to 6371 for distance in KM
    	$sql = sprintf("SELECT address, name, lat, lng, ( 3959 * acos( cos( radians('%s') ) * cos( radians( lat ) ) * cos( radians( lng ) - radians('%s') ) + sin( radians('%s') ) * sin( radians( lat ) ) ) ) AS distance FROM stores HAVING distance < '%s' ORDER BY distance LIMIT 0 , 20",
    	  mysql_real_escape_string($mlat),
    	  mysql_real_escape_string($mlng),
    	  mysql_real_escape_string($mlat),
    	  mysql_real_escape_string($radius));
    
    	$result = mysql_query($sql);
    	$rows = array();
    	while($r = mysql_fetch_assoc($result)) {
        	$rows[] = $r;
    	}
    	mysql_close($oLink);
    
    	echo json_encode($rows);
    ?>
    

    Given below is the javascript code that displays the stores on the google maps and sidebar.

    	function displayStores(result){
    		if (result.length > 0){
    			for (i=0;i<result.length;i++){
    				//Append Store Address on Sidebar
    				var html = getEmbedHTML(i+1,result[i].name,result[i].address,result[i].distance);
    				$("#divStores").append(html);
    				//place a marker
    				var image = 'images/number_' + parseInt(i+1) + '.png';
    				var latlng = new google.maps.LatLng(result[i].lat,result[i].lng);
    				var marker = new google.maps.Marker({
    					position: latlng,
    					map: map,
    					icon: image
    				});
    			}
    		} else {
    			$("#divStores").html('No Stores Found');
    		}
    	}
    
    	function getEmbedHTML(seqno,name,address,distance) {
    		var	strhtml = '<div class="row">';
    		strhtml  =  strhtml + '<img src="images/number_' + seqno + '.png" border="0" width="24" height="24" style="padding-right:10px;" /><label>' + name + '<label><br/>'
    		strhtml  =  strhtml + '<span>' + address + '<span><br/>'
    		strhtml  =  strhtml + '<span> Distance : ' + parseFloat(distance).toFixed(2) + ' miles<span><br/>'
    		strhtml  =  strhtml + '</div><div class="separator"></div>';
    
    		return strhtml;
    	}
    

    To view the demo please click here

    To download complete set of google maps examples, click here

    Be Sociable, Share!

    Written by

    Vanamali Juvvadi is a Web enthusiast and loves all things design and technology. Founded qnownow with a group of friends to share anything/everything they know/find on the internet.

    View all articles by

    Email : [email protected]

    16 Responsesso far.

    1. dpcani says:

      hello! thank you very much for the example. I’m testing it but I encotrado a problem I do not know how to solve it.

      When the database no words with accents (Example: Lion or a ‘N’) devuvel Null … I tried to change the headers but I managed to fix it.

      You know how you can fix it?

      Thanks!

      • Vanamali says:

        i did not understand the exact problem? Are you facing a problem if there are no records returned?

        Instead of $(“#divStores”).html(getEmbedHTML(‘No Stores Found’,”,”)); in the else part use this $(“#divStores”).html(‘No Stores Found’);

    2. Martin says:

      Thank you! Just what I was looking for! Thank you!

    3. jewel farazi says:

      Thank you so much! Can you add one more feature on sidebar result? Like when click on the result name or image it will open infowindow message on specific markers.

      Thanks again

    4. Joe says:

      Hi Vanamali. Thank you very much. Great work. Awesome tutorial. Any chance of updating the code with the changes you made in StoreLocator_click.html. Thanks, Joe

    5. JIm says:

      Example not working in my localhost, how can I can it work in my localhost.

    6. Ammar Faris says:

      This is a very great example.. just to share another good example of store locator developed using PHP, jQuery and Bootstrap http://superstorefinder.net

    7. Stefano says:

      Hi,
      I am trying to use this with a larger data set 6000+ items and it’s sort of breaking. Do you have any suggestions?

      • Vanamali says:

        are you able to get the data into a json object? where exactly is it breaking while displaying the data or while retrieving the data?

        If it is while retrieving the data it might be because you’ve run into PHPs memory limit or something. If you are using C#, you might have to increase json length in the web.config, something like below

        <scripting>
           <webServices>
               <jsonSerialization maxJsonLength="50000000"/>
           </webServices>
        </scripting>
        
    8. Stefano says:

      Vanamali, Thank you for getting back to me. I really appreciate it. I’m using PHP. The db has about 6300 entries…sems to work well at about 2000 so somewhere the limit is being exceeded.

      • Vanamali says:

        try to increase php memory limit, here is link explaining how to do it, if the problem still persists, can you send me the code and db file to my email, i will try to replicate the issue on my end.

    9. rebareis says:

      Hi Vanamali, this tutorial is great (way better explained than the Google one I’ve been using), but I’m having problems getting the markers to show up. I’m new to php, and I have a database on my local host but I think I’m getting confused when it comes to connecting my database. Could you help?

    10. Rob says:

      Vanamali, great explanation and tutorial. With the sidebar entries being clicked and opening the pins on the map, is there a way that when a different and/or another one is selected the open one is closed?

    Leave a Reply