MapPoint Forums

MapForums

Community of VE/MapPoint Users and Developers




Virtual Earth as Gadget for Windows Vista Sidebar

This is a discussion on Virtual Earth as Gadget for Windows Vista Sidebar within the Virtual Earth Blogs forums, part of the Blogs category; Introduction If you are using Windows Vista you probably had a look at the Sidebar Gadgets as well. There is ...


Go Back   MapPoint Forums > Blogs > Virtual Earth Blogs

Register Blogs FAQ Members List Calendar Search Today's Posts Mark Forums Read
  5 links from elsewhere to this Post. Click to view. #1 (permalink)  
Old 04-02-2008
Member
Green Belt
 
Join Date: Sep 2007
Posts: 54
Virtual Earth as Gadget for Windows Vista Sidebar

Introduction

If you are using Windows Vista you probably had a look at the Sidebar Gadgets as well.

image

There is a already pretty big gallery available on the web but since the Gadgets are basically small HTML-documents automated through JavaScript everybody can build his own Gadgets as well. I like the idea of having some condensed information in one place and open a Flyout which get's you full functionality in a bigger window. Of course I was aware that there are already Gadgets which implement some of the Virtual Earth functions so I wanted to demonstrate how easy it can be to implement your own existing Virtual Earth applications in the Sidebar. As a starting point we use the tracking application which I described in a previous posting. The idea is to have a small Gadget as shown above in the Sidebar and then to create a Flyout in which I have advanced functionality like replaying previous days.

Getting Started

If you are new to the Vista Gadgets this might be a good starting point but don't worry it is pretty easy and the following steps will be explained in detail. As mentioned before, we will build upon the code for that simple tracking application which I have described here. In the meantime I had modified that sample so that we have a replay-function as well. You will find the source code here:

The Gadget

Particularly for development and testing it is a good idea to create a folder directly in your personal Gadget-folder (e.g. C:\Users\jkebeck\AppData\Local\Microsoft\Windows Sidebar\Gadgets) rather than in the standard repository for your Visual Studio project. The folder shall follow the naming convention "SomeName.gadget". In my case it is "MyTracking.gadget".

The Manifest (gadget.xml)

The first piece of the Gadget is the XML-Manifest which describes where everything is. The name of this file must always be gadget.xml. A detailed description of the manifest can be found here and my manifest looks like this:

xml version="1.0" encoding="utf-8" ?>
<
gadget>
<
name>Where is Hannes?name>
<
version>1.0.0.0version>
<
author name="Johannes Kebeck">
<
info url="http://johanneskebeck.spaces.live.com" text="My Blog" />
<
logo src="logo.jpg" />
author>
<
copyright>© feel free to re-usecopyright>
<
description>The Vista-Sidebar-Gadget-Version of my Tracking Sampledescription>
<
icons>
<
icon width="64" height="64" src="icon.jpg" />
icons>
<
hosts>
<
host name="sidebar">
<
base type="HTML" apiVersion="1.0.0" src="gadget.html" />
<
permissions>Fullpermissions>
<
platform minPlatformVersion="1.0" />
host>
hosts>
gadget>


As you can see the source of the gadget has to be a HTML-file and I called it gadget.html but you can choose any other name as well.

The HTML-document for the Gadget (gadget.html)


As you can see the source of the gadget is a very basic HTML-document. It contains references to a style-sheet, the Virtual Earth MapControl and our own JavaScript-file which we have still to create. In the body we have a DIV-element for the title as well as another DIV-element which will host the Virtual Earth MapControl. The DIV-element for the title also contains a link to a JavaScript-function which will be discussed later.

<html>
<
head>
<
meta http-equiv="Content-Type" content="text/html; charset=Unicode" />
<
title>Hannes Tracking Gadgettitle>
<
link href="gadget.css" rel="stylesheet" type="text/css" />
<
script src="http://dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=6" type="text/javascript">script>
<
script src="gadget.js" type="text/javascript">script>
head>
<
body>
<
div style="font-weight:bold; text-align:center; width:130px"><a href='#' onclick='javascript:showFlyout();'>Where is Hannes?a>div><br />
<
div id='divMap' style="position:absolute; top:20px; left:0px; width:130px; height:130px;">div>
body>
html>

