Full Visual Studio 2005 solution included at the bottom of this post.
Update 2023-12-08: Source Code Moved Here: Download Zip of Source
Update 2008-12-31: Fixed a bug with the variable equality. Updated to the
source on the codeplex site: codeplex.com/StoreLocator
Update 2008-11-22: Fixed a bug with the variable definition. Also Moved the source code to CodePlex. From now on, all updates to the source will be made to the codeplex site: codeplex.com/StoreLocator
Update 2008-10-14: Added a SQL file so that the DB can be generated for any other type of DB provider that you may wish to use. See bottom of post for SQL File.
Many organizations have multiple locations throughout the country. A lot of the time the organizations customers will want to know where the closet location of that store is. We’ve all become accustomed to going to a companies website and finding the store locator and locating the store that’s closest to us. This is a simple thing for a user to do. But building a store locator is far from simple and can become quite complex, real quick. I’ve put together a simple example that will enable you to add store locator functionality to your ASP.NET website in no time.
Let’s start by covering the basics….
Requirements for store locator functionality:
– Database to store your store locations
– Each store location needs a Longitude / Latitude
– A method to retrieve Latitude / Longitude, also known as Geocoding
– A Web Front end that allows users to search and view the results.
Screen Shots
Search Screen:
Results Screen (click for larger view):
The Database
The database is very simple. We have one table, two sprocs, and 3 functions. It is in the App_Data folder of this solution.
The Location table holds the store locations.
The GetNearbyLocations sproc gets the locations that are closest to the user through a mathematical calculation that is inside of the sproc.
The InsertLocation sproc inserts a new location into the Location table (we’ll get to that near the end).
The three functions: XAxis, YAxis, ZAxis are used in the distance calculation that is inside of the sproc.
Important Note: I’m not the genius that wrote this mathematical calculation. Therefore, I can’t take credit for it. The database table, functions and distance sproc are all modeled after this post on MSDN. I have altered quite a few things especially the GetNearbyLocations sproc where I actually calculate the Earths X,Y, and Z axis’ at runtime.
The Geocoding – Getting the Latitude / Longitude
The latitude and longitude are needed to perform the distance calculation in the GetNearbyLocations stored procedure. The Latitude and Longitude of each store is stored in the Locations table (see the database image above) with the location record itself.
How to do we get the Latitude / Longitude?
That’s where the Google Maps API comes into place. Google Maps allows you to sign up for a free API key.
Important Note: If you are going to test this locally, you will need to get a API key that is associated with your local machine, e.g.: http://localhost:port/ where “port” is your port number, such as: localhost:4688, localhost:1637, etc).
Where put your Google Maps API Key
The key is located in two places (I know, its not best practice) but, it’s the only way I could get it to work without spending hours on figuring it out. It’s located in the web.Config and in the Default.aspx page.
Default.aspx page (click for larger view)
web.Config
In a previous post I had built a class that retrieved the latitude and longitude of an address. By using this class while a new location is being added, (AddNewStore.aspx), the Lat/Lon coordinates are then retrieved and saved.
protected void addNewStoreButton_Click(object sender, EventArgs e)
{
string address = String.Format("{0}, {1}, {2} {3}",
addressTextBox.Text,
cityTextBox.Text,
stateTextBox.Text,
zipTextBox.Text);
Coordinate addressCoordinates = Geocode.GetCoordinates(address);
… // Other code ommitted
}
The Web Front End
The web front end is simple (errrrrrrr… kind of). The application requires 2 things:
1. An address
2. A distance to search within.
The user enters this information, it’s passed to the database, the calculation is performed and the records that match the distance compared to the address are returned. Simple, right?
Now its time for the “somewhat” confusing part: the task of integrating the Google map with clickable markers. Google doesn’t offer markers that are numbered (from what I could find). So I found some on the net and included them in this project. Which leads me to the next point…
A maximum of 100 results will be returned.
This is set within the stored procedure. The reason we only return 100 records is because we only have 100 icon images (1 through 100). Plus, placing more markers on the page would have a negative impact on the memory and processor on the user’s machine. Furthermore, who’s really going to look at 100 results? The user is probably only looking for the closest couple of stores. Not the top 100.
Google Marker Placement
In order to place markers on the screen we needed lat/lon points to pass to Google’s API. This poses a problem because our data is in the DB, but Google Maps API needs it on the client to process it. Therefore, while on the server, while we have the data in a dataset (below) …
/// <summary>
/// Gets the store locations and the coordinate for the "from" area (the address the user entered).
/// </summary>
/// <param name="coordinate">A coordinate.</param>
/// <param name="data">A LocationsData dataset.</param>
private LocationsData GetLocationData(Coordinate coordinate)
{
SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["StoresDb"].ConnectionString);
connection.Open();
string SQL = "GetNearbyLocations";
SqlCommand command = new SqlCommand(SQL, connection);
command.Parameters.Add(new SqlParameter("@CenterLatitude", coordinate.Latitude));
command.Parameters.Add(new SqlParameter("@CenterLongitude", coordinate.Longitude));
command.Parameters.Add(new SqlParameter("@SearchDistance", distanceDropDown.SelectedValue));
command.Parameters.Add(new SqlParameter("@EarthRadius", 3961)); // In Miles
command.CommandType = CommandType.StoredProcedure;
SqlDataAdapter da = new SqlDataAdapter(command);
LocationsData data = new LocationsData();
da.Fill(data.Location);
return data;
}
GetJSONLocations(LocationsData data);
… we have to create a string representation of a JSON object array that holds all this info, this is done in the GetJSONLocations method. Please see the method for more documentation on how that variable is created.
Info that the JSON object holds:
– Location Name
– Address
– Url Encoded Address
– Latitude
– Longitude
This info was written to the screen using the RegisterClientScriptBlock.
Using the same method of as before we create another JSON variable (homeSpatialInfo) that holds the “home info”. This info is the address that the user typed in.
This information is used for the popup marker, as well as the link that is provided within the popup marker. Clicking on the “directions” link (within the popup marker) will take you to Google’s map site with the “to” and “from” address parameters already populated, therefore giving you a directional map from the location you typed in, to the location that you clicked on the map. Smooth, eh?
(click for larger view)
Adding a new Location
To add a new location, fire up the AddNewStore.aspx page and type in the required info (in this case I’m requiring all fields, but this can be changed to fit your own needs) and submit. If the address cannot be found, (Google Maps API returns “0” for both the Lat/Lon coordinates that it cannot find) it will inform you. Otherwise the address will be added and then upon your next search, it will be returned in the results (if the location is within the distance specified).
Database Note: The locations that are in the Stores.mdf that come with this solution are 200 Starbucks stores that are within the New York Area. This is not a comprehensive list, this is just a list I happened to have for testing purposes.
And that’s all folks!
Download and enjoy. 🙂
The download has moved to CodePlex. Get the code here.
Mikefalebita says
This tutorial has been very interesting and helpful but I want to adapt it into a more robust situation. Where Users can filter locations based on business type i.e Banks, Store, Hotel etc.
Mikefalebita says
pLS can you help?
Mikefalebita says
Pls I need this Urgently.
Donn Felker says
You can provide another che Knox on the screen to allow filtering. To filter
it, add an additional where clause to the database query.
Sent from Android
user says
What does “ProxDistance” store?
Anonymous says
2011Louis Vuitton Handbagsbag bag in the dark or black and white and dichromatic most classical style, basic money to turn fur collocation, as frills Burberry Handbags, save the original aesthetic feeling, Coach USA lining is soft Nappa sheep. Black is timeless classic Chanel Outlet , a completely black, only a “cool” word to describe Louis Vuitton Bags. Once the woman was Wholesale Bags bag, confident belovedly feels dye-in-the-wood, seem to bag can cover it all unhappy. Army green tie-dye Coach Bags filar socks Gucci Bags, and elegant streets already. This dress is a fashion model, both in the love that a detail can see Europe fashionable Prada Purses. France is the most romantic city, at the same time here fashion stylish rider is not exceptional also, to dress Christian Louboutin Pumps has the unique idea, can always to dress up like the darling of the era. Noble purple adjusted, to dress has the unique idea, can always to dress up like the darling of the era.
Anonymous says
2011Louis Vuitton Handbagsbag bag in the dark or black and white and dichromatic most classical style, basic money to turn fur collocation, as frills Burberry Handbags, save the original aesthetic feeling, Coach USA lining is soft Nappa sheep. Black is timeless classic Chanel Outlet , a completely black, only a “cool” word to describe Louis Vuitton Bags. Once the woman was Wholesale Bags bag, confident belovedly feels dye-in-the-wood, seem to bag can cover it all unhappy. Army green tie-dye Coach Bags filar socks Gucci Bags, and elegant streets already. This dress is a fashion model, both in the love that a detail can see Europe fashionable Prada Purses. France is the most romantic city, at the same time here fashion stylish rider is not exceptional also, to dress Christian Louboutin Pumps has the unique idea, can always to dress up like the darling of the era. Noble purple adjusted, to dress has the unique idea, can always to dress up like the darling of the era.
Sdfsdf says
coach bags well designed for sale.
coach outlet handbags high replica online.
coach purses high quality for cheap.
coach outlet store onsale wholesale for cheap.
coach online wholesale online.
juicy couture cheap online for sale.
cheap juicy couture wholesale for cheap.
discount juicy couture fashion designed for sale.
discount juicy handbags high quality for sale.
cheap juicy handbags wholesale online for cheap.
juicy handbags cheap for sale.
Paintball Barrel says
Curious how this might be updated for maps api v3? and maybe for mvc3?
Chanel bags says
Armitage, who coach outlet online is yet to register Burberry Scarf a try in this year’s tournament, is Coach Outlet the second England player Chanel bags to receive a ban, after lock Courtney Lawes received Louis Vuitton Shop a two-match suspension for Handbags Outlets recklessly striking an opponent during a clash Coach Purse with Argentina.It has been Gucci Shoes a controversial campaign for England, with two members of Prada Handbags coach Martin Johnson’s staff not allowed to be on the ground for their crucial Christian Louboutin Shoes win over Scotland after being found guilty of illegally tiffany rings switching balls Moncler Sale in their previous match against Romania.On Estebanez, a statement the north face outle on the four-yearly competition’s official website read: “Estebanez was suspended by Independent Judicial Officer Christopher Quinlan QC (England) in accordance with the Rugby World Cup 2011 Disciplinary process.
haha says
authentic nfl jerseys Inexpensive items
coach bags on sale I am confident with his
coach outlet store online First step in success
coach outlet online Workmanship
coach bags outlet Value of goods
coach outlet store Of love
wholesale designer bags Beautiful lines
coach bags outlet There range of children
cheap coach What are you waiting
wholesale nfl jerseys Is always expected
authentic nfl jerseys It is pretty good
Carbonell35 Adam says
Hi Donn, I’ve had an adaptation of this working for a few yrs. Now the geolocation part (when entering a new location) has stopped working due to an updated Google api. Any suggestions on finding a workaround for this? I can obviously enter the locations manually, using their coords, but was looking to restore this to its original glory! Thanks!