|
|||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||
|
Announcements
Chapters
Services
Feature Zones
|
BackgroundA month or two ago (about the same time Google launched 'full' Map functionality in Australia) I started reading about the Google Maps API, but was a little discouraged by the Javascript-focus: it's definitely a powerful toolset but I didn't have time to learn it. Then I came across GMapEZ which is a great, 'declarative' mechanism to get Google Maps working quickly and easily. This article shows how you could use Google Maps (and parts of their API) along with GMapEZ to build a 'store locator' on your website - customers can type their location (zipcode, suburb or full street address) and be shown which stores are closest to them. Building a Store LocatorThe following things are required to build a map interface to your store directory:
Some things to note
Code Structure
Steps in detailEach of the steps listed at the beginning of the article are discussed below: 1. Your stores' locationsThe starting point for the Store Locator is knowing where all the stores are. In the sample, the address data is in an XML file which is a serialized
2. What is geocoding?
// load XML containing serialized Outlet[] objects
Outlet[] oa = Kelvin<Outlet[]>.FromXmlFile(infilename);
/*
Instead of opening an XML file to get the outlet list, you could
open a database connection here and loop through all your addresses
*/
foreach (Outlet o in oa)
{
if (null == o.Location)
{
o.Location = Geocoder.LocateGoogle
(o.StreetAddressString, o.Suburb, o.State, o.ZipCode);
/*
If you had a database, you could write the latitude/longitude for
each address back to the database here
*/
}
}
/*
Here we save the data to an XML for use by the ASPX page.
If you'd been saving each lat/long to a database inside the foreach
loop, you wouldn't need this
*/
Kelvin<Outlet[]>.ToXmlFile(oa, outfilename);
The application uses the Geocoder.LocateGoogle() method (which is located in the Common project) to call the webservice. The key lines of code are:
string url =
"http://maps.google.com/maps/geo?q={0}&output=xml&key=" + _GoogleMapsKey;
//...
string xmlString = GetUrl(url);
//...
coords = xd.GetElementsByTagName("coordinates")[0]; // assumes at least one
Geoloc? gl = new Geoloc (
Convert.ToDouble(coordinateArray[1].ToString())
, Convert.ToDouble(coordinateArray[0].ToString()));
When run, the console output looks like this:
3. Where is the customer?Now that we have our data 'geocoded', we need a webpage for the customer to:
There is just a single page in the The input form itself is very simple: <form runat="server" action="NeedCoffeeNow.aspx">
Enter your suburb (or postcode):<br />
<asp:TextBox Id="SuburbTextBox" runat="server" />
within
<asp:ListBox Id="MaxDistanceList" runat="server"
SelectionMode="single" Rows="1">
<asp:ListItem Text="2 km" Value="2" />
<asp:ListItem Text="5 km" Value="5" />
<asp:ListItem Text="10 km" Value="10" />
<asp:ListItem Text="20 km" Value="20" />
<asp:ListItem Text="50 km" Value="50" />
<asp:ListItem Text="200 km" Value="200" />
</asp:ListBox>
<br />
<asp:Button Id="FindButton" Text="Find Nearest" runat="server"
OnClick="FindButton_Click" />
<asp:Literal Id="DisplayLinks" runat="server" />
</form>
When the customer enters some data (either their zipcode, suburb or full street address) the // Find the START LOCATION (entered by the user)
Geoloc startLocation = Geocoder.LocateGoogle (
this.SuburbTextBox.Text + "," +
ConfigurationManager.AppSettings["Country"])??new Geoloc();
4. Which store is closest?With both the customer's location and all the store locations available as latitude/longitude pairs, we need an algorithm to determine the distance between the customer and each store so we can find out which ones are the closest. In fact, we will get the distance to every store and "order them" according to the distance from the customer. Thankfully, CodeProject authors come to the rescue again, with C# implementation of "The Haversine formula". If you know of another algorithm, you can easily plug it into the The ASPX page loops through every store and determines the distance from the customer, adding each result to a // Generate the NEAREST OUTLETS list,
// calculating the distance between every Outlet in our XML 'database'
// and the start location; adding to a SortedList by distance
SortedList<Double, Outlet> nearest
= new System.Collections.Generic.SortedList<double, Outlet>();
foreach (Outlet o in oa)
{ if (o.Location.HasValue)
{
Double distance = Distance(startLocation, o.Location.Value);
nearest.Add(distance, o);
}
}
5. Bringing it all together: Google Maps & GMapEZHaving 'geocoded' our stores and the Customer's location, and calculated the distance between them, all we need to do is display the results! A good place to start is the GMapEZ Documentation which explains that in order to display a map with markers, all you need is a really simple HTML page, like this: <html xmlns:v="urn:schemas-microsoft-com:vml">
<head>
<title>My GMapEZ Maps</title>
<meta name="gmapkey" content="abcdefg" />
<script
src="http://bluweb.com/chouser/gmapez/gmapez-2.js"
type="text/javascript"></script>
</head>
<body>
<div class="GMapEZ" style="width: 300px; height: 300px;">
<!-- points go here -->
</div>
</body>
</html>
and as many markers as you need (where it says <a href="http://maps.google.com/maps?ll=-33.867617,151.20842"></a>
If you look closely at the output in the ASPX page, it's a little more complex: <a id="idWynyard"
href="http://maps.google.com/maps?ll=-33.86584,151.207265"
title="Wynyard">GREEN</a><div><p><b style="color:Green;">
Wynyard</b> (0.1kms)<br />301 George Street<br />Sydney, NSW, 2000</p>
<form action="http://maps.google.com/maps?f=d&hl=en">
<span style="color:Gray;font-size:smaller">
Enter your address to find your way here</span><br />
<input name="saddr" value="Sydney"/>
<input name="sll" value="-33.867139,151.207114" type="hidden"/>
<input name="daddr" value="-33.86584,151.207265" type="hidden"/>
<input type="submit" value="Get directions" />
</form></div>
To quickly explain some of the extra bits:
The GMapEZ foundation "requires" strict adherence to XML standards in the page, so "be careful" when playing with the sample code. If the page stops working, it's probably due to a missing close-tag or some other minor XML validation error. Wrap-upThe download is really just a proof-of-concept: most sites will have a database of addresses to display, and possibly logged-in customers so you'll already know their address. Alternatively you may find other uses for either the geocoding application or the GMapEZ mapping interface - have fun! P.S. You can try the NeedCoffeeNow sample online. | ||||||||||||||||||||||||||