Getting a Map with the Virtual Earth Web Service

The most basic element of Virtual Earth - maps. The Virtual Earth AJAX control is pretty simple because you could just copy and paste code into notepad, save it and run it in a browser. Well, the Virtual Earth Web Service (VEWS) is a bit of a different animal. It uses WCF and WSDL to specify service pointers of where you should be getting maps, directions, YP and Collections, and routes. I figured it would be helpful, what with my deep background in MapPoint Web Service which has a similar architecture, to provide some help on how the Virtual Earth Web Service works. So, over the next few weeks I'll post some (hopefully) helpful samples that will get you past some sticking points. We'll start with just getting a map. I should mention that because I work at Microsoft, these samples will be in ASP .Net (C#), so hopefully understanding the logic will help you translate to whatever language you're working with. If you only do JavaScript / Web Development, you're going to need some more books, because you have some learning to do.

With the VEWS, it is required that all users authenticate. So, you'll need to sign up for a developer account, then authenticate your usage with our HTTP Digest authentication scheme.

First thing we'll need to do is add the Imagery Service. This uses Windows Communication Foundation (WCF), which is "a set of .NET technologies for building and running connected systems. It is a new breed of communications infrastructure built around the Web services architecture. " Ohhh, scary. Uh, no. Basically, it makes it easier for you to not have to worry about where to make your service calls to.

Add the Imagery Service
You can add the imagery service in Visual Studio by going to Website | Add Service Reference and entering the imagery service URI into the address box, then hitting go. It should pull up the reference points in the service with two supported methods (aka Operations) - GetImageryMetaData() and GetMapUri(). Give it a name at the bottom - I named mine ImageryService.

image

Add New Web Form
You'll need a web page to contain your map, so add a web form to your project - Website | Add New Item | Web Form. I named mine Map.aspx.

Add Image to Your Web Form
VEWS returns the URI for a map image. So, you'll want to have an image placeholder there. Do this by dragging an image object from the toolbox onto your web form. You can resize it to the size you need by dragging the corners.

Authenticate
I'm not going to show you how to authenticate here, but I thought it important to point something out. Although this is a server request, the authentication still requires a token. That wouldn't be a challenge, but the token requires the user's IP so here's how to do it.

I create a class called "Authentication.cs"

In the class I put the authentication I wrote about in my Authentication and Tokens with Virtual Earth post except for one change.

Authentication.cs

using VEWSStaging;

/// <summary>
/// Authenticating for VE Tokens
/// </summary>
public class Authentication
{
public static string strVEWSToken;
public static string Authenticate(string strIP)
{
CommonService commonService = new CommonService();
commonService.Url = "https://common.virtualearth.net/find-30/common.asmx";
  commonService.Credentials = new System.Net.NetworkCredential("XXXX", "YYYY");

  // Create the TokenSpecification object to pass to GetClientToken.
TokenSpecification tokenSpec = new TokenSpecification();

  // Use the Page object to retrieve the end-client’s IPAddress.
tokenSpec.ClientIPAddress = strIP;

  // The maximum allowable token duration is 480 minutes (8 hours).
// The minimum allowable duration is 15 minutes.
tokenSpec.TokenValidityDurationMinutes = 480;

  // Now get a token from the Virtual Earth Platform Token service.
strVEWSToken = commonService.GetClientToken(tokenSpec);
return strVEWSToken;
}
}

We'll get the IP in the from the Maps.aspx page in the next step.

Requesting a Map
Now, I used most of the code from the SDK so it would help you longer term - teach a man to fish..... Also, I don't use error handling, so for production applications you definitely want to add checks. Here's the code that works for authenticating via my Authentication Class and passing the IP (UserHostAgent) to get the token (yes, token is required). I set the options for the map (center point, zoom level, map style, image height and image width) then request the URI for the map. You'll pass that URI down into the image you dropped on your web page, and you're done!

Map.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Map.aspx.cs" Inherits="Map" %>

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

<html xmlns="https://www.w3.org/1999/xhtml">
<head runat="server">
<title>VEWS Map</title>
</head>
<body>
<form id="form1" runat="server">
<div>
</div>
</form>
<asp:Image ID="Image1" runat="server" Height="480px" Width="600px" />
</body>
</html>

Map.aspx.cs

using System;
using System.Collections;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using ImageryService;

public partial class Map : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
string myToken = Authentication.Authenticate(Page.Request.UserHostAddress);
ImageryService.MapUriRequest myMapURIRequest = new MapUriRequest();
myMapURIRequest.Credentials = new ImageryService.Credentials();
myMapURIRequest.Credentials.Token = myToken;
myMapURIRequest.Center = new ImageryService.Location();
myMapURIRequest.Center.Latitude = 37.42196783438708;
myMapURIRequest.Center.Longitude = -122.084039747715;

  ImageryService.MapUriOptions myMapURIOptions = new ImageryService.MapUriOptions();

myMapURIOptions.Style = ImageryService.MapStyle.AerialWithLabels;
myMapURIOptions.ZoomLevel = 17;
myMapURIOptions.ImageSize = new ImageryService.SizeOfint();
myMapURIOptions.ImageSize.Height = (int)Image1.Height.Value;
myMapURIOptions.ImageSize.Width = (int)Image1.Width.Value;

  myMapURIRequest.Options = myMapURIOptions;

  ImageryService.ImageryServiceClient imageryService = new ImageryService.ImageryServiceClient();
ImageryService.MapUriResponse myMapURIResponse= imageryService.GetMapUri(myMapURIRequest);
string MapURI = myMapURIResponse.Uri;

  Image1.ImageUrl = MapURI;
}
}

I did this in the Page_Load method, but you can certainly request a map from any web form object and event. When it's all said and done, you get this lovely aerial photo with labels returned to you in .JPEG format and rendered onto a blank page. You'll want to just build your application around it as needed.

image

I've been getting the question recently about the advantages of VEWS over AJAX. Perhaps this is a post in and of itself, but from a feature perspective:

  1. VEWS (SOAP) is a server to service model (AJAX is client to service). This means you'll get the map image before your web page is sent to the client. You can control the image and ensure it's there before sending it down to the client.
  2. VEWS provides static images (on the fly), so you can insert them anywhere that support HTTP requests - mobile devices, JavaScript disabled browsers - or insert them into other documents such as PDFs.
  3. If you're using MapPoint Web Services, you can finally move over to a similar architecture with almost complete feature parody, but get the "pretty" maps and aerial photos.
  4. JavaScript is a lightweight scripting language which is great for fast web development, but for heavier applications requiring back end integration you can use VEWS with .Net, Java and any other language that works with HTTP.

SOAP is so clean.

CP