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).
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.
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)
<body onload="GetMap()">
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:
- Virtual Earth SDK reference: http://dev.live.com/virtualearth/sdk/
- Virtual Earth Dev site: http://dev.live.com/virtualearth/
- Virtual Earth Tools for Visual Studio: http://dev.live.com/tools/ (This is an alternate way to use VE Maps in your ASP.Net app. It provides you with a server side VE Map control, which means that you can load it with data in your server side code).
- VE intellisense for Visual Studio 2008: http://www.codeplex.com/VEJS (This will make your life extremely easy to work with the VE map control, as it provides you with intellisense inside Visual Studio).
Great article i was use it on my current project.
ReplyDeleteRajnish
http://ignou-student.blogspot.com
Excellent work.. and great explanations..
ReplyDeleteGreat article!!...
ReplyDeleteI have one interesting question...
What will i need to do to adapt this code to work with the Bing Silverlight Control?
Thanks
Just a quick note.
ReplyDeleteIf you plan on loading a bunch of points on the client side you may want to load them into an array of shapes and then add them all at once. Helps speed things up a bit.
Excellent tutorial
ReplyDelete