Recent Blog Posts RSS
ViaWindowsLive on Via Virtual Earth Blog
The new ViaWindowsLive community site has launched and features not only a definitive set of resources on all Live Services from Microsoft but also a special section on Virtual Earth including a new site gallery for you to upload your sites, new articles on Version 6, including getting started guide, an interactive quick guide, location finder and more. Subscribe to the VWL aggregated blog to stay in touch with everything Live Services related. Find all the great content from this site and much, much more. Explore how other Live Services can compliment Virtual Earth and your applications.
Version 5 URL changed - Error: 'VEMap' is undefined on Via Virtual Earth Blog
It has been reported that the old url to access the Version5 javascript for Virtual Earth no longer works. This is effecting sites worldwide.
The correct way to reference the Version 5 javascript is:
<script type="text/javascript" src="http://dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=5"></script>
If you have been effected a forum thread has been started here
Silverlight Virtual Earth viewer on Via Virtual Earth Blog
With the launch of silverlight yesterday I was digging around and found this viewer for Virtual Earth by Greg Schechter. It does use the 1.1 alpha of silverlight. It gives some interesting ideas for where Virtual Earth could be headed. Certainly the demo of the performance of silverlight compared to javascript for processing showed a significant increase. This could be very useful.
And of course on the gamer front check this out by Andy Beaulieu and shoot down some UFO's over Birdseye images.
John.
So much new Virtual Earth Imagery Worldwide. on Via Virtual Earth Blog
I subscribe to all the VE blogs and recently the posts about updated imagery has been more and more frequent.
The latest is here and for myself downunder we saw three updates, Canberra, Newcastle and Uluru:


Derek Chan posts 3 Articles in a month! on Via Virtual Earth Blog
A big thank you to the efforts of Derek Chan who posted his third VE article today (he actually had it ready weeks ago but had to wait for Mr Bottleneck here at VVE ;) )
The 3 articles are all relivant to Version 5 of Virtual Earth and deal with the Mini Map, debugging javascript and now custom pins in routes.
All these can now be found in our articles section.
If you have something to contribute send us an email.
John (The bottleneck)
Creating Your First Virtual Earth v1 Page (Part 1) RSS
This article is written for an old version of the Virtual Earth platform. While still available for reference purposes, it is unlikely to work if implemented.
This article will help you understand how to get started using the Virtual Earth Map Control. The map control used in Virtual Earth is a JScript control that presents a great user experience for map content.
This article is also available in PDF format.
By the end of this article we will have created a web page that displays a map control and allows for some user input as shown in Figure 1.

Figure 1
Using the MapControl
The Virtual Earth Map Control script can be found at http://virtualearth.msn.com/js/MapControl.js
You can link directly to this on your site but that will cause issues with security. By default most browsers will not allow Jscript to run from another site than the one being browsed. Users would have to confirm that they wanted to run the Jscript from the VirtualEarth site. This doesn�t create a great user experience.
The simple solution is to copy the MapControl.js file to your site. Once you have a copy of the JS file in your domain then the map control can be accessed.
Creating a Map Control instance
To create a new instance of a Virtual Earth Map Control you will need to write a small method in Jscript on your page. This will create an instance of the Mapcontrol, position it on the page and set up the initial content of the control.
The VE_MapControl constructor has the following prototype:
VE_MapControl(Latitude, Longitude, Zoom, MapStyle, PositionType, Left, Top, Width, Height);
- Latitude
- the latitude of the centre point of the map to display in the control
- Longitude
- the longitude of the centre point of the map to display in the control
- Zoom
- the scale to zoom in of the map displayed. A number from 2 to 18. Where 2 is zoomed as far out as the control will allow and 18 is zoomed in as close as the control will allow.
- MapStyle
-
the style to use when displaying the map. There are currently 3 style options; aerial, road, and hybrid. To set a style use the first letter (lowercase) of the style.
- a - aerial: Displays an aerial satellite image of the map display.
- r � road: Displays a vector street map of the area in the control.
- h � hybrid: Displays a combination of aerial and vector. The aerial image is overlayed with vector street and location information.
- PositionType
- the way in which the control should be positioned on the page. The two main options here are �relative� and �absolute�.
- Left
- the position of the left of the control on the page
- Top
- the position of the top of the control on the page
- Width
- the width of the control
- Height
- the height of the control
Example:
map = new VE_MapControl(32.69, -117.13, 12, 'r', "absolute", 400, 10, 400, 300);
A simple web page with a Virtual Earth map control can then be created as shown in Listing 1.
<html>
<head>
<title>My Virtual Earth</title>
<script src="MapControl.js"></script>
<script>
var map = null;
function OnPageLoad()
{
map = new VE_MapControl(32.69, -117.13, 12, 'r', "absolute", 10, 10, 700, 500);
document.body.appendChild(map.element);
}
</script>
</head>
<body onLoad="OnPageLoad()">
</body>
</html>
Listing 1
This should allow you to create a page that looks similar to that shown in figure 2 below. The control provides a number of features for �free�. You should be able to:
- move the map around by dragging it
- zoom in and out with the mouse wheel
- zoom in by double clicking on a location

