Now days, more and more web sites are including Store Locators to aid their site visitors to find the closest location. Retail chains want to make it easy for customers to find and shop at their stores. Manufacturers & wholesalers want to give their visitors simple information on the closest retail stores offering their products. With the rapid growth of smartphones that already know your location, this becomes even more valuable. Even retail chains with a small number of locations are beginning to prefer this method over simply listing all of their locations on a page.
There are many service providers available that will take your location data and manage it, and provide you a hosted solution to your store locator needs. However, these services can be costly, and since they are primarily subscription based, the cost goes on as long as you offer the functionality on your site. If you are looking for an alternative, a custom store locator is not difficult to code up. If your developer hasn’t done one before, show them this post to get them started.
Assumptions
There are a couple of assumptions we’re making in this tutorial. First, you obviously have more than one location, so we are assuming that your locations are stored in a database table. Any database will do, but for illustration, we’ll assume it is in a MySQL database table named “stores”.
Second, you’re going to need the latitude & longitude of each store in your table. If you only have a small number of locations, you can get a latitude & longitude by hand in Google, as we explained in this earlier post on Google Maps. If you have a large set of stores without latitude/longitude info, you can use the Google Maps API to systematically look them up as described here.
Finally, you’ll need a database table of all ZIP codes with their latitude & longitude. Since we don’t know exactly where a user is when he types in the starting ZIP code, we can only go with the lat/long of the center of that ZIP code. A good source of ZIP code information is Zip-Codes.com. Their database is inexpensive and contains a wealth of information beyond just the city, latitude, & longitude info. Plus, they update it each month, so you’re always up to date.
Write The Code
Our examples will be in MySQL, and we’ll skip some of the guts such as the actual execution of the database lookups. But this code can easily be modified into .NET or any other database-friendly language. And we just provide the critical elements to save space and encourage you to customize fully to your needs. If anyone needs further explanation on any of the code provided, don’t hesitate to ask in the comments, or by sending us an email.
Receive the starting ZIP code and maximum search radius and look up the latitude & longitude of the starting ZIP code. Your user would have entered the zip code into a box on their form and either entered a radius (in this example, in miles) into a text box or more likely chosen from a drop-down box of choices. Start by receiving those values and looking up the ZIP code in your zipcodes database table.
$basezip=$_POST["basezip"]; // basezip and maxmiles are the names of the elements in the form $maxmiles=$_POST["maxmiles"]; $ssql="SELECT * FROM zipcodes WHERE ZipCode='" . $basezip . "'"; // open database with above SQL statement $baselat=$row["Latitude"]; $baselon=$row["Longitude"];
Next we’ll draw a figurative “square” around the center lat/lon that will be somewhat larger in area than a true circle of radius $maxmiles. The square will have a width and height of twice $maxmiles, and we’ll use the latitude & longitude of each side of the square in the next SQL statement to pull a list of candidates of stores within the maximum radius. Some of those will be too far, but by calculating the distance on only this subset of stores, we can speed things up significantly over calculating the distance of all stores in your table.
// $mlatrad is the number of degrees of latitude plus or minus from the base latitude to search $mlatrad = $maxmiles / ((6076 / 5280) * 60) + $maxmiles / 1000; // $mlonrad is the number of degrees of longitude plus or minus from the base longitude to search $mlonrad = $maxmiles / (((cos(floatval($baselat * 3.141592653589 / 180)) * 6076) / 5280) * 60) + $maxmiles / 1000; $ssql="SELECT * FROM stores WHERE (sLat<=" . ($baselat + $mlatrad) . " And sLat>=" . ($baselat-$mlatrad) . ") AND (sLong<=" . ($baselon+$mlonrad) . " And sLong>=" . ($baselon-$mlonrad) . ")"; //now open database with the above SQL statement
In the SQL statement above, we are assuming that the “stores” table has the latitude of each store in the field named “sLat”, and the longitude in the field named “sLong”.
Now we have an open recordset of stores that are “candidates” to be shown to the user as being within the maximum number of miles from the user’s ZIP code. But since this is a square and not a circle, there could be some stores in the “corner” of the square that are outside the maximum radius. So we want to loop through this recordset and calculate the distance from the base ZIP code for each store. If it is within the maximum distance, we’ll add it to an array to use for sorting and listing to the user.
$k=0; while ($row=mysql_fetch_array($rs)) { $difflong = $baselon - $row["sLong"]; $distance = sin(deg2rad($baselat)) * sin(deg2rad($row["sLat"])) + cos(deg2rad($baselat)) * cos(deg2rad($row["sLat"])) * cos(deg2rad($difflong)); $distance = acos($distance); $distance = rad2deg($distance); $distance = $distance * 60 * 1.1515; If ($distance $k=$k+1; $storeid[$k]=$row["storied"]; $storedist[$k]=$distance; } }
Now you have a couple of arrays that will allow you to display the results to your user. Just loop through the $storedist array to show closest to farthest, and use the corresponding entry in the $storeid display to look the store up in your stores table and display whatever information you choose for the store.
Adding Maps
You can add to the functionality of this even further by incorporating an interactive map with markers for each store in your results. A good and free source for this is Google Maps. Perhaps we’ll do a separate post at some point to get into that in detail, but in the meantime, you can get the gist of it by reviewing our earlier post on adding Google Maps to your site. That talks mainly about a map for one location, but you can use the information in the article to list all of the locations of the search into the map.