Virtual Earth WebPart

4 minute read

After reading a post on the blog of Wesley Bakker I thought by myself maybe it is fun to create a webpart in which we can load a map from Virtual Earth.

And so I did I began with creating a webpart with certain properties so that you can also add a location and a pushpin for that location.

First you have to think off a way to get the virtual earth map in the webpart. I have done this by writing the JavaScript to the page in the render method off the webpart.

[Guid("d2a82f7b-d32b-4154-8370-2a2bae4f7af7")]
  public class VirtualEarthWebPart : System.Web.UI.WebControls.WebParts.WebPart
  {
         public VirtualEarthWebPart()
         {
         }

         protected override void Render(HtmlTextWriter writer)
         {
             string javascript = null;

             if (String.IsNullOrEmpty(strLocation))
             {
                 javascript = "This query has returned no items. To configure the query for this Web Part, <a href=\"javascript:MSOTlPn_ShowToolPane2Wrapper('Edit', this, '" + this.ID + "')\">open tool pane</a>.";
             }
             else
             {
                 //Create Java Script String
                 javascript = CreateJavaScriptString();
             }

             writer.Write(javascript);
         }

         public string CreateJavaScriptString()
         {
             StringBuilder htmltext = new StringBuilder();

             htmltext.Append("<script src=\"http://dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=6.2\"></script>");
             htmltext.Append("<script type=\"text/javascript\">");

             htmltext.Append(" var map = null; ");
             htmltext.Append(" var points = null; ");
             //Load Virtual Earth Map
             htmltext.Append("  function GetMap() ");
             htmltext.Append("  { ");
             htmltext.Append("    map = new VEMap('myMap'); ");
             htmltext.Append("    map.LoadMap(); ");
             htmltext.Append("    map.Find(null, '" + strLocation + "', null, null, null, null, false, false, true, true, findAddressCallBack); ");
             htmltext.Append("  }");

             htmltext.Append(" function findAddressCallBack(thelayer, resultsArray, places, hasMore, veErrorMessage) ");
             htmltext.Append(" { ");
             htmltext.Append("   if(places != null && places.length >0) ");
             htmltext.Append("   { ");
             htmltext.Append("     var latitude = places[0].LatLong.Latitude; ");
             htmltext.Append("     var longitude = places[0].LatLong.Longitude; ");
             htmltext.Append("     points = new VELatLong(latitude, longitude); ");
             htmltext.Append("     try ");
             htmltext.Append("     { ");
             htmltext.Append("       var shape = new VEShape(VEShapeType.Pushpin, points); ");

             //Set Custom Image URL
             if (!String.IsNullOrEmpty(customIconUrl))
             {
                 htmltext.Append(" shape.SetCustomIcon('" + customIconUrl + "'); ");
             }

             //Set Location Title
             if (!String.IsNullOrEmpty(titleLocation))
             {
                 htmltext.Append(" shape.SetTitle('" + titleLocation + "'); ");
             }

             if (!String.IsNullOrEmpty(descriptionLocation))
             {
                 htmltext.Append(" shape.SetDescription('" + descriptionLocation + "'); ");
             }

             if (!String.IsNullOrEmpty(photoLocation))
             {
                 htmltext.Append(" shape.SetPhotoURL('" + photoLocation + "');    ");
             }

             if (!String.IsNullOrEmpty(moreLocation))
             {
                 htmltext.Append(" shape.SetMoreInfoURL('" + moreLocation + "'); ");
             }

             if (zoomLevel != 0 && zoomLevel <= 19)
             {
                 htmltext.Append("  map.SetZoomLevel(" + zoomLevel + "); ");
             }

             if (modeEnum == MapModeEnum.TwoDimensional)
             {
                 htmltext.Append("       map.SetMapMode(VEMapMode.Mode2D); ");
             }
             else
             {
                 htmltext.Append("       map.SetMapMode(VEMapMode.Mode3D); ");
             }
             htmltext.Append("       map.AddShape(shape); ");
             htmltext.Append("      map.SetMapStyle(VEMapStyle." + mapEnum.ToString() + "); ");
             htmltext.Append("     } ");
             htmltext.Append("     catch(e) ");
             htmltext.Append("     { ");
             htmltext.Append("       alert(e.message); ");
             htmltext.Append("     } ");
             htmltext.Append("   } ");
             htmltext.Append(" } ");

             //Add Function GetMap to the LoadEvent
             htmltext.Append("  function addLoadEvent(func) ");
             htmltext.Append("  { ");
             htmltext.Append("    var oldonload = window.onload; ");
             htmltext.Append("    if(typeof window.onload != 'function') ");
             htmltext.Append("    { ");
             htmltext.Append("      window.onload = func; ");
             htmltext.Append("    } ");
             htmltext.Append("    else ");
             htmltext.Append("    { ");
             htmltext.Append("      window.onload = function()");
             htmltext.Append("        { ");
             htmltext.Append("          func(); ");
             htmltext.Append("        } ");
             htmltext.Append("    } ");
             htmltext.Append("  } ");

             htmltext.Append("  addLoadEvent(GetMap); ");

             htmltext.Append("</script> ");
             htmltext.Append("<div id='myMap' style=\"position:relative;\"></div>");

             return htmltext.ToString();
         }

     } 

In the code displayed above I created a StringBuilder with the complete JavaScript and even a html section (div) for displaying the map. In the code above you can also see multiple checks for empty strings. This I have done for certain properties I have added to the webpart.

The properties I have added to the webpart are written down at the end of this post. In the code section below I have added two examples off properties I created for the webpart.

 public enum MapStyleEnum
 {
       Road, Shaded, Aerial, Hybrid, Oblique, Birdseye, BirdseyeHybrid
 };

 protected MapStyleEnum mapEnum;

 /// <summary>
 /// property for the Map Style
 /// </summary>
 [WebBrowsable(true),
 Personalizable(true),
 Category("Virtual Earth Map Settings"),
 DisplayName("Map Style"),
 WebDisplayName("Map Style"),
 Description("Please choose a Map Style.")]
 public MapStyleEnum MyEnum
 {
      get
      {
         return mapEnum;
      }
      set
      {
          mapEnum = value;
      }
 }

 //Custom icon
 private string customIconUrl;

 /// <summary>
 /// property for the location title
 /// </summary>
 [WebBrowsable(true),
 Personalizable(true),
 Category("Virtual Earth Location Settings"),
 DisplayName("Custom Icon Url"),
 WebDisplayName("Custom Icon Url"),
 Description("Please enter the url off the custom icon.")]
 public string CustomIconUrl
 {
   get
   {
       return customIconUrl;
   }
   set
   {
     customIconUrl = value;
    }
  }