by Raj Rao
I had created a Google Maps web-page that loaded data from a database using web-services: Denver Traffic Cameras. This post is a tutorial on how to create such a page (its basically a tutorial on how to create a web-service which can be called from java-script and then continues on to show you how to use it with the Virtual Earth map control). Why is this important? Because once you can pass data from the server down to the browser, you can pull data from your database and use it to populate the VE map. (Or for that matter any other browser based map control). The possibilities are endless.
note: the source code can be downloaded from - http://www.aggregatedintelligence.com/Samples/VEandWS/VEandWS.zip
1. Create an ASP.Net web site.
I used VS 2008 and .Net framework 3.5. If you use .Net 2.0, then you will need to install the MS AJAX framework for this to work. (Ajax libraries come installed with .Net 3.0 and above)
2. Create a web-service (extension should be ASMX)

This will add an ASMX file, as well as a cs file in the app_code folder. The cs file implements the web-service and the ASMX file allows the web-service to be referenced by JavaScript. (Call it WebService.asmx, so that it is easy for you to follow my code).
3. Add the attribute “[System.Web.Script.Services.ScriptService]” on the web-service.
This is required so that the service can be called from JavaScript.
4. Add a ScriptManager to the web-page.
Next, in the aspx file (called default.aspx in my example), drag a ScriptManager from the toolbox onto the page (this is the page where you will use the web-service). The script manager is required for AJAX support on the page and will allow us to reference the web-service. To add a reference to the web-service, you need to modify the script manager control so that it looks like the following code:
<asp:ScriptManager ID="ScriptManager1" runat="server">
<Services><asp:ServiceReference Path="~/WebService.asmx" /></Services>
</asp:ScriptManager>
5. Add a web-service method
The web-service file that was added to the App_Code folder will contain a basic implementation of a method that can be called from JavaScript and should be called “HelloWorld”. If not, add the following code to the web-service class.
[WebMethod]
public string HelloWorld() {
return "Hello World";
}
6. Call the web-service from the web-page
Next, add the following code to the <head> section of the aspx file (this code contains the call-back function that will be called when we call the HelloWorld web service method).
<script type="text/javascript">
// This is the callback function that
// processes the Web Service return value.
function SucceededCallback(callBackValue)
{
var RsltElem = document.getElementById("divReturnCall");
RsltElem.innerHTML = callBackValue;
}
</script>
Finally, in the <body><form> section of the ASPX page, add the following code, which adds a button (whose on-click handler, calls the web-service method “HelloWorld”) and a div element that will be used to display the return value from the web-service.
<input type="button" onclick="WebService.HelloWorld(SucceededCallback)" value="Call Web Service" />
<div id="divReturnCall">
</div>
Now when you run this page, you will see a button, which when clicked, will update the div with the text that is returned by the HelloWorld web-service method.
7. Update the code, so that the web-service returns an object
Next, we will add a class that we will use to return data via the web-service.
Add the following code to the webservice.cs file (after the definition for the WebService class):
public class MyWebServiceData
{
private string _description ="Hello World";
public string Description
{
get { return _description; }
set { _description = value; }
}
}
8. Update the web-page code to handle the object that is being returned:
Next update the SucceededCallback in the default.aspx page with the following code:
function SucceededCallback(callBackValue)
{
var RsltElem = document.getElementById("divReturnCall");
RsltElem.innerHTML = callBackValue.Description;
}
The code now uses the Description property on the returned value to update the web-page.
9. Introduce Virtual Earth into the page
Now, lets add a Virtual Earth map control to the page.
In the <head> add a reference to the VE javascript file:
<script type="text/javascript" src="http://dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=6.2"></script>
Also add the following code to the in the script section of the page containing the SucceededCallback method.
var map = null;
function GetMap() {
map = new VEMap('myMap');
map.LoadMap();
map.SetCenterAndZoom(new VELatLong(39.729466, -104.982005), 10);
}
In the <body> section of the page, add a div with ID “myMap” that will contain the map.
<div id='myMap' style="position:relative; width:500px; height:500px;"></div>
Finally, add the onLoad event to the <body> of the page (the onLoad event will call the method which will load the VE map into the page)
Your page should now look like this:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<!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 runat="server">
<title></title>
<script type="text/javascript" src="http://dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=6.2"></script>
<script type="text/javascript">
// This is the callback function that
// processes the Web Service return value.
function SucceededCallback(callBackValue)
{
var RsltElem = document.getElementById("divReturnCall");
RsltElem.innerHTML = callBackValue.Description;
}
var map = null;
function GetMap() {
map = new VEMap('myMap');
map.LoadMap();
map.SetCenterAndZoom(new VELatLong(39.729466, -104.982005), 10);
}
</script>
</head>
<body onload="GetMap()">
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server">
<Services><asp:ServiceReference Path="~/WebService.asmx" />
</Services>
</asp:ScriptManager>
<div id='myMap' style="position:relative; width:500px; height:500px;"></div>
<div id="divReturnCall"></div>
<input type="button" onclick="WebService.HelloWorld(SucceededCallback)" value="Call Web Service" />
</form>
</body>
</html>
Test the page out: When the page loads, it should show you the Virtual Earth map centered over Denver.
10. Update the web-service so that it returns objects that contain push-pin information:
The web-service needs to return an array of objects which will contain the location information (latitude,longitude) of the push-pins to be added to the web-page.
Change the code for “MyWebServiceData” so that it has properties for all the information needed to create a push-pin (latitude, longitude, title and description):
public class MyWebServiceData
{
public string Description {get;set;}
public double Latitude { get; set; }
public double Longitude { get; set; }
public string Title { get; set; }
public MyWebServiceData(string title, string description, double lat, double lon)
{
Title = title;
Description = description;
Latitude = lat;
Longitude = lon;
}
}
Also, update the HelloWorld web-service method so that it returns an array of the MyWebServiceData objects: (I have prefilled it with push-pins of a couple of landmarks in Denver)
[WebMethod]
public MyWebServiceData[] HelloWorld()
{
MyWebServiceData[] cv = new MyWebServiceData[2];
cv[0] = new MyWebServiceData("Push pin 1", "City and County of Denver", 39.740755, -104.990201);
cv[1] = new MyWebServiceData("Push pin 2", "Colorado State Capitol", 39.739336, -104.984858);
return cv;
}
11. Update the web-page, so that it can take advantage of the push-pin information that the web-service now returns.
In the ASPX file, update the <script> in the web-page to the following code:
<script type="text/javascript">
// This is the callback function that
// processes the Web Service return value.
function SucceededCallback(callBackValue) {
//send the data to the AddPushpin method
AddPushpin(callBackValue);
var RsltElem = document.getElementById("divReturnCall");
RsltElem.innerHTML = "Pushpins have been loaded";
}
var map = null;
function GetMap() {
map = new VEMap('myMap');
map.LoadMap();
map.SetCenterAndZoom(new VELatLong(39.739039, -104.988613), 15);
}
function AddPushpin(callBackData) {
//load the data from callBackData in VEShape objects and load into the map, but first clear the old pushpins
map.DeleteAllShapes();
for (i = 0; i < callBackData.length; i++) {
var shape = new VEShape(VEShapeType.Pushpin, new VELatLong(callBackData[i].Latitude, callBackData[i].Longitude));
shape.SetTitle(callBackData[i].Title);
shape.SetDescription(callBackData[i].Description);
map.AddShape(shape);
}
}
</script>
The code, adds a method called “AddPushpin”, which creates and adds the pushpins sent back by the web-service. The AddPushpin method is called from the call-back method “SucceededCallBack”, which updates the old div “divReturnCall”, with a success method, once the push-pins have been added.
Now, when you click the button, the web-service method “HelloWorld” gets called, which returns an array of pushpin objects. The returned objects are sent to the call-back method “SucceededCallBack”, which passes it along to AddPushpin, where the code iterates over the array, adding each contained object as a push-pin.

Further things to do:
Now that I have shown you how to use a web-service with the Virtual Earth map control, you can modify the web-service method “HelloWorld” to return data from a database. This will allow you to customize your site easily.
You can also swap out the Virtual Earth control and instead use the Google Maps control.
Downloads:
The solution can be downloaded from: http://www.aggregatedintelligence.com/Samples/VEandWS/VEandWS.zip
Reference: