Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / ASP.NET

Data Visualization with the Virtual Earth ASP.NET Controls

4.91/5 (22 votes)
6 Dec 2008CPOL9 min read 248.8K   818  
An introduction on how to use Virtual Earth's ASP.NET Controls to show data on a map.

Introduction

This article is very much an introduction to the new ASP.NET controls for Virtual Earth. Here, I will explain how to get a basic site up and running with a Virtual Earth map on it, and show you some of the basic visualization methods available. Virtual Earth is a very powerful mapping toolkit, and there are many aspects that I am not going to cover.

This article is based on the November 2008 CTP of the Windows Live Tools.

A pre-built example of some of the code in this article is also available for download: Virtual Earth Example (17.3 KB).

Getting Going

First, you need to add an assembly reference to the Virtual Earth control to your project.

Assembly Reference in Visual Studio Solution

In each page that you want to use the Virtual Earth control, you must add a line that looks like this at the top of the file:

ASP.NET
<%@ Register Assembly="Microsoft.Live.ServerControls.VE"
    Namespace="Microsoft.Live.ServerControls.VE"
    TagPrefix="ve" %>

This registers the assembly, allowing you to use the control.

When you view the ASPX page, you will see that you have additional tools in the toolbox that relate to Virtual Earth. The one we are going to look at in this post is the Map control.

ASP.NET Toolbox in Visual Studio

From the toolbox, you can drag a Map control onto your design surface. The code it generates will set up a default position and zoom level which centers on the continental United States.

By default, the control is a 400x400px square, and has been given a name of Map1:

HTML
<ve:Map ID="Map1" runat="server" Height="400px" Width="400px" 
    ZoomLevel="4" />

To start with, we are going to change the defaults to something that is closer to home (well, mine at least), and centre it on central and southern Scotland and zoom in somewhat. I also don't like the name Map1, so I'm going to change that too:

HTML
<ve:Map ID="VEMap" runat="server" Height="600px" Width="400px" 
    ZoomLevel="8" Center-Latitude="55.75" Center-Longitude="-3.5" />

The first thing I should comment on is the zoom level because it doesn't really mean anything to anyone. Personally, I'd like to say "here's a bounding box for the area I want to see, you figure out how to do that and sort out the aspect ratio for me". Then again, maybe, that's because when I wrote a GIS system for my final year project at university, that was what I did. I didn't constrain the user to specific and artificial zoom levels. The math behind it isn't difficult, and a modern graphics card can do that with its proverbial eyes closed. Having said that, I can understand why it was done that way. It means that none of the maps are generated on the fly, it is all based on pre-existing graphic files that are retrieved as needed. This means no strained servers trying to render maps.

The zoom level ranges from 1 to 19. 1 is zoomed out to the whole world, and 19 is zoomed in to street level. In between that, it seems to be mostly a matter of experimentation.

As it stands, the program will display a map on the page, and you can zoom in or out, pan around, and change display modes and so on, just like Live Maps.

This is all very well and good. However, if you want the map to be able to respond to server side events, you still need to do a little extra work to wire everything up correctly. The Virtual Earth server-side events are handled as part of an AJAX postback rather than a page postback. The map control has its own internal UpdatePanel that you would normally need to indicate that the part of the page is "AJAXified", so to speak. So, to ensure that the code works as we would expect it to, we need to add something else to the ASPX file.

We need a ScriptManager:

ASP.NET
<asp:ScriptManager ID="ScriptManager1" runat="server" 
     EnablePartialRendering="true">
</asp:ScriptManager>

Displaying Points on a Map

In Virtual Earth parlons, displaying a point is done with "Pushpins". A pushpin is a type of shape that we can put on the map.

In the code-behind, we have a method for adding shapes to the map (AddShape) as this is a multi-step process. First, we need to create an object to represent the point, then an object to represent the shape (we'll come to other shape types later, but for the moment, we're just dealing with pushpins). Finally, we add the shape to the map.

The Page_Load method adds a number of shapes to the map, these pushpins represent locations where Scottish Developers have held user group meetings. The code looks like this:

protected void Page_Load(object sender, EventArgs e)
{
    // Glasgow Caledonian University
    AddShape(55.8662120997906, -4.25060659646988);

    // Dundee University
    AddShape(56.4572643488646, -2.97848381102085);

    // Microsoft Edinburgh (George Street)
    AddShape(55.9525336325169, -3.20506207644939);
    
    // Microsoft Edinburgh (Waterloo Place)
    AddShape(55.9535374492407, -3.18680360913277);
}
 
private void AddShape(double latitude, double longitude)
{
    LatLongWithAltitude point = new LatLongWithAltitude(latitude, 
        longitude);
    Shape shape = new Shape(ShapeType.Pushpin, point);
    VEMap.AddShape(shape);
}

From this, we get a fairly standard output when the application is run:

Pushpins in Virtual Earth

At present, this is all visual. There isn't any real functionality. What we'll do is add some very basic functionality, so that when you hover over a pushpin, it tells you something about it. The Shape object has a Description property into which you can put an HTML fragment. So, here is the updated code:

