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.

Live Demo | Download

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!


TrackBack

TrackBack URL for this entry:
http://mattberseth.com/blog-mt/mt-tb.fcgi/58

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.

Posted by: lien jardine on April 21, 2008 12:00 AM

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?

Post a comment

(If you haven't left a comment here before, you may need to be approved by the site owner before your comment will appear. Until then, it won't appear on the entry. Thanks for waiting.)

Consulting Services

Yep - I also offer consulting services. And heck, I'll do just about anything. If you enjoy my blog just drop me an email describing the work you need done.

Recent Comments

  • lien jardine wrote: I am trying to get the VE pushpin functionality to work with the codes provided on your website. I ...
  • Gfw wrote: Great article and thanks for posting. I used it on my site at <a href="http://yyyz.net/VirtualEarth/...