Share this page

Tuesday, June 16, 2009

Webpart to use Bing Maps in Sharepoint 2007 y WSS 3.0

Last month I was working in a new portal in Sharepoint to show information about the new virus A(N1H1). In this project I developed a Webpart to show the hospitals location in the maps using the Bing services.
In this article I want to share a generic Webpart that we can use to show locations around the world using latitude and longitude saved in a list of Sharepoint. The only requirement is that the list must have a content type associated. This content type only adds a few columns to handle the points and information to show a message when the point is loaded. In image 1 we can see the Webpart in Sharepoint. For this example I’m using the latitude and longitude of Uruguay, my country.

[Image 1]
clip_image002

The development has been done in Visual Studio 2008 and has 3 projects:

1) Class Library -> This component handles the interaction with Sharepoint lists and code behind our user control.

2) Project Web-> In this project we are going to create a user control (ASCX).

3) WSPBuilder project-> In this project we are going to create a solution to install in Sharepoint as a feature.

Before starting with the development, we need to understand how the Bing maps services work and how we can use them. Using JavaScript we can access the services and the object model to create our maps. The first thing that we need to do is register the reference to the SDK. In section 1 we can see this reference.

[Section 1]

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

Now we are going to add an HTML object where the maps will be loaded in our user control. The HTML that we should use is a DIV, in section 2 we can see the HTML that we created in our code.

[Section 2]

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

The next step is to create the JavaScript function to generate the object needed to show a map. The first object that we must create is “VEMap”. This object represents a map in JavaScript and in the constructor we must set the name of the HTML object where we want to show the map. In this example we must set the Id of the DIV added to the user control. In section 3 we can see the function named “GetMap()”.

[Section 3]

<script type="text/javascript">
         var map = null;         
         function GetMap()
         {
            map = new VEMap('myMap');
            map.LoadMap(new VELatLong(47.6, -122.33), 10 ,'r' ,false);
         }   
</script>


In this function the first thing that we need to do is to create an instance of the object VEMap, and as commented before, we must set the ID of the HTML object. Once the instance is created, we are going to invoke the method LoadMap and we have to set the different parameters. The first parameter is the instance of the object VELatLong and in the constructor we must set the latitude and longitude of the point that we want to show in the map. The second parameter is the zoom level from 1 to 19. The third is a style enumeration. In figure 1 we can see a message with the point to show additional information. We can create this message using the object VEShape and we must set a few parameters in the constructor. In section 4 we can see the source code that we are using in this example to load a point with its message.



[Section 4]



    <script type="text/javascript">
         var map = null;
         var pinid = 0;
         function GetMap(pVeLatLong, pZoom) {
            map = new VEMap('myMap');
            map.LoadMap(pVeLatLong, pZoom, 'r', false);
        }
         function AddPushpin(pVeLatLong, pNombre, pDescripcion) {
             var shape = new VEShape(VEShapeType.Pushpin, pVeLatLong);
             shape.SetTitle(pNombre);
             shape.SetDescription(pDescripcion);
             pinid++;
             map.AddShape(shape);
         }
         var mm_load = window.onload;
         window.onload = function() {
         if (typeof LoadMapa != 'undefined')
             LoadMapa();
             if (typeof mm_load != 'undefined')
                 eval(mm_load);
         }
    </script>


Very well, the next step is to create the code behind our user control. In this example we are using C# as server code. In the code behind we must develop the Load event and SelectedIndexChanged. In the Load event we must show all points in the DropDownList and in the event SelectedIndexChange we must load the map in our user control injecting the latitude and longitude saved in the list of Sharepoint.

Once our code is ready, we are going to change the “Control” directive of our user control to set the assembly where the class of our user control was implemented. In section 5 we can see the directive of our control.



[Section 5]



<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="LocationsVirtualEarth.ascx.cs" Inherits="Siderys.Blog.VirtualEarth.UI.UserControl.LocationsVirtualEarth, Siderys.Blog.VirtualEarth.UI, Version=1.0.0.0, Culture=neutral, PublicKeyToken=711eed342842acee" %>



Now we are going to work in the WSPBuild project to prepare our package to install the solution in Sharepoint. In section 2 we can see the folders created to install all files needed in Sharepoint.



[Image 2]

clip_image003



When a project using WSPBuilder is created, a folder named “12” is also created. This folder represents the one created by Sharepoint during the installation, C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12. We must create the folders where the files must be saved, for example, the features are created in the folder named “Features” inside the folder named “Template”. To install our feature we must create a folder inside the “Features” folder and we must save the files to our feature in this folder. In section 3 we can see all files in their folders. If you create a feature using the template item that was added when we installed the WSPBuilder add-in, the folder for the feature will be created automatically. In section 3 we can see all the files needed to install the solution inside their folders.



[Image 3]

clip_image004



Some files are not included in the project because they will be copied (using a configuring script in the properties of the project) when we compile the solution or project in Visual Studio. When the feature in Sharepoint is activated, a content type will be created with its fields. This content type must be associated to the list. In section 6 we can see the XML needed to create a feature in Sharepoint that will be saved in the file “SiderysVirtualEarthMapContentType.xml”.



[Section 6]



<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <ContentType ID="0x01001B25C760504E45c8AA38B26573E16F61"               
    Name="Siderys.Blog.VirtualEarthMap"
    Group="Siderys.Blog"
    Description="Content Type to add fields to create a point to use in maps">
    <FieldRefs>
      <FieldRef ID="{0664FE0B-F9B2-46eb-B069-0DAE0C610935}" Name="Name Point" Required="TRUE"  ShowInEditForm = "TRUE" ShowInNewForm = "TRUE" ShowInDisplayForm ="TRUE"/>
      <FieldRef ID="{613ADC57-8EB4-49c3-BC76-126791C6C050}" Name="Latitude" Required="TRUE"  ShowInEditForm = "TRUE" ShowInNewForm = "TRUE" ShowInDisplayForm ="TRUE"/>
      <FieldRef ID="{FD566634-C1E0-45d5-BB4E-41A364C5AA37}" Name="Longitude" Required="TRUE"  ShowInEditForm = "TRUE" ShowInNewForm = "TRUE" ShowInDisplayForm ="TRUE"/>
      <FieldRef ID="{CF35C355-55F7-4131-9D94-A4957C750F38}" Name="Address Point" Required="TRUE"  ShowInEditForm = "TRUE" ShowInNewForm = "TRUE" ShowInDisplayForm ="TRUE"/>
      <FieldRef ID="{1DAE65FF-9FA5-48ce-A1D7-E4634F97A219}" Name="Phone Point" Required="TRUE"  ShowInEditForm = "TRUE" ShowInNewForm = "TRUE" ShowInDisplayForm ="TRUE"/>      
    </FieldRefs>
   </ContentType>
</Elements>


In our feature we are going to use custom site columns and these columns will be created when the feature is activated. Each column is added in the "Content Type" using the node FieldRef as we can see in the section 6, but we need to create all of them using an XML. We are going to define each site column in the file named Fields.xml. In section 7 we can see the XML needed to create the sites columns.



[Section 7]



