Tuesday, 2 June 2009

Using Microsoft Bing Maps in SharePoint

The last time I blogged I wrote about SharePoint and Google Maps – specifically how to display maps in a SharePoint Web Part. Since you frequently have geographical information stored in SharePoint, most often as postal addresses, this is a really powerful addition to your developer arsenal. But Google Maps is only one of the mapping providers you can use in this way, for example, there's MapQuest and Yahoo! Maps.

Microsoft's mapping solution is called Bing Maps. Just last week Microsoft announced it is rebranding Virtual Earth as Bing Maps. The API that you use to place Bing Maps on your Web site is now called Bing Maps for Enterprise. For those of you who've developed Virtual Earth code before, you'll be pleased to know there's not much change. A few people asked me how to use this technology in SharePoint – it can be done in a very similar way to Google Maps and in this post I'll cover the differences.

Review of Architecture

As for the Google Maps solution I described in my last post, the interesting part about this task is getting a largely server-side technology like SharePoint to work with a client-side technology like Bing Maps. Suppose you have some search results, each of which has a latitude and longitude, that you want to display in a list and on a map. In a conventional Web Part you'd loop through the results in server-side ASP.NET code to build an HTML list to display on the browser. Bing Maps uses JavaScript on the client to add pushpins like this:

var shape = new VEShape(VEShapeType.Pushpin, map.GetCenter());

shape.SetTitle('A new pushpin');

shape.SetDescription('This is just to demonstrate pushpins');


So the question is, how to get client-side code to loop through a collection that only exists on the server?

Our approach is to render an XML island that contains relevant information for each search result. The client side code can locate this island and loop through it, adding a pushpin or another shape for each entry. We'll put the JavaScript in a separate file but embed it as a resource in the .NET assembly as we did for Google Maps.

You could also consider an AJAX-style approach to this problem: this would consist of a Web service that receives search terms and returns results. Client-side code could both render the list and the pushpins on the map and you get all the improvements in responsiveness that are achievable with good AJAX coding. One thing to watch out for: the built-in SharePoint Web Services are not enabled for AJAX so you'd have to write your own.

Most of the coding for this Bing Maps solution is exactly the same as for Google Maps, so you should read this after digesting the previous post. The following tasks are exactly the same:

  • Rendering the XML Data Island.
  • Registering and embedding the scripts in the Web Part assembly.
  • Parsing the XML Island.

That leaves us with three tasks that are different for Bing Maps. I'll describe these below.

Map Results Web Part

To put a Bing Map on a static Web page you must first link to the scripts library:

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

Then you must use a <div> tag to position and size the map:

<div id='myMap' style="position:relative; width:800px; height:600px;"></div>

These can both be rendered in server-side code like the following in your map Web Part's Render method:

protected override void Render(System.Web.UI.HtmlTextWriter writer)
      //Render the script tags that link to Google Maps API
      writer.WriteLine("<script " +
           "src=\"http://ecn.dev.virtualearth.net/mapcontrol/" +
            "mapcontrol.ashx?v=6.2\" " +
            "type=\"text/javascript\"> </script>");
      //Render the div that will display the map
      writer.Write("<br /><div id=\"map\" " +
            "style=\"position:relative; width: 800px; height: 600px\" ></div>");

Loading the Map

This JavaScript function loads and sets properties for the map. This should go in the JavaScript file you have embedded in the Web Part assembly:

var map;

function loadMap(){
      //Create the map
      map = new VEMap("map");
      //The default latitude and longitude.
      var latlong = new VELatLong(54.59088, -4.24072);
      //The default zoom level
      var zoomlevel = 5;
      map.setCenterAndZoom(latlong, zoomLevel);
      //Add the controls
      //Parse the XML in the HTML data

The parseXmlIsland function is just like that for Google Maps because the XML is the same. For each result in the XML island, it adds a pushpin.

Adding Pushpins

This addPushPin function inserts a new pin at the longitude and latitude specified. The parseXmlIsland function calls this for each result:

function addPushPin(Title, Path, Latitude, Longitude){
      //Formulate the HTML that goes into the caption window
      var infoHtml = "<a href="http://www.blogger.com/">" + Title + "</a>";
      //Add the pushpin
      var pinLatLong = new VELatLong(Latitude, Longitude);
      var pin = new VEShape(VEShapeType.PushPin, pinLatLong);
      pin.SetTitle("<h2>" + Title + "</h2>"
      //Add an info window
      //Add pushpin to the map


So you can Bing Maps in SharePoint using just the same approach as Google Maps. The coding details have differences but the overall architecture and some of the tasks are identical. All the code in both my posts uses latitude and longitude, but both APIs provide geo-coding functions that can convert an address into polar co-ordinates if you need it.


Windows SharePoint Services Developer Center

SharePoint Server Developer Center

Bing Maps Interactive SDK


Anonymous said...

I am using this same approach. However the map loads so slow. I can see the map from asp.net application in approximately 20 sec. However when I link it in a page viewer in Sharepoint, it takes around 30 secs. I have around 200 locations to put it in the map. Is that why it takes time? Please help. Thanks

Atramental said...
This comment has been removed by the author.
Atramental said...

I have managed to add a map with pushpins to my sharepoint site, which porks perfectly. Unfortunately when viewed through FireFox the map displaysoutside of the webpart frame and fills the screen when zooming in.

Any ideas what would be required to be added to the script to prevent this?

Nadeem Yousuf said...

This example shows how to create a bing map in Silverlight and then integrating it in SharePoint