The CSS for the Gadget (gadget.css)


Docked gadgets must be at least 60 pixels high and anywhere from 25 pixels to 130 pixels wide to fit within the maximum width of the Sidebar. The size of the gadget is defined by the height and width of the HTML-body. As you can see in the CSS below I override the styles for scalebar, copyrights and logo. This is something that you should normally never do and in fact it violates the Terms of Use but since the map in my sidebar is so small that the attribution would obstruct the map completely and since my flyout will have the complete attribution anyway, I hope that it is OK. My Style-sheet looks like this.

html
{
overflow:hidden;
}

body
{
font-family:Tahoma;
font-size:12px;
background-color:#464646;
color:#FFFFFF;
position:absolute;
left:0px;
top:0px;
margin-left:0px;
margin-top:0px;
width:130px;
height:150px;
}

h1
{
font-family:Tahoma;
text-align:center;
}

/* Set Link-Colors */
a:link {color:#FFFFFF}
a:visited {color:#FFFFFF}
a:hover {color:#FFFF00}
a:active {color:#FFFFFF}

/* Removing the Microsoft logo, scalebar, and copyright logos off of the map */
#divMap .MSVE_PoweredByLogo
{
display:none;
}
#divMap .MSVE_ScaleBar
{
display:none;
}
#divMap .MSVE_ScaleBarLabel
{
display:none;
}
#divMap .MSVE_Copyright
{
display:none;
}

The JavaScript for the Gadget (gadget.js)


The first difference you see is the reference to the flyout-document. The rest is pretty much the same as the original website for my tracking application which was explained in my previous posting with a few exceptions:


  • The default size of the dashboard would be too big for the gadget so I choose a smaller size:
    * map.SetDashboardSize(VEDashboardSize.Tiny);
    Alternatively you could switch of the interactivity of the map completely which would remove the dashboard and disable all mouse- and keyboard-events:
    * map.LoadMap(new VELatLong(51.461962075378054, -0.9260702133178665), 13, VEMapStyle.Shaded, true);
  • I added a function showFlyout(). This function is being executed when you click on the link in the title of the gadget and will basically open the flyout windows.
window.onload = GetMap;

//TheGadget Flyout-file
System.Gadget.Flyout.file = "flyout.html";

//Map
var map = null;

//VEShapeLayer
var slTracks = new VEShapeLayer();

function GetMap()
{
map = new VEMap('divMap');
map.SetDashboardSize(VEDashboardSize.Tiny);
map.LoadMap(new VELatLong(51.461962075378054, -0.9260702133178665), 13, VEMapStyle.Shaded);
map.AddShapeLayer(slTracks);
//Start Tracking and Set Intervall to 5 minutes
showtime=setInterval("Track()", 300000);
Track();
}

//Tracking
function Track()
{
//Delete previous tracks
slTracks.DeleteAllShapes();

//Build the URL
//The random URL-parameter avoids caching
var url="http://YourServer/Tracking.ashx?" + Math.random();

//Get the appropriate XMLHTTP object for the browser
var xmlhttp = GetXmlHttp();

//if we have a valid XMLHTTP object
if (xmlhttp)
{
xmlhttp.Open("GET", url, true); //varAsynx = true

//set the callback
xmlhttp.onreadystatechange = function()
{
if (xmlhttp.readystate ==4) //4 is a success
{
//server code creates JavaScript "on the fly" for us to
//execute using eval()
var result = xmlhttp.responseText
eval(result);
}
}
xmlhttp.send(null);
}
}

function GetXmlHttp()
{
var x = null;
try
{
x = new ActiveXObject("Msxml2.XMLHTTP");
}
catch (e)
{
try
{
x = new ActiveXObject("Microsoft.XMLHTTP");
}
catch (e)
{
x = null;
}
}
if (!x && typeof XMLHttpRequest != "undefined")
{
x = new XMLHttpRequest();
}
return x;
}

function showFlyout()
{
System.Gadget.Flyout.show = true;
}

All right that's already the first part. Click in the "+" symbol in the sidebar to bring up the "Gadget Gallery".

image

Your new gadget should be visible. Double-click to add it to the sidebar or just drag-and-drop it onto the sidebar.

image

The Flyout


The flyout is a bigger window which will appear when you set the property "System.Gadget.Flyout.show = true;" It will be attached to the docked gadget in the sidebar and is often used to configure the content of the docked gadget or - as in my example - to provide additional information and functions. The approach is very similar to the docked gadget mentioned above and I will use the main web site for the tracking application which I described previously a a template.

The HTML-document for Flyout (flyout.html)


Well the original posting was just providing the tracking functionality and not the function to replay a day so we will have to make some modifications to provide a replay of previous days. In the header we reference the Virtual Earth MapControl as well as our own CSS and JavaScript.

Please note: even though we did define the style for background-colour in the external CSS this would not be applied to the flyout. Apparently this is a bug in the sidebar. The workaround is to define the style in the HTML-document directly.

The body contains a first DIV-element which is basically a header. The second DIV-element contains some checkboxes to start and stop live tracking as well as a replay of a previous day. The days which are available for replay - i.e. the days when I had my GPS switched on - will be displayed in an HTML-SELECT-element. And finally there is a DIV-element which will host our Virtual Earth map.

DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<
html xmlns="http://www.w3.org/1999/xhtml">
<
head>
<
title>Tracking Gadgettitle>
<
link href="flyout.css" rel="stylesheet" type="text/css" />
<
script src="http://dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=6" type="text/javascript">script>
<
script src="flyout.js" type="text/javascript">script>
head>
<
body style="background-color:#5b86ce">
<
div style="position:absolute; top:0px; left:0px; width:100%; height:60px;" class="header">
<
table style="width:100%" >
<
tr style="vertical-align:top">
<
td style="width:140px; min-width:140px"><img src="VirtualEarth.gif" alt="Virtual Earth Logo" style="margin-left:5px;" />td>
<
td><h1 style="min-width:400px">Tracking Gadgeth1>td>
<
td style="width:140px; min-width:140px; text-align:right"><a>Version 6<br />a>td>
tr>
table>
div>
<
div id='divCtrl' style="position:absolute; top:65px; left:5px; width:195px; height:400px;">
<
input id="cbTracking" type="checkbox" onclick="StartStopTracking('cbTracking')" />Start/Stop Tracking<br /><br />
<
hr /><br />
<
b>Select a day for replayb><br />
<
select id="ddReplayDate" style="width:190px">select><br />
<
input id="cbReplay" type="checkbox" onclick="StartStopReplay('cbReplay')" />Start/Stop Replay<br /><br />
<
hr /><br />
<
a href='#' onclick='javascript:hideFlyout();'>Close Flyouta>
div>
<
div id='divMap' style="position:absolute; top:65px; left:205px; width:590px; height:530px;">div>
body>
html>

The CSS for the Flyout (flyout.css)


There are no surprises in the CSS. As mentioned before the height and width of the body determine the size of the flyout-window.

html
{
overflow:hidden;
}

body
{
font-family:Tahoma;
font-size:12px;
background-color:#5b86ce;
color:#00284A;
position:absolute;
left:0px;
top:0px;
margin-left:0px;
margin-top:0px;
width:800px;
height:600px;
}

h1
{
font-family:Tahoma;
text-align:center;
}

.header
{
font-family:Tahoma;
background-color:#00284A;
color:#5b86ce;
}

a

The JavaScript for the Flyout (flyout.js)


The live-tracking part is the same as in the docked gadget with the exception that I use the default dashboard-size for the map and that I provide a checkbox which allows me to start and stop tracking.

I also call a function GetDates(). This function creates an AJAX-call to a new web-handler (GetDates.ashx). The source for that web handler is included in the sample code linked above and also listed at the end of this posting. It basically connects to the database and executes a "SELECT DISTINCT GPSdate FROM Tracks ORDER BY GPSdate DESC". The result will be used to create a JavaScript which populates my HTML-SELECT-element in the flyout.html site with the available days for replay. The general approach to integrate Virtual Earth with a database is described in one of my previous posting.

Another AJAX-call will be executed when the checkbox for the replay is activated. It calls my web handler Replay.ashx. This web handler is as well included the sample code linked above and listed at the end of this posting.

Finally there is also a JavaScript hideFlyout() which allows us to close the Flyout-window but in fact the flyout would be closed anyway when the flyout-window looses it's focus.

window.onload = GetMap;

//Map
var map = null;

//VEShapeLayer
var slTracks = new VEShapeLayer();

function GetMap()
{
//Populate Dropdown-List
GetDates();

map = new VEMap('divMap');
map.LoadMap(new VELatLong(51.461962075378054, -0.9260702133178665), 13, VEMapStyle.Shaded);
map.AddShapeLayer(slTracks);
}

//Start/Stop Tracking
function StartStopTracking(control)
{
if (document.getElementById(control).checked == false) {
clearInterval(showtime);
slTracks.DeleteAllShapes();
}
else {
//Start Tracking and Set Intervall to 5 minutes
showtime=setInterval("Track()", 300000);
Track();
}
}

//Tracking
function Track()
{
//Delete previous tracks
slTracks.DeleteAllShapes();

//Build the URL
//The random URL-parameter avoids caching
var url="http://YourServer/Tracking.ashx?" + Math.random();

//Get the appropriate XMLHTTP object for the browser
var xmlhttp = GetXmlHttp();

//if we have a valid XMLHTTP object
if (xmlhttp)
{
xmlhttp.Open("GET", url, true); //varAsynx = true

//set the callback
xmlhttp.onreadystatechange = function()
{
if (xmlhttp.readystate ==4) //4 is a success
{
//server code creates JavaScript "on the fly" for us to
//execute using eval()
var result = xmlhttp.responseText
eval(result);
}
}
xmlhttp.send(null);
}
}

function GetXmlHttp()
{
var x = null;
try
{
x = new ActiveXObject("Msxml2.XMLHTTP");
}
catch (e)
{
try
{
x = new ActiveXObject("Microsoft.XMLHTTP");
}
catch (e)
{
x = null;
}
}
if (!x && typeof XMLHttpRequest != "undefined")
{
x = new XMLHttpRequest();
}
return x;
}

//Fill DropDownList
function GetDates()
{
//Build the URL
//The random URL-parameter avoids caching
var url="http://YourServer/GetDates.ashx?" + Math.random();

//Get the appropriate XMLHTTP object for the browser
var xmlhttp = GetXmlHttp();

//if we have a valid XMLHTTP object
if (xmlhttp)
{
xmlhttp.Open("GET", url, true); //varAsynx = true

//set the callback
xmlhttp.onreadystatechange = function()
{
if (xmlhttp.readystate ==4) //4 is a success
{
//server code creates JavaScript "on the fly" for us to
//execute using eval()
var result = xmlhttp.responseText
eval(result);
}
}
xmlhttp.send(null);
}
}

//Start/Stop Replay
function StartStopReplay(control)
{
if (document.getElementById(control).checked == false) {
slTracks.DeleteAllShapes();
}
else {
Replay();
}
}

//Replay
function Replay()
{
//Build the URL
var url="http://YourServer/Replay.ashx?myDate=" + document.getElementById("ddReplayDate").value;

//Get the appropriate XMLHTTP object for the browser
var xmlhttp = GetXmlHttp();

//if we have a valid XMLHTTP object
if (xmlhttp)
{
xmlhttp.Open("GET", url, true); //varAsynx = true

//set the callback
xmlhttp.onreadystatechange = function()
{
if (xmlhttp.readystate ==4) //4 is a success
{
//server code creates JavaScript "on the fly"
//execute using eval()
var result = xmlhttp.responseText
eval(result);
}
}
xmlhttp.send(null);
}
}

function hideFlyout()
{
System.Gadget.Flyout.show = false;
}

That's it. Now my boss can always see where the "Virtual Hannes" is without even opening his browser.

image

The complete source code for the web application is linked here. The code for the gadget is here:


Other Listing


GetDates.ashx

<%@ WebHandler Language="VB" Class="GetDates" %>

Imports System
Imports System.Web
Imports System.Data.SqlClient

Public Class GetDates : Implements IHttpHandler

Public Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
'set culture to en-UK to avoid potential problems with decimal-separators
System.Threading.Thread.CurrentThread.CurrentCultu re = System.Globalization.CultureInfo.CreateSpecificCul ture("en-UK")

'Retrieve Dates
Dim settings As ConnectionStringSettings = ConfigurationManager.ConnectionStrings("Tracking")
Dim sb As StringBuilder = New StringBuilder
sb.Append("var sOpts = " + """" + "" + """" + ";")
context.Response.Write(sb.ToString())
End Sub

Public ReadOnly Property
IsReusable() As Boolean Implements IHttpHandler.IsReusable
Get
Return False
End Get
End Property

End Clas
s

Replay.ashx

<%@ WebHandler Language="VB" Class="Replay" %>

Imports System
Imports System.Web
Imports System.Data.SqlClient

Public Class Replay : Implements IHttpHandler

Public Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
'set culture to en-UK to avoid potential problems with decimal-separators
System.Threading.Thread.CurrentThread.CurrentCultu re = System.Globalization.CultureInfo.CreateSpecificCul ture("en-UK")

'Fetch the URL-parameter
Dim myDate As String = context.Request.Params("myDate")

'Retrieve GPS-Positions
Dim settings As ConnectionStringSettings = ConfigurationManager.ConnectionStrings("Tracking")
Dim sb As StringBuilder = New StringBuilder
Dim myPins As String = ""
Dim myIcon As String = ""
Dim myConn As New SqlConnection(settings.ConnectionString)
Dim myQuery As String = "SELECT Lat, Long, DevName, GPSdate, GPStime, Speed, Heading FROM Tracks WHERE GPSdate LIKE '" + myDate + "' ORDER BY GPStime"
Dim myCMD As New SqlCommand(myQuery, myConn)
myConn.Open()
Dim i As Integer = 0
Dim myReader As SqlDataReader = myCMD.ExecuteReader()
While myReader.Read()
i = i + 1
'Determine the CustomIcon based on the heading and speed
If myReader(5).ToString = "0" Then
myIcon = "stationary.png"
Else
Select Case
myReader(6)
Case 0 To 22
myIcon = "n.png"
Case 23 To 57
myIcon = "ne.png"
Case 58 To 112
myIcon = "e.png"
Case 113 To 147
myIcon = "se.png"
Case 148 To 202
myIcon = "s.png"
Case 203 To 247
myIcon = "sw.png"
Case 248 To 292
myIcon = "w.png"
Case 293 To 337
myIcon = "nw.png"
Case 338 To 360
myIcon = "n.png"
End Select
End If

myPins = myPins + _
"setTimeout('slTracks.DeleteAllShapes();var " + myReader(2).ToString + "=new VEShape(VEShapeType.Pushpin, new VELatLong(" + myReader(0).ToString + ", " + myReader(1).ToString + "));" + _
myReader(2).ToString + ".SetTitle(" + """" + myReader(2).ToString + """" + ");" + _
myReader(2).ToString + ".SetDescription(" + """" + "Date: " + myReader(3).ToString + "
Time: "
+ myReader(4).ToString + "
Speed: "
+ myReader(5).ToString + "
Heading: "
+ myReader(6).ToString + """" + ");" + _
myReader(2).ToString + ".SetPhotoURL(" + """" + "http://YourServer/Hannes.JPG" + """" + ");" + _
myReader(2).ToString + ".SetMoreInfoURL(" + """" + "http://johanneskebeck.spaces.live.com/" + """" + ");" + _
myReader(2).ToString + ".SetCustomIcon(" + """" + myIcon + """" + ");" + _
"slTracks.AddShape(" + myReader(2).ToString + ");" + _
"map.SetCenter(new VELatLong(" + myReader(0).ToString + ", " + myReader(1).ToString + "));'," + (i * 1000).ToString + ");"
End While
i = i + 1
myPins = myPins + _
"setTimeout('alert(" + """" + "Replay Complete" + """" + ");'," + (i * 1000).ToString + ");"
sb.Append(myPins)
myReader.Close()
myConn.Close()
context.Response.Write(sb.ToString())
End Sub