<Elements xmlns="http://schemas.microsoft.com/sharepoint/"
xmlns:sen="http://schemas.seneca.com/sharepoint/">
  <Field
    ID="{0664FE0B-F9B2-46eb-B069-0DAE0C610935}"
    Type="Text"
    Name="NamePoint"
    DisplayName="Name Point"
    StaticName="NamePoint"
    Hidden="FALSE"
    Required="TRUE"
    Sealed="FALSE"
    Group="Siderys.Blog"
    Description="Name of the point"/>
  <Field
    ID="{613ADC57-8EB4-49c3-BC76-126791C6C050}"
    Type="Text"
    Name="Latitude"
    DisplayName="Latitude"
    StaticName="Latitude"
    Hidden="FALSE"
    Required="TRUE"
    Sealed="FALSE"
    Group="Siderys.Blog"
    Description="Latitud of the point"/>
  <Field
    ID="{FD566634-C1E0-45d5-BB4E-41A364C5AA37}"
    Type="Text"
    Name="Longitude"
    DisplayName="Longitude"
    StaticName="Longitude"
    Hidden="FALSE"
    Required="TRUE"
    Sealed="FALSE"
    Group="Siderys.Blog"
    Description="Longitude of the point"/>
  <Field
    ID="{CF35C355-55F7-4131-9D94-A4957C750F38}"
    Type="Text"
    Name="AddressPoint"
    DisplayName="Address Point"
    StaticName="AddressPoint"
    Hidden="FALSE"
    Required="TRUE"
    Sealed="FALSE"
    Group="Siderys.Blog"
    Description="Direccion of the point"/>
  <Field
    ID="{1DAE65FF-9FA5-48ce-A1D7-E4634F97A219}"
    Type="Text"
    Name="PhonePoint"
    DisplayName="Phone Point"
    StaticName="PhonePoint"
    Hidden="FALSE"
    Required="TRUE"
    Sealed="FALSE"
    Group="Siderys.Blog"
    Description="Phone of the point"/>
</Elements>


The last file that we are going to create is the feature.xml and in this file we are going to define the feature for Sharepoint. In section 8 we can see the XML needed to create a feature.



[Section 8]



<Feature  Id="F8AC6324-85CA-4222-B0A0-493E7039C5C9"
          Title="Siderys.Blog.VirtualEarth.UI.WebPart"
          Description="WebPart to show locations in a Virtual Earth Maps"
          Version="12.0.0.0"
          Hidden="FALSE"
          Scope="Site"
          DefaultResourceFile="core"
          xmlns="http://schemas.microsoft.com/sharepoint/">
  <ElementManifests>
    <ElementManifest Location="elements.xml"/>
    <ElementManifest Location="Fields.xml"/>
    <ElementManifest Location="SiderysVirtualEarthMapContentType.xml"/>
    <ElementFile Location="Siderys.Blog.VirtualEarth.UI.WebPart.webpart" />
  </ElementManifests>
</Feature>


In image 4 we can see the feature activated in Sharepoint.



[Image 4]

clip_image006



To install the solution we need to create a WSP package to install all in Sharepoint. To do this, we go to the WSP project in Visual Studio and in the contextual menu option we select “build WSP”. In section 10 we can see the code to create a .bat file.



[Section 10]



stsadm -o addsolution -filename Siderys.Blog.VirtualEarth.WSP.wsp

echo *


echo * Activando la solucion Siderys.Blog.VirtualEarth.WSP.wsp


echo *


stsadm -o deploysolution -name Siderys.Blog.VirtualEarth.WSP.wsp -immediate –allowGacDeployment


stsadm -o execadmsvcjobs


iisreset



In my SkyDrive you can find the complete source code. Remember, to open the solution we need to have Visual Studio 2008 and WSPBuilder installed.



clip_image007


Descargar Solución Completa con Instalador



Fabián Imaz

8 comments:

Tom said...

Thanks for posting the source code and the great description. Have you thought about putting this on CodePlex?

Fabián Imaz said...

Tom

Thanks for your comment. No, I haven't. I will research how i can put my developments in codeplex. If you review my skydrive thre are a lof of development (source code) there.

Tks,

Charlotte said...

Nice to see a new innovative way to use Web Parts in SharePoint.

Fabián Imaz said...

Thank you Charlotte for your comments.

Anonymous said...

thanks a lot for sharing your webpart.
I can not use it in my site. please help me to how to create the list & content type . and how to configure this webpart on my page?

Fabián Imaz said...

Hello,

After installed WSP and activated the feature you have a lint named "Locations" where you need add the points that you want to show in the map.

Fabían

Jasper Oosterveld said...

Hi, is this also possible with the sandbox solutions of SharePoint 2010 Online?

Fabián Imaz said...

Jasper,

I think that you can use in Office online. But remember, this webpart was made for install in SharePoint 2007 not SharePoint 2010.