How to Integrate Virtual Earth Maps with a SharePoint List


Greg Hi everyone,


My name is Greg Chan and I’m a Program Manager in the SharePoint Designer team. I’ve also been involved in the development and testing of the Application Templates for Windows SharePoint Services 3.0. Just a couple weeks ago, I attended Tech Ed in Orlando and presented a breakout session called “Designing and Building Sophisticated Composite Applications with Microsoft Office SharePoint Designer 2007”.

Today, I’ll show you how to integrate the Virtual Earth Map control with your SharePoint list. This is actually part of the demo I gave in Tech Ed, and it has generated a lot of interest. Many of you have requested more information on this, so as promised, I’m dedicating this post to it. Some of you may be wondering… “Isn’t this the same as the Plotting Your Data Using Virtual Earth blog that Jon Campbell posted awhile back?” While there are overlaps, the key difference is that this post will talk about plotting a single address as opposed to multiple addresses.  A big benefit for doing single address is that Virtual Earth is good at plotting a single address without the need for longitudes and latitudes.  We simply need to pass in the address value and take advantage of functions provided by Virtual Earth to geocode it. (I don’t know about you, but when I search for driving directions, I’m not typing in longs and lats…)

Let’s get started!

Here’s the scenario — you own a bike shop and use a SharePoint site to manage the manufacturing process for building bicycles. In your site, you have a Suppliers list that stores information about each of your supplier like phone number, address, e-mail, etc. The list is based off the Contacts list. You want to insert a map control inside the display form for each supplier to show the location of the supplier.

Step 1 – Modifying the Display Form

Open in SharePoint Designer the display form (DispForm.aspx) of the SharePoint list containing the address information. Then, we want to use the data view to generate the map. (Yet another reason why we call data view the swiss army knife of web parts…) Below are the detailed steps to do this:


  1. In SharePoint Designer, open up DispForm.aspx under the Suppliers folder.
  2. Bring up the Data Source Library task pane.
  3. Select the Suppliers list and drag it onto the design surface, below the default list form controls.
  4. Bring up the Common Data View Tasks menu for the data view.
  5. Pick the Filter option.
  6. In the Filter Criteria dialog:

    1. Field Name = ID
    2. Comparison = Equals
    3. Value = Create a new parameter

  7. In the Data View Parameters dialog:

    1. Name your parameter (i.e. SupplierID)
    2. Parameter Source = Query String
    3. Query String Variable = ID
    4. Default Value = 36 (optional, I prefer to enter a # that maps to an item that I know already exists in my list)

  8. Hit OK and OK.

Note – All standard SharePoint forms contain an ID parameter in the query section of the URL:



http://<site_name>/Lists/Suppliers/DispForm.aspx?ID=36


Each item in a SharePoint list is mapped to a unique ID value. This ID value is what we’re using to filter the data view.


As a result, we’ve just inserted a data view of the suppliers list that is filtered down to show ONLY the current supplier and not all other suppliers. Right now, the data view is still rendered as a table by the default XSLT. Next step, we’re going to write custom XSLT and JavaScript to format the data view as a map!

Step 2 – Use custom XSLT + JavaScript to create Virtual Earth Map control

In order to create the Virtual Earth Map control, we’ll need to utilize some JavaScript functions provided by the Virtual Earth SDK. Below are JavaScript snippets that we need.

Load the map




var map;


 


// Loads the Virtual Earth map control


function loadMyMap() {


            map = new VEMap(&&apos;myMap&apos;);


            map.LoadMap();


            map.FindLocation &apos;<xsl:value-of select=@WorkAddress />,     <xsl:value-of select=@WorkCity />, <xsl:value-of select=@WorkState />,  <xsl:value-of select=@WorkZip />&apos;, displayPushPinCallBack);


}


FindLocation() will take the address values passed in and center the map to that location. This is a great function! For the function parameters, we’re passing in the XSL values of the Address, City, State and Zip Code field of the supplier.

Add the pushpin



function displayPushPinCallBack() {


      var pin = new VEPushpin(


          1,


          map.GetCenter(),


          null,


          &quot;<xsl:value-of select=@Title />&quot;,


          &apos;&apos;


          );


       map.AddPushpin(pin);


}


GetCenter() will return the longitude and latitude values of the center of the map, which is currently the location of the address you passed in from FindLocation(). We’re also passing in the XSL value of the Title field of the supplier.

The entire XSL stylesheet

Here’s the entire XSL that we will use to format the data view into a Virtual Earth Map control.



<?xml version=1.0 encoding=utf-8 ?>


<xsl:stylesheet version=1.0 xmlns:xsl=http://www.w3.org/1999/XSL/Transform>


  <xsl:output method=html indent=no/>


  <xsl:template match=/>


    <xsl:call-template name=dvt_1/>


  </xsl:template>


  <xsl:template name=dvt_1>


    <xsl:variable name=Rows select=/dsQueryResponse/Rows/Row />


    <xsl:call-template name=dvt_1.body>


      <xsl:with-param name=Rows select=$Rows />


    </xsl:call-template>


  </xsl:template>


  <xsl:template name=dvt_1.body>


    <xsl:param name=Rows />


   


    <!– Link to the Virtual Earth Map control JS file –>


    <script src=http://dev.virtualearth.net/mapcontrol/v4/mapcontrol.js>


    </script>


    <xsl:for-each select=$Rows>


      <xsl:call-template name=dvt_1.rowview />


    </xsl:for-each>


  </xsl:template>


  <xsl:template name=dvt_1.rowview>


    <div id=myMap style=width:650px; height:400px;></div>


    <script type=text/javascript>


 


      _spBodyOnLoadFunctionNames.push(&quot; loadMyMap &quot;);


      var map;


      // Loads the Virtual Earth map control


      function loadMyMap() {


          map = new VEMap(&apos;myMap&apos;);


          map.LoadMap();


          map.FindLocation(&apos;<xsl:value-of select=@WorkAddress />,


<xsl:value-of select=@WorkCity />,


<xsl:value-of select=@WorkState />,


<xsl:value-of select=@WorkZip />&apos;, displayPushPinCallBack);


      }


      function displayPushPinCallBack() {


          var pin = new VEPushpin(


            1,


            map.GetCenter(),


            null,


            &quot;<xsl:value-of select=@Title />&quot;,


            &apos;&apos;


          );


          map.AddPushpin(pin);


      }


    </script>


  </xsl:template>


