Virtual Earth Map Control within a ModalPopup
As mentioned in my previous post, I am currently researching different ways my current projects web application can better leverage the Virtual Earth Map Control. Currently, we have a single page buried deep in our sitemap that users can use to view an aerial photo of a particular property. Users love the mapping feature and have requested that it be made available on more of our screens.
Our applications most heavily used screen allows users to search for real estate that is currently for sale. The page is setup as a standard search page with a handful of input elements at the top of the page that the user enters parameters into. When they click search, we run fetch the records that meet their criteria and populate a GridView with the results. We thought it might be interesting if we could display the Virtual Earth Map as a popup right on this search screen. To see what this would take I created a sample page that displays the names, address and geo information from 10 random celebrities (aren't you curious what Neverland Ranch looks like from 10,000 feet?). The last column in the GridView contains a 'View Map' link that when clicked displays a map of where the selected celebrity lives within a Virtual Earth Map. The best part - no postbacks are required. The following outlines the steps I used to create this sample page.
Create the DataSource
To generate the ten records for test data I went to http://www.celebrityweb.com/address.htm to find a few celebrities addresses. Once I had the address I used batchgeocode (http://www.batchgeocode.com/lookup/) to get the latitudes and longitudes.
Next, following the portability guidelines I talked about here, I created an xml file and business object that I used to fetch the celebrity records. A sample celebrity record takes the following format
<celebs> <FirstName>Kevin</FirstName> <LastName>Bacon</LastName> <Address>9830 Wilshire Boulevard</Address> <City>Beverly Hills</City> <State>CA</State> <ZipCode>90212</ZipCode> <Latitude>34.066963</Latitude> <Longitude>-118.410621</Longitude> </celebs>
Finally, I wire the business object to the ObjectDataSource specifying the TypeName and SelectMethod like so
<asp:ObjectDataSource ID="odsCelebs" runat="server" SelectMethod="Select" TypeName="CelebrtiesDataObject" />
Create Client Side JavaScript Functions
Next, I created 2 client side JavaScript functions. One for creating and initializing the VEMap and the other for displaying the ModalPopup as well as adding the pushpin to the VEMap surface. The inline comments cover these functions pretty well ...
<script type="text/javascript"> var map; function pageLoad(sender, args){ if(!args.get_isPartialLoad()){ // create and the map map = new VEMap('myMap'); // put the dashboard into tiny mode map.SetDashboardSize(VEDashboardSize.Tiny); } } function showMap(latitude, longitude){ // show the popup $get('btnShowPopup').click(); // relaod the map map.LoadMap(); // put the map in hybrid mode map.SetMapStyle(VEMapStyle.Hybrid); // create the VELatLong and add the pushpin // to the map var veLatLong = new VELatLong(latitude, longitude); map.AddPushpin(veLatLong); // center the map map.SetMapView(new Array(veLatLong)); } </script>
Wire up OnClientClick to Call Our showMap JavaScript Function
Next, I wired the OnClientClick LinkButton to call the showMap javascript function passing the Latitude and Longitude of the current row. This could have all be done in the markup except the OnClientClick doesn't support the databinding syntax. To get around this I handle the OnRowDataBound GridView event and set the OnClientClick property like so
protected void GvCelebs_RowDataBound(object sender, GridViewRowEventArgs e) { if (e.Row.RowType == DataControlRowType.DataRow) { // extract the link button LinkButton lnkViewMap = (LinkButton)e.Row.FindControl("lnkViewMap"); // grab the datarowview System.Data.DataRowView row = (System.Data.DataRowView)e.Row.DataItem; // set the onclientclick to fire our showMap javascript function, // passing through the lat/longs lnkViewMap.OnClientClick = string.Format("showMap({0}, {1}); return false;", row["Latitude"], row["Longitude"]); } }
Add the Markup for the GridView, VEMap and Popup Control
The last piece is to add the markup for the div element that contains the VEMap as well as the ModalPopupExtender. I placed the map in a table along with a Close button that will dismiss the dialog. Because the dialog is always programmatically displayed the button that triggers the modal to popup (TargetControlID) is marked as hidden so it is not displayed to the user, but it is still available to our JavaScript.
<asp:GridView ID="gvCelebs" runat="server" DataSourceID="odsCelebs" OnRowDataBound="GvCelebs_RowDataBound" AutoGenerateColumns="false" AllowSorting="true" Width="100%"> <AlternatingRowStyle BackColor="aliceBlue" /> <HeaderStyle HorizontalAlign="Left" /> <Columns> <asp:BoundField HeaderText="First Name" DataField="FirstName" SortExpression="FirstName" /> <asp:BoundField HeaderText="Last Name" DataField="LastName" SortExpression="LastName" /> <asp:BoundField HeaderText="Address" DataField="Address" SortExpression="Address" /> <asp:BoundField HeaderText="City" DataField="City" SortExpression="City" /> <asp:BoundField HeaderText="State" DataField="State" SortExpression="State" /> <asp:BoundField HeaderText="Zip Code" DataField="ZipCode" SortExpression="ZipCode" /> <asp:TemplateField> <ItemTemplate> <asp:LinkButton ID="lnkViewMap" runat="server" Text="View Map" /> </ItemTemplate> </asp:TemplateField> </Columns> </asp:GridView> <asp:Panel ID="pnlPopup" runat="server" style="display:none"> <table> <tr> <td> <div id="myMap" class="map" /> </td> </tr> <tr> <td align="right"> <asp:Button ID="btnClose" runat="server" Text="Close" Width="50px" /> </td> </tr> </table> </asp:Panel> <asp:Button ID="btnShowPopup" runat="server" style="display:none" /> <ajaxToolkit:ModalPopupExtender ID="mdlPopup" runat="server" CancelControlID="btnClose" PopupControlID="pnlPopup" TargetControlID="btnShowPopup" BackgroundCssClass="modalBackground" />
Thats it. Enjoy!
Comments
Great article and thanks for posting. I used it on my site at http://yyyz.net/VirtualEarth/VirtualEarth5.aspx
Have you figured out how to show the info box when the mouse hovers over the pushpin?
Thanks in advance for any help.
I am trying to get the VE pushpin functionality to work with the codes provided on your website. I am unable to get it to work. Any thoughts?