Blog Post

Embedding Bing Maps in a Web Page

,

I was doing some maintenance on the SQLSaturday web site recently and one request kinda low on the list was to try using Bing Maps. We’ve been using Google Maps (see SQLSaturday #17 for an example) because it’s easy to use. Just enter the address and make sure it’s the one you want, then click “Link” in the upper right hand menu and copy the HTML, giving you something like this:

<iframe width="425" height="350" frameborder="0" scrolling="no" marginheight="0" marginwidth="0" src="http://maps.google.com/maps?f=q&amp;source=s_q&amp;hl=en&amp;geocode=&amp;q=225+S+Westmonte+Dr,+Altamonte+Springs,+FL+32714&amp;sll=37.0625,-95.677068&amp;sspn=46.764446,78.662109&amp;ie=UTF8&amp;z=14&amp;iwloc=A&amp;ll=28.671085,-81.388779&amp;output=embed"></iframe><br /><small><a href="http://maps.google.com/maps?f=q&amp;source=embed&amp;hl=en&amp;geocode=&amp;q=225+S+Westmonte+Dr,+Altamonte+Springs,+FL+32714&amp;sll=37.0625,-95.677068&amp;sspn=46.764446,78.662109&amp;ie=UTF8&amp;z=14&amp;iwloc=A&amp;ll=28.671085,-81.388779" style="color:#0000FF;text-align:left">View Larger Map</a></small>

Not  much to look at but it works, no code. We’ve got a column in event table where it’s stored, making it easily and nicely data driven. When I added the task my thought was it only going to consist of changing the prompt in the setup to “bing”. No…..

Turns out that Bing doesn’t provide that same kind of support, that I could find at least. Putting a link to the map is easy, but a live working map seemed to require code. I found a couple of blog posts like this one and groaned, didn’t really want to put time into it. Finally convince myself on a Sunday morning that it would be a good learning opportunity and off I go.

If you look at the code in the post I just referenced they are calling a JavaScript function in the Body OnLoad event. That’s easy enough to copy, except – I’m using master pages (a easy way to apply consistent elements to each page) and the master page has the BODY tag. I don’t really want this function running on every page when it only applies to one. Finally I ask the right question and end up with this in the Page load event:

'only run map code if we have the data
If Me.lblLatitude.Text <> "" And Me.lblLongitude.Text <> "" Then
    Me.ClientScript.RegisterStartupScript(Page.GetType, "Startup", "<script language='javascript'>try { GetMap();} catch (error) {}</script>")
Else
    Me.BingMap.Visible = False
    Me.litMap.Text = oEvent.MapURL
End If

For those less code inclined by the time this runs I’ve already loaded and displayed the lat/long from the database (stored as varchar if you’re wondering) and now I’m branching based on whether those values exist. That is to avoid breaking all the old events that have the Google code stored. The meat of it is the RegisterStartupScript that ultimately adds the call to the GetMap function in the Body OnLoad event.

Then, I need to add some JavaScript to the location page. I think this can be injected at runtime as well, but since it won’t change much, saw no reason not to embed it:

<script type="text/javascript" src="http://dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=6.2"></script>

<script type="text/javascript">
   var map = null;
   myBingZoom = 14;

   function GetMap() {

          try
              {
                var myBingLat = document.getElementById('<%=lblLatitude.ClientID%>').outerText;
                var myBingLng = document.getElementById('<%=lblLongitude.ClientID%>').outerText;
                var divtag = document.getElementById('<%=BingMap.ClientID%>');
                var mybirdWaypoint = new VELatLong(myBingLat, myBingLng);
                map = new VEMap(divtag.id);
                map.LoadMap(mybirdWaypoint, myBingZoom);
                map.AddPushpin(mybirdWaypoint);
                }
           catch (Error)
              {
              }
   }
</script>

And then in the page where I wanted the map, added this:

<div id="BingMap" style="position:relative; width:400px; height:285px;" runat="server" visible="true"></div>

Now if you know what you’re doing that’s about 10 minutes worth of work. Took me 2 hours to get it all done. If you decide to try this remember that JavaScript is case sensitive. Case Sensitive. CASE sensitive. Next, Visual Studio 2008 will debug client side JS if you enable debugging – which strangely enough is a browser setting and not in VS – but a real help, very cool feature.

You’ll see two lines that get the lat and long from the controls. Maybe there is an easier way, but this was the example I found and went with it. The “getelemementbyID” exists to translate what I called the lat/long controls at design time to what they were finally called by asp.net when the entire page was rendered.

One other note. In my case I only wanted to show the map if I had lat/long, but originally it still took up space on the page. The answer was to add “runat=Server” to the div tag so that I could flip the visible property to false in code as needed, eliminating the white space it was reserving.

I haven’t found a solid way of getting the event lat/long yet, though I can’t say I’ve looked deeply. Sometimes it shows up in the Bing URL (I think). Found this site that provides them using a few difference sources, but none of them seemed to be quite right when I plugged in values for SQLSaturday #16 (example here).

It was an interesting project and while not necessarily the best use of my time when I look at now versus then, it may lead to something more interesting like being able to map all of the SQLSaturday events easily on one map. But that’s on the list for another day!

 

 

Rate

You rated this post out of 5. Change rating

Share

Share

Rate

You rated this post out of 5. Change rating