</xsl:stylesheet>



  • _spBodyOnLoadFunctionNames() adds a function to the onload event of the body element. This ensures that loadMyMap() is called whenever the display form is loaded. The Using Javascript to Manipulate a List Form Field blog has a more detailed description of this.
  • The actual XSL is pretty basic. We’re simply using XSL to generate the <div> container for the map control and also passing in XSL values for the JavaScript function calls.

Next thing you’ll want to do is take that entire XSL stylesheet and save it out as a separate XSL file. This will make things a lot cleaner and easier to manage. We’ll save this out into a file called LiveMaps.xsl, and store it in the folder for the Suppliers list, along with the DispForm.aspx.


Step 3 – Format the data view using LiveMaps.xsl


Now we want to use LiveMaps.xsl to render the data view.



  1. Go back to DispForm.aspx in SharePoint Designer.
  2. Right-click on the data view, which is a Data Form Web Part.
  3. Select Web Part Properties.
  4. Expand the Miscellaneous category.
  5. For XSL Link, click on the button to the right of the input field.
  6. Navigate to the LiveMaps.xsl file and select it.

All Done!


Back on the browser, when you go to the display form of any supplier, there’ll be a great map view that will show you the location of the supplier. You’ll be able to interact with the map, just like you would on http://local.live.com.


Thanks,


Greg