Figure 2
Receiving Events from the Map Control
As the map displayed on the control is changed the map control raises events that provide information about the map currently displayed in the control.
The events you can receive from the control are:
- onStartContinuousPan
- onEndContinuousPan
- onStartZoom
- onEndZoom
- onMouseClick
- onMouseDown
- onMouseUp
All of the event functions are passed a single parameter. This event parameter is defined in the MapControl.js as:
function VE_MapEvent(srcMapControl,latitude,longitude,zoomLevel)
{
this.srcMapControl=srcMapControl;
this.latitude=latitude;
this.longitude=longitude;
this.zoomLevel=zoomLevel;
}
The latitude and longitude indicates the centre point of the map. The zoomlevel provides the amount zoom applied to the map displayed.
The first events we will examine are the panning events. These are raised each time the map starts or stops panning, or scrolling. As you might expect the onStartContinousPan event is raised when the map starts scrolling and the onEndContinousPan event is raised when the map control finishes scrolling the map.
To the simple page we created in the previous step we can add some code to handle the onEndContinousPan event and display information as to the new centre point of the map.
The code shown in Listing 2 demonstrates this.
<html>
<head>
<title>My Virtual Earth</title>
<script src="MapControl.js"></script>
<script>
var map = null;
function OnPageLoad()
{
map = new VE_MapControl(32.69, -117.13, 12, 'r', "absolute", 10, 100, 700, 500);
document.body.appendChild(map.element);
map.onEndContinuousPan = function(e)
{
document.getElementById("info").innerHTML =
'Latitude = ' + e.latitude +
', Longitude = ' + e.longitude +
', Zoom=' + e.zoomLevel;
}
}
</script>
</head>
<body onLoad="OnPageLoad()">
<div id="info" style="font-size:10pt">
</div>
</body>
</html>
Listing 2
We can do the same with the onEndZoom event by adding a function to handle that event, Listing 3.
<html>
<head>
<title>My Virtual Earth</title>
<script src="MapControl.js"></script>
<script>
var map = null;
function OnPageLoad()
{
map = new VE_MapControl(32.69, -117.13, 12, 'r', "absolute", 10, 100, 700, 500);
document.body.appendChild(map.element);
var updateInfo = function(e)
{
document.getElementById("info").innerHTML =
'Latitude = ' + e.latitude +
', Longitude = ' + e.longitude +
', Zoom=' + e.zoomLevel;
}
map.onEndContinuousPan = updateInfo;
map.onEndZoom = updateInfo;
}
</script>
</head>
<body onLoad="OnPageLoad()">
<div id="info" style="font-size:10pt">
</div>
</body>
</html>
Listing 3
The page should now appear as shown in Figure 3.