C#
protected void Page_Load(object sender, EventArgs e)
{
    // Glasgow Caledonian University
    AddShape(55.8662120997906, -4.25060659646988, 
        "<b>Glasgow Caledonian University</b>");

    // Dundee University
    AddShape(56.4572643488646, -2.97848381102085,
        "<b>Dundee University</b>");

    // Microsoft Edinburgh (George Street)
    AddShape(55.9525336325169, -3.20506207644939,
        "<b>Microsoft Edinburgh</b> (George Street)");
    
    // Microsoft Edinburgh (Waterloo Place)
    AddShape(55.9535374492407, -3.18680360913277,
        "<b>Microsoft Edinburgh</b> (Waterloo Place)");
}
 
private void AddShape(double latitude, double longitude, 
                      string description)
{
    LatLongWithAltitude point = new LatLongWithAltitude(latitude, 
        longitude);
    Shape shape = new Shape(ShapeType.Pushpin, point);
    shape.Description = description;
    VEMap.AddShape(shape);
}

The result when you hover over a pushpin looks like this:

Pushpin with description

That's all great if you want the default pushpin look. However, you might want to customise the pins so they match more what you are looking for. The Shape class has a CustomIcon property which you can set to be a graphics object. In the following example, I've used a simple PNG file with a red circle and a semi-transparent yellow fill.

The code now looks like this:

C#
private void AddShape(double latitude, double longitude, 
                      string description)
{
    LatLongWithAltitude point = new LatLongWithAltitude(latitude, 
        longitude);
    Shape shape = new Shape(ShapeType.Pushpin, point);
    shape.Description = description;
    shape.CustomIcon = "images/target.png";
    VEMap.AddShape(shape);
}

And, the result looks like this:

Pushpin with a different style

You can also use animated GIF files, and they will animate on the map; however, I'd recommend using them sparingly as they can quickly become distracting.

Drawing Lines

In the section, I will show how to create a Shape object that represents a point on the map. The Shape constructor takes a parameter that describes the type of object and a point. If you want to draw lines, you'll need to select the type "Polyline" and provide more than one point. To construct a polyline Shape object, a list of points is needed, and a point is represented by a LatLongWithAltitude object.

C#
List<LatLongWithAltitude> points = new List<LatLongWithAltitude>();

Once this is populated, the Shape can be created:

C#
Shape result = new Shape(ShapeType.Polyline, points);

Alternatively, it is possible to defer the addition of the points until a later time by assigning them through the Points property.

Lines and Pushpins

One thing you have to be careful of when creating shapes that are lines (or polygons, but we'll come to that later on) is that by default, a pushpin is also displayed to go along with the line in order to give the user something to hover over so they can gain more information.

Lines with pushpins

If these pushpins are not desired, then the IconVisible property needs to be set to false.

C#
shape.IconVisible = false;

On the other hand, if a pushpin is desired for each line, then you can control where the pushpin appears. By default, they are somewhere along the middle of the line. The IconAnchor property can be set to the point at which the pushpin is to appear. For example, to set the pushpin to appear at the start of a line, use:

C#
shape.IconAnchor = shape.Points[0];

You can also do the other customizing of the pushpin, as I showed above.

Customizing the Line

There are many ways to customise the line as well. You can change the colour and width of the line on the Shape object.

Map with customised lines

The data in the example above is the rail services in Scotland, and includes information on the route, start and end stations, the length of the route, and the train franchise operator.

In the example, the visualization of the lines is dependent on two attributes. The train franchise operator is reflected in the colour of the lines, while the route distance is reflected in the width of the line. The shorter suburban routes are quite thin lines, while the intercity lines are much thicker.

The LineWidth property accepts the width in pixels of the line, while the LineColor property accepts a Color object (specifically from the Microsoft.Live.ServerControls.VE namespace). The Color object allows you to specify the standard red, green, and blue values (each 0-255) along with an alpha blend value (a double from 0 to 1.0).

Line Generalization

So far, this is pretty easy; however, what appears on the map isn't necessarily what you put into the Shape object. Virtual Earth generalizes the shape that you create, presumably to improve performance. I suspect the idea was to generalize in a way that the user wouldn't notice; however, in some situations, it is very obvious that the line is not displaying its original points.

Take a look at these two maps. They both display exactly the same data. One is just a zoomed in version of the other (I've enlarged the zoomed out version so they are the same size, to make them easier to compare).

Line Generalisation example 1Line Generalisation example 2

The map on the left shows the naturally zoomed in version. The one on the right shows the zoomed out version (which I then resized back so that both maps are the same size for this article).

Because central Scotland is quite busy and has a lot of rail routes, have a look at the routes in the Highlands (north of Scotland) to see this phenomenon more easily. Take the most northern route, for example. The map on the left shows it weaving in and out of the mountains reasonably clearly, while the map on the right shows the route slightly more straightened out. Also, the map on the right doesn't even appear to hit some of the points.

Drawing Polygons

Finally, the last Shape type is polygon. Like the polyline, it will also display pushpins by default. And, like the polyline, you can set the line width and colour which applies to the perimeter of the polygon.

As polygon datasets are very expensive in Scotland, I've just created simple rectangles to use as polygons in this example. The data represents the locations of attendees from a Scottish Developers user group event.

Polygons in Virtual Earth

There is really only one additional property that is available. That is FillColor. It also takes a Color object like the LineColor property.

C#
shape.FillColor = new Color(red, green, blue, alpha);

That is really it. There isn't that much more that can be said about polygons.

Summary

Virtual Earth is a powerful web based mapping tool, and in this article, I've concentrated on just one aspect of it, namely data visualization with Shape objects.

History

  • 1.0 Initial version (6th December 2008).

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)