Comments (99)

  1. Matthew says:

    Thanks for your code but I am having problems getting the actual map to display.  The variables are coming through correctly but I am getting "// Link to the Virtual Earth Map control JS file" showing up on the page.  Is there something missing in the code?

  2. Ricky Spears says:

    Has anyone been able to get this to work as written? I’m trying it, but the map isn’t displaying. All the configuration went well, and when I view the source, the right parameters are loading into the JavaScript portions of the XSL. I’m just not seeing the map.

  3. Ricky Spears says:

    I figured out what I was doing wrong and I was able to get it to work. When I coiped the XSL code above, and pasted it into my editor, it kept line breaks between the parameters for map.FindLocation(). To make this work, you will need to make sure that the entire function, and its parameters are all on one line.

    Thanks for providing this, Greg!

  4. Steven Johnson says:

    Thanks for the clue on the coding Ricky.  That did the trick to get the map to show but now I get the map covering the entire page and not limited to the div.  Any thoughts?

  5. Joost says:

    ‘How can the code render the virtual eartch map"? Is it some javascript? Which will only render when connected to the internet?

    I tried get it to work on a vpc which isn’t connected to the internet..can that make any difference?

    regards Joost

  6. Siguiendo con la recopilación de recursos iniciada en un post previo , en la nueva entrega de recursos

  7. Ricky Spears says:

    Joost – You are correct. This just uses javaScript to dynamically pass information to the Live Maps server. The user viewing the page must have access to the Internet in order for the browser to make the call to the server.

    Steven – I don’t have any idea why yours is showing up that way. Sorry.

  8. Juan says:

    This is a great tip and saw it in action twice at TechEd. I just had a chance to try it myself and seems i have missing something. I am not getting the map but instead a message saying // Link to the Virtual Earth Map control JS file, I am wondering is someone got this error when trying this.

  9. Matthew says:

    Juan I am getting the same message after running the code.  If you remove the {generate-id()} form <div id=’myMap{generate-id()}’ style="width:650px; height:400px;"> (the {generate-id()} is added by Designer after you attach the xsl page) the map will work but the map shows up covering the entire page.  Ricky, did your work correctly after fixing the line breaks?

  10. Ricky Spears says:

    Juan – See my note in the comments above about making sure that all the parameters for the Map.FindLocation() function are all one one line. This will cause the map to display. To get rid of the

    // Link to the Virtual Earth Map control JS file

    simply delete that line from your XSLT. It’s just a comment that’s not needed.

  11. Greg says:

    Hi guys,

    Regarding the XSL not working and an error with "//", I made a mistake in one of the comments in the XSL and that’s why you’re seeing this issue.  My bad.  

    I’ve updated the blog to show the proper XSL code.  Basically, this line

    "// Link to the Virtual Earth Map control JS file"

    should be replaced by this:

    <!– Link to the Virtual Earth Map control JS file –>

    This should work now.  

    Greg

  12. Jon Campbell says:

    Steven – Though it shouldn’t be necessary anymore, I previously had to set the "overflow:hidden" css attribute in the style for the myMap div. Try that and see if it gets you going.

  13. Ricky Spears says:

    Matthew – The only two changes I made were to remove the comment line and the line breaks between the parametrs in the Map.FindLocatin() function. It ran fine after that. Good luck!

  14. Ian Morrish says:

    Here is another take on displaying the map in a Web Part page using a connection from a list of addresses

    http://www.wssdemo.com/demo/default.aspx

  15. Buchtipps Microsoft Office SharePoint Server 2007 – Das Handbuch von Bill English Beginning SharePoint

  16. Direkter Download: SPPD-074-2007-07-12 [00:00] Intro [00:00] Buchtipps Microsoft Office SharePoint Server

  17. Direkter Download: SPPD-074-2007-07-12 [00:00] Intro [00:00] Buchtipps Microsoft Office SharePoint Server

  18. Shankar says:

    Hi,

    This is awesome stuff. I am getting it to work for US locations, however I can’t seem to figure out what’s going on with the Canadian locations. Any help would be appreciated.

    Thanks.

  19. Jon Campbell says:

    Shankar: The key line you want to look at is map.FindLocation(&apos;<xsl:value-of select="@WorkAddress" />,

    <xsl:value-of select="@WorkCity" />,

    <xsl:value-of select="@WorkState" />,

    <xsl:value-of select="@WorkZip" />&apos;, displayPushPinCallBack);

    That line dictates what the map works against to find addresses. You will need to probably add another field, such as @WorkCountry, to further state where the address points to.

  20. Shankar says:

    Thanks Jon, that did the trick.

  21. Shankar says:

    Hi Jon,

    Couple of questions, can this tool work with the new version of VE? I tried changing the JS code to map to the new version, however I got a javascript error and no map was displayed. I would like to use features like “Getting driving directions”, etc.

    The pushpin works fine, however the title/label is displayed not accurately. The title/label box is couple of inches below/above the point where the mouse is hovering (over the pin).

    Thanks

    Shankar.

  22. Jason W. says:

    Thanks Greg!!! Got it working and my peers and co-workers love it. It makes me look like a genius!!

  23. Chad E says:

    Thank you very much for this post.  We are actually Feeding the data view with BDC fields from our office locations database.  Great feature for our corporate intranet.  Thanks again.

  24. Andyoye says:

    I am not able to get this working. I get "this web part doesnt have a valid XSLT style sheet…". Any ideas? Thanks

  25. Andyoye says:

    I removed the line breaks from the map.Findlocation(). Now it tries to read from maps.live.com but I am not seeing any map still.

  26. Shah says:

    it’s broken….  :(

  27. Chad E says:

    Is there a function that will allow the user to get driving directions in the map control on the SharePoint list?

  28. Simon says:

    Anyone can tell me how i can add more than one pin (meaning more records) into the map under sharepoint? Thanks.

  29. Nick recently blogged about a new web part available for users of his BDC Meta Man tool that allows users

  30. dustin says:

    Nick recently blogged about a new web part available for users of his BDC Meta Man tool that allows users

  31. Victor Shamanovsky says:

    Works great.

  32. Doug says:

    Very Cool… Thanks

  33. Microsoft’s Virtual Earth technology powers the maps on Live Search and many other web-based applications,

  34. Ryan says:

    Nice sample and walkthrough.  I would like to build this into a contact list and then save the list as a template, so all new contact lists on the site have the functionality available.  However, the map data view has the original List ID hardcoded from designer.  How can I make the List ID a parameter (similar to the record ID) so it can be changed dynamically and context sensitive to the calling list?  The List ID is not located int he URL, so can it be bound from a different location?

  35. Ryan says:

    Just found the answer to my previous question, so I thought I would share.  When the data view is created, the List ID is bound to a hardcoded default value.  Simply modify the parameter binding so the correct List ID is acquired from CAML.  This appears to work OK in the limited testing I have performed thus far…

    From

    <ParameterBinding Name="ListID" Location="None" DefaultValue="…"/>

    To

    <ParameterBinding Name="ListID" Location="CAMLVariable" DefaultValue="CurrentListID"/>

  36. Brian says:

    I’m still doing something wrong. I don’t have much experience with SharePoint designer but this demo looked pretty easy. I’m still getting "Unable to display this webpart."

    Maybe I did something wrong when I added the data view

  37. Jon Campbell says:

    Simon: check out http://blogs.msdn.com/sharepointdesigner/archive/2007/05/23/plotting-your-data-using-virtual-earth.aspx?CommentPosted=true#commentmessage

    Chad E/Shankar: I just answered the driving directions question in the comments of the above post – i that should get you going.

    This code should still work just fine, but I will verify. There have been a few changes between v4 and v6 (the current release of VE as of today) – check out http://dev.live.com/virtualearth/sdk/ for more info. They have a link that indicates what is new.

  38. Shankar says:

    Thanks Jon- that worked !!

  39. Daniel says:

    Works great, pretty easy.

    If I’m not using a contact list, but a custom list I just need to change the variables names in the map,FIndLocation() right?

    The page is showing a VE error for the address, including "<div>" in the address, any help here?

    THe name of the pinpoint is defined by what variable in the code?

  40. Daniel says:

    Any tip on how to display all pinpoints from the list?

  41. Jon Campbell says:

    Daniel: for plotting multiple points, check out http://blogs.msdn.com/sharepointdesigner/archive/2007/05/23/plotting-your-data-using-virtual-earth.aspx#comments. I am in the process of putting something together that is new and improved for all those people wanting batch geocoding, so stay tuned.

    As for your question about the pushpin –

    function displayPushPinCallBack() {

             var pin = new VEPushpin(

               1, // this is the ID of the pushpin. you can use it modify the pushpin via javascript later if you want to, but for most people this is just something you have to set. When you are displaying multiple pins you should be sure that this is unique.

               map.GetCenter(), // this is where you want the pushpin. since findlocation sets the center of the map over your address, you can use GetCenter() to grab the coordinates.

               null, // the custom icon for your pushpin (i think). note that this has changed in the current SDK

               &quot;<xsl:value-of select="@Title" />&quot;, // this is the title/name of your pushpin. you can put whatever you want here

               &apos;&apos; // this is the description of your pushpin. you can put whatever you want here – images, text, links, tables, etc. I have even hosted an iframe here with a little effort.

             );

             map.AddPushpin(pin);

         }

    If you want to change the title or description as shown in the popup, just dump in the appropriate fields or text into the spaces i mention above and you should be good to go.

  42. Simon says:

    I get the message ‘unable to display this webpart’

    I have a custom list with a location, address, postal code etc..

    I have tried to use v4 and now v6 with the following :

    map.Find(null,'<xsl:value-of select="@WorkZip">’);

    I loaded the stylesheet into the same directory vis SPD.

    The step 3.5 does not show me a button on the right hand side of the box but when I type the file name in it shows in the XSL.

    New to MOSS how would I debug this to see what is being loaded and when?

    Thanks

  43. simon_uk71 says:

    I resolved the issue I had and posted on the 20th. I changed the script to v6, removed the pushpin and added layers.

  44. Tom Cantrell says:

    I’m struggling getting this to display. I am just getting a blank area at the bottom of the page.

    When I check the code rendered to the page I see and error below the line

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

    var 1456bt="Invalid invoke target specifed.",1709ct="Invalid argument passed; both start and end must be preset .  . . .

    But I do see the correct address parameters passed in the script below.

    Any ideas?

  45. Gregory says:

    Any chance you can upgrade this code for V6??  I am attempting … can load the map but still working on the pushpins.   Thanks!

  46. Direkter Download: SPPD-074-2007-07-12 [00:00] Intro [00:00] Buchtipps Microsoft Office SharePoint Server

  47. Dean says:

    I can’t get this to work with V 6 either. some tips would be greatly appreciated.

    Dean

  48. Trinh says:

    I got it to work with V6 — make sure that your id=’myMap’ is not changed to {generatedID}.

    But, when I mouseover my pin the popup is not displayed next to the pin. The popup for the title and description is displayed outside of my VE map.

    Any ideas?

    Thanks

  49. Anthony says:

    I’ve been needing something like this for some time now.  Greg and everyone else here, great work!  I’ll throw you a bone if needed as I had to play with the SDK to get mine to work the way I wanted.  I had to create one menu for my users so that they wouldn’t attempt to install VE 3D as it’s not needed.  Ryan had some good ideas for making this reuseable as it’s nice to have a template without having to tweak the code all the time.

    FULL MENU VE v.6

    _______________________________________________________________________________

    <?xml version="1.0" encoding="utf-8" ?>

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform&quot; xmlns:ddwrt2="urn:frontpage:internal">

     <xsl:output method="html" indent="no"/>

      <xsl:template match="/" xmlns:ddwrt="http://schemas.microsoft.com/WebParts/v2/DataView/runtime"&gt;

        <xsl:call-template name="dvt_1"/>

     </xsl:template>

      <xsl:template name="dvt_1">

        <xsl:variable name="Rows" select="/dsQueryResponse/Rows/Row" />

        <xsl:call-template name="dvt_1.body">

          <xsl:with-param name="Rows" select="$Rows" />

        </xsl:call-template>

     </xsl:template>

      <xsl:template name="dvt_1.body">

        <xsl:param name="Rows" />

       <!– Link to the Virtual Earth Map control JS file –>

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

        <xsl:for-each select="$Rows">

          <xsl:call-template name="dvt_1.rowview" />

       </xsl:for-each>

     </xsl:template>

      <xsl:template name="dvt_1.rowview">

       <div id=’myMap’ style="position:absolute; width:635px; height:220px;"></div>

       <script id="myMap" style="position:absolute; width:635px; height:220px;">

         _spBodyOnLoadFunctionNames.push("GetMap");

         var map = null;

         // Loads the Virtual Earth map control

         function GetMap() {

             map = new VEMap(‘myMap’);

             map.LoadMap();

             map.Find(null,'<xsl:value-of select="@WorkAddress" />,<xsl:value-of select="@WorkCity" />,<xsl:value-of select="@WorkState" />,<xsl:value-of select="@WorkZip" />’, null, null, null, null, null, null, null, null, callback);

         }

         function callback() {

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

             pin.SetCustomIcon();

             pin.SetTitle("<xsl:value-of select="@Company" />");

             pin.SetDescription("<xsl:value-of select="@WorkCity" />, <xsl:value-of select="@WorkState" />");

             map.AddShape(pin);

         }

       </script>

     </xsl:template>

    </xsl:stylesheet>

    SMALL MENU VE v.6

    _______________________________________________________________________________

    <?xml version="1.0" encoding="utf-8" ?>

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform&quot; xmlns:ddwrt2="urn:frontpage:internal">

     <xsl:output method="html" indent="no"/>

      <xsl:template match="/" xmlns:ddwrt="http://schemas.microsoft.com/WebParts/v2/DataView/runtime"&gt;

        <xsl:call-template name="dvt_1"/>

     </xsl:template>

      <xsl:template name="dvt_1">

        <xsl:variable name="Rows" select="/dsQueryResponse/Rows/Row" />

        <xsl:call-template name="dvt_1.body">

          <xsl:with-param name="Rows" select="$Rows" />

        </xsl:call-template>

     </xsl:template>

      <xsl:template name="dvt_1.body">

        <xsl:param name="Rows" />

       <!– Link to the Virtual Earth Map control JS file –>

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

        <xsl:for-each select="$Rows">

          <xsl:call-template name="dvt_1.rowview" />

       </xsl:for-each>

     </xsl:template>

      <xsl:template name="dvt_1.rowview">

       <div id=’myMap’ style="position:absolute; width:635px; height:220px;"></div>

       <script id="myMap" style="position:absolute; width:635px; height:220px;">

         _spBodyOnLoadFunctionNames.push("LoadSmall");

         var map = null;

    // Loads the Virtual Earth map control with the Small Toolbar

         function LoadSmall() {

             if (map!=null) {

             map.Dispose();

         }

             map = new VEMap(‘myMap’);

             map.SetDashboardSize(VEDashboardSize.Small);

             map.LoadMap();

             map.Find(null,'<xsl:value-of select="@WorkAddress" />,<xsl:value-of select="@WorkCity" />,<xsl:value-of select="@WorkState" />,<xsl:value-of select="@WorkZip" />’, null, null, null, null, null, null, null, null, callback);

         }

         function callback() {

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

             pin.SetCustomIcon();

             pin.SetTitle("<xsl:value-of select="@Company" />");

             pin.SetDescription("<xsl:value-of select="@WorkCity" />, <xsl:value-of select="@WorkState" />");

             map.AddShape(pin);

         }

       </script>

     </xsl:template>

    </xsl:stylesheet>

    _______________________________________________________________________________

    Hope this helps out those in need.

  50. Anthony says:

    I have one task I’d love to take on and I’m not certain how to harvest the information and return the results onto a VE map using WSS data.  I re-wrote the xsl above for v6 and it’s doing what I want for one data record.  What I want to do is take a small list of several projects which include address data and plot them on a VE map but the above code only works with one record.  Is there a way to pin multiple entries on a single map using WSS data?

    Please let me know awclayton77@msn.com

    Thanks in advance!

  51. Jon Campbell says:

    Anthony – That question comes up a lot. The basic gist is to use something similar to http://blogs.msdn.com/sharepointdesigner/archive/2007/05/23/plotting-your-data-using-virtual-earth.aspx#comments combined with elements of this post as well. My suggestion would be to use the following formula:

    0) start with your map hidden, perhaps with a loading image or something

    1) Use a DFWP to generate an array of javascript structures, one for each address

    2) call findlocation for the first address, specifying a callback that stores the lat/lon

    3) in the callback, if there are more points to plot then call findlocation on the next point

    4) if no more points are left, then plot them all

    Its not ideal, but it does work. The best solution would be to use some custom code to agressively cache the geocoded points and re-use that data when possible, but the above process should work for those without the ability to deploy custom code.

  52. Nitu says:

    I need immediate help in getting this working. I get "this web part doesnt have a valid XSLT style sheet getting Live SSL from Server". Any help is highly appreciated. Thanks in advance.

  53. Anthony says:

    I was able to plot multiple lists directly from a SP List vs. XML list using Jon Campbell’s help at http://blogs.msdn.com/sharepointdesigner/archive/2007/05/23/plotting-your-data-using-virtual-earth.aspx

    Essentially I built the page as he states but substituted the XML data source with a data source library list from my SP site and it worked.

    Thanks again to all.

  54. Hi folks. This is Greg Chan, Program Manager in the SharePoint Designer team. For those of you who attended

  55. Dave says:

    Mine is blowing out the div and going full screen… Anyone have this issue and resolve it?

  56. Jon Campbell says:

    Dave: A common reason for the map to go full sceen is when the "overflow:hidden" is not set. Try setting that on your map’s div – it may solve the issue.

  57. Michael Doherty says:

    I would like to know if there is a way to intergrate your outlook contact list to the Virtual Earth so when you update the contact list it updates the collection on Virtual Earth. Anyone have any ideas on how this is done?

  58. shivamoss says:

    HI all

    ..

    i need help i am working on the look and feel of the page .

    what i have done is i have copied a default theme(verdant)and made changes to the

    Cust1011-65001.css and replace the content of "C:Program FilesCommon FilesMicrosoft Sharedweb server extensions12TEMPLATETHEMESCustomBrowntheme.css

    the changes are seen when the changes are made but when i replace the content of "C:Program FilesCommon FilesMicrosoft Sharedweb server extensions12TEMPLATETHEMESCustomBrowntheme.css

    and when perform the application pool recycle of that web application and when i opened the Cust1011-65001.css file the number of lines of code got increased by itself and copy of ms-pagetitle was seen  with the default  url of the image even after mnaking the changes again and again

    please help

    shiva…..

  59. I have been using the Virtual Earth control a lot lately for various demos, mostly by putting customized

  60. Jon Campbell says:

    Michael – What you are describing is basically what is presented in the other mapping post on this blog – http://blogs.msdn.com/sharepointdesigner/archive/2007/05/23/plotting-your-data-using-virtual-earth.aspx. You would need to have your contacts list sync’d up with a sharepoint contacts list, and then plot that sharepoint list. Since you will need geocoding, check my response to anthony’s question on how to get that done for a list.

  61. Nakul Bhagat says:

    Hey Guys,

    I guess some of you guys have problem loading the map even following everythiong in the blog. It seems that the _spBodyOnLoadFunctionNames.push(&quot; loadMyMap &quot;); doesn’t work at times. So I replaced that code with "function addLoadEvent(func)

         {

               var oldonload = window.onload;

               if (typeof window.onload != &apos;function&apos;)

               { window.onload = func; }

               else

               { window.onload = function()

                     { oldonload(); func(); }

    }

          }

             addLoadEvent(loadMyMap);

    "

    And this worked for me. Hope this helps.

    Thanks

    Nakul

  62. Jon Campbell says:

    Nakul – the most common reason why _spBodyOnLoadFunctionNames won’t work is if you are on a page that doesn’t use the default.master that ships with wss/moss out of the box. As you noted, the above code serves a similar function and will work on pages with or without the _spBodyOnLoadFunctionNames stuff.

  63. Nakul Bhagat says:

    Jon,

    Thanks for pointing out the reason why _spBodyOnLoadFunctionNames doest work. I observed one more thing if I use this code and browse it using Safari, I don’t see the map at all. I am not able to figure out what seems to be the reason.

  64. Ram says:

    Great job

    but my job is slightly different that i have to show the offices of a company that r in my share point list.

    like if i have to show of the US offices of the company,then i have to  show the address in map of that particular office.

    plz help me

    Regards

    Ram

  65. Jon Campbell says:

    Ram – This post should get you most of the way to what you want. If I understand you correctly, you are wanting to have the address shown with the pushpin in the popup that comes up? If so, then you want to modify the VEPushPin javascript call. The last two arguments are the title and description, respectively, which are displayed in the popup that is shown when you hover over the pushpin for the location. The code above sets the title to be the Title field (which is really the last name) and the description to be blank. You just need to change those last two arguments to reflect your desired behavior

  66. Jan says:

    Hi,

    thats really cool and exactly what I need for a showcase. I got this to work straight a way. But know I’m trying ot re-build this for the second time and it doesn’t work.

    Does someone have any idea what might be wrong? I think I haven’t changed anything.

    Regards

    Jan

  67. Jon Campbell says:

    Jan – I would suggest taking this code and translating it to the lates version (6.1 as of today) of the sdk (http://dev.live.com/virtualearth/sdk/). That might work better for you, and it should be a pretty straight forward task.

  68. Dave Bednarski says:

    Almost there- it seems great so far!

    Im getting an error when opening the display page.  A map loads but it is only a map of the US, not a specific address.  Here is what the error says:

    The server is temporarily unavailable.  Try again late.

    Is this really a temporary error?

  69. Dave Bednarski says:

    Solved my problem.

    I had changed the xpaths thinking that it was causing a previous error.  For example I made @WorkAddress just @Address  and etc..

  70. Hi Jon says:

    Hello Jon

    rather than using the xml as a data source for the grid view,i have to use SQL as a data source

    Is this possible?

    Please help me

    Ram Sharma

  71. Jon Campbell says:

    Ram – You can use any of the datasources that are supported by the DataFormWebPart, which means most ASP.Net DatasSourceControls. If you are using a SQL datasource then you will want create a DataView of your SQL data source, then adapt the above xsl to meet your needs. The main thing you will need to change are the <xsl:value-of /> calls to make sure that they refer to the appropriate fields in your sql datasource. There are a couple ways to do this, but an easy way is to insert a table view of your data, then look at the xsl in order to find the columns you want.

  72. Ram says:

    Hi Jon

    Thanks  for your reply, i have created data view of my SQL data source by following these steps:

    1. Created a data table in SQL having columns name lat,long,name and description

    2 Create a aspx page SP designer and write down the functions like GetMap,AddPin etc

    3 open data source library from the task pane and expand Data Source Connections and connect to my data base that SQL data base.

    4 and then right click the data source that appear in data source library,click on show data and it shows me the data’

    But as you kindly said in your reply"then adapt the above xsl to meet your needs" and "The main thing you will need to change are the <xsl:value-of /> calls to make sure that they refer to the appropriate fields in your sql datasource."i am getting these  point

    Please guide me

    Regards

    Ram Sharma

  73. John Mcclain says:

    First off, Great Post!! I actually took this code and hooked it into a BDC connection.

    Now for my issue.  I am getting an popup each time this page is loaded saying that “This page contains both secure and nonsecure items".  I thought I could fix this by changing the "Mixed Mode" setting in IE but it did not fix it.  Any thoughts on what I can do to prevent this popup?

  74. Jon Campbell says:

    John – This blog post should help fix your problem – it sounds like you are using https/ssl or whatnot. You basically need to use an ssl path to get to the map javascript. try changing http://dev.virtualearth.net/mapcontrol/v4/mapcontrol.js to be https://dev.virtualearth.net/mapcontrol/v4/mapcontrol.js. However, you should probably update the code to use the v6 api since VE seems to be retiring some of their older versions.

    http://weblogs.asp.net/davidbarkol/archive/2007/11/23/ssl-support-for-virtual-earth-is-here.aspx

  75. SharePoint Designer 2007 Getting to know the Data Form Web Part (1 of 4) SharePoint Designer 2007 Handbuch

  76. LISpeedyG says:

    Hi All,

    Gregg, Great post..

    I have implemented this in a contact management application.  In that application I have the prospects identified by several key parameters.  These parameters are then used to group the prospect detail records.

    At the present time, the VE control adds pins to the entire list as defined by the number of total prospects returned by a given view.  Now, each prospect view contains collapsed groups, based on the key parameters mentioned above.

    I have two additional actions I need the mapping to include, and wonder if anyone here can point me to the appropriate pace to research:

     1.  I would like to have the VE control map only the expanded group details.

     2.  I would like to vary the color/type/size of pin used based on key values contained in each contact details.

    Again, any help/direction for research would be a ppreciated.

    Thank You.

  77. SharePoint Designer 2007 Getting to know the Data Form Web Part (1 of 4) SharePoint Designer 2007 Handbuch

  78. Jon Campbell says:

    LISpeedyG – What you are describing for #2 is essentially conditional formatting. You will need to modify the XSL mentioned in the article to make it happen, but it can be tricky.

         function displayPushPinCallBack() {

             var pin = new VEPushpin(

               1,

               map.GetCenter(),

               null,   <————- this argument controls the icon

               &quot;<xsl:value-of select="@Title" />&quot;,

               &apos;&apos;

             );

    Basically you would use either xsl:if statements or an xsl:choose block to pick which pin icon you want based on your requirements. For example, lets say you have 3 icons: 1.png, 2.png, and 3.png. The code might look like this:

         function displayPushPinCallBack() {

             var pin = new VEPushpin(

               1,

               map.GetCenter(),

               <xsl:choose>

                 <xsl:when test="@Rating=1">&quot;http://mysite/images/1.gif&quot;</xsl:when&gt;

                 <xsl:when test="@Rating=2">&quot;http://mysite/images/2.gif&quot;</xsl:when&gt;

                 <xsl:when test="@Rating=3">&quot;http://mysite/images/3.gif&quot;</xsl:when&gt;

               </xsl:choose>,

               &quot;<xsl:value-of select="@Title" />&quot;,

               &apos;&apos;

             );

    I’m not sure I follow your first question, but if you are wanting to modify what is shown in the popup dialog, then its the same process:

         function displayPushPinCallBack() {

             var pin = new VEPushpin(

               1,

               map.GetCenter(),

               null,   <————- this argument controls the icon

               &quot;<xsl:value-of select="@Title" />&quot;, <—– this argument controls the title

               &apos;&apos; <————— this argument controls the description

             );

  79. Anyone got this working on Firefox?

  80. Actually using position:absolute in the style attribute, makes the map display correctly in FF

     <div id=’myMap’ style="position:absolute; width:635px; height:220px;"></div>

      <script id="myMap" style="position:absolute; width:635px; height:220px;">

  81. Chris Ellis says:

    I implemented this and it was all working fine until a couple of weeks ago.  Has there been a change to the map control API that I need to account for in the xsl code?

  82. Chad E says:

    Hi, could someone possibly update the code to use the new version of the script (http://dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=6.1)?  The code above, as is, does not work.  The web part is blank.  if I change the script to the above mentioned, I get errors and sometimes i get the map of U.S. but no address plotted on it.  Any help would be greatly appreciated.

    Thanks

  83. LISpeedyG says:

    John,

    Thanks so much for the tip.  I have, just today due to heavy workload, been able to use your guidance in replacing the standard pushpin with custom ones based on one of the list values.  BTW– would it be difficult to add a legend using the new pushpins with their respective identifiers to the map?

    With regard to my first question, sorry for the incomprehensible question.  I will try and be more explicit:

    My current list is displayed with using a grouping criteria selectable using a drop down list.  So, initially the a maximum of 100 items is displayed but are all initially viewed in a collapsed format.  So, I may see NY–80, NJ–20, etc.. if they are grouped by States.  The problem, is that the current code steps through all the rows (all 100 in this case) and maps them all onto VE.  I, instead, would like to initially show a blank map (all groups collapsed) and once the group(s) are expanded, to map only the rows viewable once expanded.

    Hopefully I have clarified the original question and you, or someone else can give me some guidance on this.

    Thanks Again for your help.

  84. MadhurChadha says:

    The blog mentioned here basically talks of integrating Virtual earth maps with a contact list.

    The display form of the list is modified to show the map.

    But i beleive this method will create deployment issues ,we obviously cannot ask a client to do such configurations.Can we export these configurations in any way??

    Instead what we did recently we created a custom webpart that accesed the location details like the dataview webpart and passed them to virtual earth

    Now we created a custom list definition and in its dispform.aspx we added this webpart…

    The biggest advantage was that any in no of instances of the list could be created and will require no configuration at all…

    If there any other workaround…do suggest

  85. Randy says:

    I have just started working with this and am having some issues.  I read through all the comments and didn’t see anything that seems to help.  I updated to the latest link http://dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=6.2.  Everything for map.FindLocation is on the same line with no line breaks.  When I display the page all I get is "Unable to display this webpart….".  Any ideas what might be causing this?

  86. Mike says:

    This feature would be great in my site…if it worked. Can anybody find the missing semi-colon in the following line of code?

    <script type="text/javascript" src="https://dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=6&s=1"></script&gt;

    …SharePoint complains and won’t display the map…I tried putting a semi-colon in all the obvious, possible places and nothing works. (note: I am using the v6 & https version of the code)

    Is anybody else getting  "A semi colon character was expected…" error? Can anybody solve the mystery?

  87. Mike says:

    After much troubleshooting with many aspects of this post and code, I found that my map was not displaying because the div tag had mysteriously disappeared from LiveMaps.xsl. I don’t know how this happened, but I added back the following line and it worked…

    <div id=’myMap’ style="position:absolute; width:635px; height:220px;"></div>

    I eventually gave the div tag more height, increasing the value to 620px, so that I could see a good sized map, but the map will run over the footer…but it works, so I’m happy.

  88. Un año más ( ¡FELIZ AÑO NUEVO A TODOS! ), aquí estoy dando guerra (y ya van más de dos desde que Rodrigo

  89. Mike Ferguson says:

    Referring to Greg’s original xsl listing above (many thanks by the way), if you change what I’ve outlined below, it seems to be working now.

    Change from this:

       <script src="http://dev.virtualearth.net/mapcontrol/v4/mapcontrol.js"&gt;

       </script>

    To This:

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

    </script>

    Also, change this:

       map.FindLocation(&apos;<xsl:value-of select="@WorkAddress" />,<xsl:value-of select="@WorkCity" />,<xsl:value-of select="@WorkState" />,<xsl:value-of select="@WorkZip" />&apos;, displayPushPinCallBack);

    To This:

       map.Find(null,&quot;<xsl:value-of select="@WorkAddress" />,<xsl:value-of select="@WorkCity" />,<xsl:value-of select="@WorkState" />,<xsl:value-of select="@WorkZip" />&quot;,null,null,null,null,null,null,null,null, displayPushPinCallBack)

    Also, change this function:

         function displayPushPinCallBack() {

             var pin = new VEPushpin(1,map.GetCenter(),null,&quot;<xsl:value-of select="@Title" />&quot;,&apos;&apos;);

             map.AddPushpin(pin);

         }

    To This:

         function displayPushPinCallBack() {

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

             map.AddShape(shape);

         }

    I found these resources to be especially helpful:

    MSDN

    http://msdn.microsoft.com/en-us/library/cc879134.aspx

    and the Virtual Earth interactive SDK

    http://dev.live.com/Virtualearth/sdk/#

    Cheers

    Mike

  90. Tim Pohlad says:

    Please Help

    I’ve gone through this 3 times.

    when i attach the xsl file, everything loads but no map appears.

    I know its working correctly because my sharepoint site is https:// and I’m using another VE map elsewhere that prompts me with the same message "this page contains secure and unsecure……"

    everything is in the correct spots – if i remove the xsl link i get the dataview where the map should be poping up – I’m lost?

    PS – I updated the code to VE 6 – but either way 4 or 6 the same thing happens even after I’ve gone thorugh every suggestion (including the fact my default.master is customized – tried that fix also!!!)

  91. Uzma says:

    Great post! Thanks to all who have contributed to a valuable resource.

    http://sharepointuzma.wordpress.com/

  92. Tom Resing says:

    I’ve created an updated XSL file you can use with the Virtual Earth 6.2 API. You can grab it off my new blog post:

    http://blogs.microlinkllc.com/tresing/archive/2009/04/02/virtual-earth-6-2-in-sharepoint.aspx

    -Tom

  93. Hi guys,

    I am trying to use the following XSL for transform the coreresults web part in MOSS. I add metadata property mappings for lat and long in central admin then use the follwoing XSLT: However I get a blank DIV with no results any ideas:

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform&quot; >

    <xsl:output  method="html"/>

       <!– This template is called for each result –>

       <xsl:template match="Result">

           <xsl:text>AddShape(</xsl:text>

           <xsl:value-of select="lat"/>

           <xsl:text>,</xsl:text>

           <xsl:value-of select="lon"/>

           <xsl:text>,"</xsl:text>

           <xsl:value-of select="title"/>

           <xsl:text>");</xsl:text>

       </xsl:template>

       <!– XSL transformation starts here –>

       <xsl:template match="/">

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

           <xsl:text>

           </xsl:text>

                   <script type="text/javascript" language="JavaScript">

                       <![CDATA[

               var map = null;

               var shapes = new Array();

               function CreateMap()

               {

                   map = new VEMap(‘myMap’);

                   options = new VEMapOptions();

                   options.EnableBirdseye=false;

                   optionddShape(lat,lon,desc)s.EnableDashboardLabels=false;

                   map.SetDashboardSize(VEDashboardSize.Tiny);

                   map.LoadMap(new VELatLong(47.6, -122.33), 11 ,’h’ ,false,VEMapMode.Mode2d,false,0,options);

                   CreateArray();

                   var shapeLayer = new VEShapeLayer();

                   map.AddShapeLayer(shapeLayer);

                   shapeLayer.AddShape(shapes);

               }

              function AddShape(lat,lon,desc)

              {

                    var shape = new VEShape(VEShapeType.Pushpin, new VELatLong(lat, lon));

                    shape.SetDescription(desc);

                    shapes.push(shape);

                    //If you want to set a custom pushpin icon, use the next line

                    shape.SetCustomIcon(‘http://myimage.jpg‘);

              }

              _spBodyOnLoadFunctionNames.push("CreateMap");

               ]]>

                  <xsl:text>function CreateArray() {</xsl:text>

                   <xsl:apply-templates select="//Result"/>

                   <xsl:text>}</xsl:text>

    </script>

           <script type="text/javascript" src="http://dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=6.1"/&gt;

       </xsl:template>

       <!– End of Stylesheet –>

    </xsl:stylesheet>

    Thanks James

  94. MilkMan says:

    Did anyone get the Directions To, and the Directions From to work in the Pushpin.  I saw the code in an earlier post but I am to much of a newby to know where to put it.  Thanks for your help.

  95. David Lozzi says:

    Doesn’t the license for Microsoft’s maps restrict you from using their maps internally (behind a firewall, non-public) unless you pay a licensing fee? We looked into this for customers and that’s what MS came back to us with, and it was rather expensive!

  96. Direkter Download: SPPD-074-2007-07-12 [00:00] Intro [00:00] Buchtipps Microsoft Office SharePoint Server

  97. Macca30 says:

    I don’t understand this part of the process.

    Query String Variable = ID

    Default Value = 36 (optional, I prefer to enter a # that maps to an item that I know already exists in my list)

    When I add the above I loose all my records.  Can someone explain why this would happen?

  98. shadesinister says:

    SQL data source use dsQueryResponse/NewDataSet/Row instead of dsQueryResponse/Rows/Row