Figure 3
Changing the Map Style
Previously, in the section describing the creation of the Map Control, the 3 different map styles were explained.
The map styles are:
- aerial
- an aerial satellite image of the map display
- road
- a street map of the area in the control
- hybrid
- a combination of aerial and vector. The aerial image is overlayed
Once the map control is displayed it is possible to change the map style by using the SetMapStyle function on the Map Control:
SetMapStyle(mapStyle)
The function takes one parameter to indicate the style. Similar to setting the initial style the parameter is the first single character of the style; �a�, �r� or �h�.
On the page we are creating let�s add two checkboxes to allow the user to change the map style.
<html>
<head>
<title>My Virtual Earth</title>
<script src="MapControl.js"></script>
<script>
var map = null;
function OnPageLoad()
{
map = new VE_MapControl(32.69, -117.13, 12, 'r', "absolute", 10, 100, 700, 500);
document.body.appendChild(map.element);
var updateInfo = function(e)
{
document.getElementById("info").innerHTML =
'Latitude = ' + e.latitude +
', Longitude = ' + e.longitude +
', Zoom=' + e.zoomLevel;
}
map.onEndContinuousPan = updateInfo;
map.onEndZoom = updateInfo;
}
function ChangeMapStyle()
{
var Aerial = document.getElementById("AerialStyleCheck");
var Vector = document.getElementById("VectorStyleCheck");
var s = 'r';
if (Aerial.checked && Vector.checked)
{
s = 'h';
}
else if (Aerial.checked)
{
s = 'a';
}
map.SetMapStyle(s);
}
</script>
</head>
<body onLoad="OnPageLoad()">
<div id="info" style="font-size:10pt">
</div>
<div id="MapStyle" style="POSITION:absolute;LEFT:470px;TOP:60px">
<input id="VectorStyleCheck" type="checkbox" onclick="ChangeMapStyle()" checked="checked">
Street Style
<input id="AerialStyleCheck" type="checkbox" onclick="ChangeMapStyle()">
Aerial Style
</div>
</body>
</html>
Listing 4
Viewing this page in a browser now allows the user to see any of the 3 styles. Figure 4 shows a hybrid view of the map in the control.