Public ReadOnly Property
IsReusable() As Boolean Implements IHttpHandler.IsReusable
Get
Return False
End Get
End Property

End Clas
s




Click here to view the article.
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!Spurl this Post!Reddit! Wong this Post!
Reply With Quote
Reply


LinkBacks (?)
LinkBack to this Thread: http://www.mapforums.com/virtual-earth-gadget-windows-vista-sidebar-7401.html

Posted By For Type Date
Virtual Earth as Gadget for Windows Vista Sidebar (://URLFAN) This thread Refback 07-21-2008 05:30 PM
Gadgetism.org: Check out these new Sidebar Gadgets for Windows Vista This thread Refback 05-11-2008 11:08 PM
Programming MapPoint via .NET - MapPoint Articles - MP2K Magazine This thread Refback 04-08-2008 06:30 PM
The Magazine for MapPoint - MP2K Magazine This thread Refback 04-03-2008 10:56 AM
Virtual Earth as Gadget for Windows Vista Sidebar - MapPoint Forums This thread Refback 04-02-2008 02:59 PM

Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)

 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is On
Trackbacks are On
Pingbacks are On
Refbacks are On

Similar Threads

Thread Thread Starter Forum Replies Last Post
Traffic by Live Search Maps Vista Gadget Returns VirtualEarth MSDN Blog Virtual Earth Blogs 0 02-11-2008 06:00 PM
Virtual Earth API: How to Create a Full-Screen Virtual Earth Mashup Keith Kinnan's Weblog Virtual Earth Blogs 0 01-04-2008 09:27 AM
Virtual Earth News from GEOINT 2007: Virtual Earth Appliance VE For Government Virtual Earth Blogs 0 10-24-2007 12:10 PM
Vista Gadget That Tracks the International Space Station Eric Frost MP2K Magazine Articles 1 04-20-2007 04:41 AM
Using Virtual Earth in a Vista Gadget Eric Frost MP2K Magazine Articles 0 03-06-2007 01:53 PM


All times are GMT -5. The time now is 02:00 AM.


Powered by vBulletin® Version 3.7.2
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.2.0
MP2K Magazine
Visitor Map

Cheap Ski
Looking for a cheap ski? Holiday Hypermarket uses the UK's leading tour operators to provide you with fantastic low prices. Book a cheap ski holiday online today.

Spain Holidays
Find great Spain Holidays with Travel Counsellors. A personal Travel Counsellor can help you plan the perfect holiday to Spain.

Holidays to Cuba
Situated between Jamaica and the Bahamas, Cuba has a delightful tropical climate and warm, clear waters with beaches of white sand. Check for cheap holidays to Cuba.

Holidays to Jamaica
Holidays to Jamaica are about taking things easy. Forget your watch and chill out beneath the clear Jamaican sky.

Cheap Morocco Holidays
Cheap Morocco holidays may be the answer to your cheap holiday search. With sunshine throughout most of the year it can be great value if you avoid the peak season. Why not include a trip to the small tranquil town of Chefchaouen Tangier in your visit?

Holiday Packages
Spoil yourself and your loved ones with one of the great Holiday Packages from Travel.co.uk.

Cyprus Holidays
Fancy a Mediterranean holiday? Get information on Cyprus holidays at On The Beach.


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51