Figure 4
Adding a Pushpin to the Map
The ability to add pins to the map allows us to indicate particular locations on the map control. Pins work by overlaying information on the map control. The prototype of the AddPushpin method looks like this:
AddPushpin(id,lat,lon,width,height,className,innerHtml)
- id
- the identifier of the pin. This should be unique for the pin on the map control.
- lat
- the latitude of the location to place the pushpin
- lon
- the longitude of the location to place the pushpin
- width
- the width of the pin
- height
- the height of the pin
The width and height are used to calculate the offset of the pin so that the center of the pin is at the latitude and longitude specified.
HINT: If you want to have the bottom right corner of the pin at the latitude and longitude then you could double these values.
- Classname
- name of a style class for the pin. Without this the pin will not be displayed. This can be described in a CSS file or inline as per the example below.
- innerHTML
- the text to go in the Pushpin
In the following example (Listing 5) the onMouseClick event is used to add a pushpin to the map where the user clicked.
<html>
<head>
<title>My Virtual Earth</title>
<style type="text/css" media=screen>
<!--
.pin
{
width:44px;height:17px;
font-family:Arial,sans-serif;
font-weight:bold;font-size:8pt;
color:White;overflow:hidden;
cursor:pointer;text-decoration:none;
text-align:center;background:#0000FF;
border:1px solid #FF0000;
z-index:5;
}
-->
</style>
<script src="MapControl.js"></script>
<script>
var map = null;
function OnPageLoad()
{
map = new VE_MapControl(32.69, -117.13, 12, 'r', "absolute", 10, 100, 700, 500);
document.body.appendChild(map.element);
var updateInfo = function(e)
{
document.getElementById("info").innerHTML =
'Latitude = ' + e.latitude +
', Longitude = ' + e.longitude +
', Zoom=' + e.zoomLevel;
}
map.onEndContinuousPan = updateInfo;
map.onEndZoom = updateInfo;
map.onMouseClick = function(e)
{
map.AddPushpin('pin', e.latitude, e.longitude, 88, 34, 'pin', 'MyPin');
}
}
function ChangeMapStyle()
{
var Aerial = document.getElementById("AerialStyleCheck");
var Vector = document.getElementById("VectorStyleCheck");
var s = 'r';
if (Aerial.checked && Vector.checked)
{
s = 'h';
}
else if (Aerial.checked)
{
s = 'a';
}
map.SetMapStyle(s);
}
</script>
</head>
<body onLoad="OnPageLoad()">
<div id="info" style="font-size:10pt">
</div>
<div id="MapStyle" style="POSITION:absolute;LEFT:470px;TOP:60px">
<input id="VectorStyleCheck" type="checkbox" onclick="ChangeMapStyle()" checked="checked">
Street Style
<input id="AerialStyleCheck" type="checkbox" onclick="ChangeMapStyle()">
Aerial Style
</div>
</body>
</html>
Listing 5
Viewing this page in a browser will now allow push pins to be added by clicking on the map. There are several issues with this:
- Each time the map is dragged another push pin gets added.
- Double clicking on the map to zoom in no longer works, because a pin is added first that receives the double click event.
- It is possible to add multiple pins with the same identifier.
A solution would be not to add push pins using the onMouseClick event. For now let�s stick with this and each time we add a pin remove the previous pin.
To remove a pin use the RemovePushpin function.
RemovePushpin(id);
This function takes a single parameter which identifies the pin to remove.
Removing a pushpin will remove any pushpins that share the same identifier.
The onMouseClick function shown in Listing 5 can be changed to remove the previous pin as shown in Listing 6.
map.onMouseClick = function(e)
{
map.RemovePushpin('pin');
map.AddPushpin('pin', e.latitude, e.longitude, 88, 34, 'pin', 'MyPin');
}
Listing 6
We should now have a page that will contain a single push pin indicating the last place on the map that was clicked, Figure 5.

Figure 5
Adding Navigation Controls
The map control has some useful built in navigation features but it is sometimes useful to provide extra controls on the web page to allow the user to navigate around the map. In this final section of this article you will learn how to add buttons to the web page that can control the contents of the map control.
Panning
We will start by adding buttons to pan around the map. In the body element of the HTML page buttons can be added with simple HTML code:
<input type="button" value="Pan Up" onclick="DoPanUp()" style="position:absolute;left:60px;top:600px;"/>
<input type="button" value="Pan Left" onclick="DoPanLeft()" style="position:absolute;left:10px;top:630px;"/>
<input type="button" value="Pan Right" onclick="DoPanRight()" style="position:absolute;left:100px;top:630px;"/>
<input type="button" value="Pan Down" onclick="DoPanDown()" style="position:absolute;left:45px;top:660px;"/>
The code to action on the button clicks can then be added to the script section in the page. Using the PanMap method on the map control. PanMap takes 2 parameters, x and y. These indicate by how much to pan the map view in the x and y directions.
function DoPanUp() { map.PanMap(0, -100); }
function DoPanDown() { map.PanMap(0, 100); }
function DoPanLeft() { map.PanMap(-100, 0); }
function DoPanRight() { map.PanMap(100, 0); }
If you load this page in a browser and click the buttons you can see the map jump around. This is not a great user experience. It would be nicer to show the map scrolling smoothly in each of the directions. This can be achieved using the ContinuousPan function of the map control. ContinuousPan takes a third parameter along with the x and y. This third parameter indicates how many times to repeat the pan. In this way a number of small operations can be put together to provide the appearance of the map scrolling.
function DoPanUp() { map.ContinuousPan(0, -10, 20); }
function DoPanDown() { map.ContinuousPan(0, 10, 20); }
function DoPanLeft() { map.ContinuousPan(-10, 0, 20); }
function DoPanRight() { map.ContinuousPan(10, 0, 20); }
Zooming
Next we will add 2 buttons in the HTML; to zoom in and to zoom out.
<input type="button" value="Zoom In" onclick="DoZoomIn()" style="position:absolute;left:250px;top:630px;"/>
<input type="button" value="Zoom Out" onclick="DoZoomOut()" style="position:absolute;left:340px;top:630px;"/>
The accompanying script code can use the ZoomIn and ZoomOut functions of the map control. Each functional call will simply increase or decrease the zoom level by 1.
function DoZoomIn() { map.ZoomIn(); }
function DoZoomOut() { map.ZoomOut(); }
Conclusion
If you have followed along with this article you should now have a page that looks similar to that shown in Figure 1. The complete code listing is provided in Listing 7 below.
Using the Virtual Map Control is relatively simple and it provides a very compelling user experience for mapping and location identification.
<html>
<head>
<title>My Virtual Earth</title>
<style type="text/css" media=screen>
<!--
.pin
{
width:44px;height:17px;
font-family:Arial,sans-serif;
font-weight:bold;font-size:8pt;
color:White;overflow:hidden;
cursor:pointer;text-decoration:none;
text-align:center;background:#0000FF;
border:1px solid #FF0000;
z-index:5;
}
-->
</style>
<script src="MapControl.js"></script>
<script>
var map = null;
function OnPageLoad()
{
map = new VE_MapControl(32.69, -117.13, 12, 'r', "absolute", 10, 100, 700, 500);
document.body.appendChild(map.element);
var updateInfo = function(e)
{
document.getElementById("info").innerHTML =
'Latitude = ' + e.latitude +
', Longitude = ' + e.longitude +
', Zoom=' + e.zoomLevel;
}
map.onEndContinuousPan = updateInfo;
map.onEndZoom = updateInfo;
map.onMouseClick = function(e)
{
map.RemovePushpin('pin');
map.AddPushpin('pin', e.latitude, e.longitude, 88, 34, 'pin', 'MyPin');
}
}
function ChangeMapStyle()
{
var Aerial = document.getElementById("AerialStyleCheck");
var Vector = document.getElementById("VectorStyleCheck");
var s = 'r';
if (Aerial.checked && Vector.checked)
{
s = 'h';
}
else if (Aerial.checked)
{
s = 'a';
}
map.SetMapStyle(s);
}
function DoPanUp() { map.ContinuousPan(0, -10, 20); }
function DoPanDown() { map.ContinuousPan(0, 10, 20); }
function DoPanLeft() { map.ContinuousPan(-10, 0, 20); }
function DoPanRight() { map.ContinuousPan(10, 0, 20); }
function DoZoomIn() { map.ZoomIn(); }
function DoZoomOut() { map.ZoomOut(); }
</script>
</head>
<body onLoad="OnPageLoad()">
<div id="info" style="font-size:10pt">
</div>
<div id="MapStyle" style="POSITION:absolute;LEFT:470px;TOP:60px">
<input id="VectorStyleCheck" type="checkbox" onclick="ChangeMapStyle()" checked="checked">
Street Style
<input id="AerialStyleCheck" type="checkbox" onclick="ChangeMapStyle()">
Aerial Style
</div>
<input type="button" value="Pan Up" onclick="DoPanUp()" style="position:absolute;left:60px;top:600px;"/>
<input type="button" value="Pan Left" onclick="DoPanLeft()" style="position:absolute;left:10px;top:630px;"/>
<input type="button" value="Pan Right" onclick="DoPanRight()" style="position:absolute;left:100px;top:630px;"/>
<input type="button" value="Pan Down" onclick="DoPanDown()" style="position:absolute;left:45px;top:660px;"/>
<input type="button" value="Zoom In" onclick="DoZoomIn()" style="position:absolute;left:250px;top:630px;"/>
<input type="button" value="Zoom Out" onclick="DoZoomOut()" style="position:absolute;left:340px;top:630px;"/>
</body>
</html>
Listing 7


