Geoffrey Emery
Tech Goodness

Virtual Earth Web Services – Create A Map Image from a Latitude Longitude

January 23, 2009 07:37 by gemery

In this tutorial we are going to look at what you need to get a map from a  Lat Long(GeoCode)

First a picture of what the final project will look like.

image

Note:

You must!  change the username in the web.config

    <add key="VEUsername" value="YourKey"/>
    <add key="VEPassword" value="YourPassword"/>

with your own information

image

1) Learn about Tokens

Okay, so, first things first, you need to authenticate - see my post Authentication and Tokens with Virtual Earth for authentication.

2) Create  AJAX Website in VS

Now that you are dialed in with your virtual earth tokens we are going to dive right into the web services. Lets go ahead and create a web site in VS. I am going to spice this up a bit and make it Ajax enabled. So go ahead and install AJAX or if you are using VS2008 sp 1 you should be already cool. Through in a script manager down and a update panel, and a update progress manager down on the page. This is the web form should look like in between the body tags should look this now.

<asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
        <asp:UpdateProgress ID="UpdateProgress1" runat="server" AssociatedUpdatePanelID="UpdatePanel1" DisplayAfter="5">
           <ProgressTemplate>
              
           </ProgressTemplate>
       </asp:UpdateProgress>
       <asp:UpdatePanel ID="UpdatePanel1" runat="server">
           <ContentTemplate>
     
           </ContentTemplate>
       
       </asp:UpdatePanel>

 

3) Fill in the UI

The full default.aspx page

<%@ 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 id="Head1" runat="server">
    <title>Virtual Earth Web Services Imagery Map Creation Sample</title>
</head>
<body style="font-family:Arial; font-size:small">
    <form id="form1" runat="server">
    <div style="font-weight:bold">
        VE Web Services Imagery Map Creation Sample
    </div>
    <br />
    <div>
        <asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
        <asp:UpdateProgress ID="UpdateProgress1" runat="server" AssociatedUpdatePanelID="UpdatePanel1" DisplayAfter="20">
            <ProgressTemplate>
                <img alt="updatepannel" src="Images/Update.gif" />
            </ProgressTemplate>
        </asp:UpdateProgress>
        <asp:UpdatePanel ID="UpdatePanel1" runat="server">
            <ContentTemplate>
                Latitude: <asp:TextBox runat="server" ID="TextBox_Latitude" Width="125" />
                Longitude: <asp:TextBox runat="server" ID="TextBox_Longitude" Width="125" />
                Zoom Level: <asp:DropDownList runat="server" ID="DropDownList_ZoomLevel" 
                    onselectedindexchanged="DropDownList_ZoomLevel_SelectedIndexChanged" AutoPostBack="true" />
                <br />
 
                <table>
                    <tr>
                        <td>&nbsp;</td>
                        <td>
                            <asp:Image ID="Image_Map" runat="server" Height="432px" Width="585px" />
                            <br />
                        </td>
                        <td align="center">&nbsp;</td>
                    </tr>
                </table>
                
                <br />
                <div runat="server" id="Div_Info" />
                
            </ContentTemplate>
        
        </asp:UpdatePanel>
    
    </div>
    </form>
</body>
</html>

4) Add the token to the web.config

<appSettings>
<!--
  This username and password is supplied for demo purposes only.  Please do not use this account for 
  anything other than this demo.  This account is monitored very closely and will be deactivated if used improperly
  To get your own Virtual Earth account, go to https://mappoint-css.live.com/MwsSignup/.
-->
<add key="VEUsername" value="YourToken"/>
<add key="VEPassword" value="YourPassword"/>
 
appSettings>

5) Add the Utility Class

You can do this as you like. I like to keep it separate. This takes the userkey and passowrd out of the webconfig and news up a new VECredential for you

using System.Net;
using VEAuthenticationService;
using System.Text.RegularExpressions;
using System.Configuration;
    public static class Utils
    {
        private static string GetVEUsername() { return ConfigurationManager.AppSettings["VEUsername"].ToString(); }
        private static string GetVEPassword() { return ConfigurationManager.AppSettings["VEPassword"].ToString(); }
 
        public static string StripHTMLTags(string HtmlToStrip)
        {
            return Regex.Replace(HtmlToStrip, @"<(.|\n)*?>", string.Empty);
        }
 
        /// <summary>Returns a token from the Virtual Earth web service</summary>
        public static string Token(string ClientIP)
        {
            // This token will expire so that should be handled appropriately
            
                // Create a CommonService so we can make the request
                CommonService commonService = new CommonService
                {
                    // Supply your Virtual Earth credentials
                    // to get a Virtual Earth developer account, go to https://mappoint-css.live.com/MwsSignup/
                    Credentials = new NetworkCredential(Utils.GetVEUsername(), Utils.GetVEPassword())
                };
 
                // Create a token specification
                TokenSpecification tokenSpecification = new TokenSpecification
                {
                    // Token will expire in 60 minutes, max is 480 minutes
                    TokenValidityDurationMinutes = 60,
                    // Supply the client's IP address
                    ClientIPAddress = ClientIP
                };
                return commonService.GetClientToken(tokenSpecification);
          }
    }
 
 
 
 
 
 
 
 

6) Add the Update Image of your choice to to images folder for the update panel progress bar. –> this might make more sense after you download the project

7) add  your web service reference

Add a web service by right clicking on the project

image

Imagery Service

http://dev.virtualearth.net/webservices/v1/imageryservice/imageryservice.svc?wsdl

8) Add the Guts

Now we add the GUTS to the code behind of the default.aspx page

First I am going to load the page up with some default values for testing purposes

protected void Page_Load(object sender, EventArgs e)
    {
        if (Page.IsPostBack == false)
        {
            // Load some default data into the UI
 
            //Hotel Bonaventure, ( 34.052563, -118.256012 )
            //this.TextBox_Latitude.Text = "34.052563";
            //this.TextBox_Longitude.Text = "-118.256012";
 
            //Los Angeles Convention Center, ( 34.0404, -118.2688 )
            this.TextBox_Latitude.Text = "34.0404";
            this.TextBox_Longitude.Text = "-118.2688";
             
 
            //One Microsoft Way
            //this.TextBox_Latitude.Text = "47.64";
            //this.TextBox_Longitude.Text = "-122.13";
 
            for (int i = 1; i <= 20; i++)
                this.DropDownList_ZoomLevel.Items.Add(i.ToString());
            this.DropDownList_ZoomLevel.SelectedIndex = 18;     // Default the zoom level to 19
 
            // Load a default map
            this.RenderMap(Convert.ToDouble(this.TextBox_Latitude.Text),
                Convert.ToDouble(this.TextBox_Longitude.Text),
                Convert.ToInt32(this.DropDownList_ZoomLevel.SelectedValue));
        }
    }

Now for the fun stuff Getting the map from Microsoft

/// <summary>Renders and places a map image on the page</summary>
    /// <param name="centerLatitude">Latitude that the map should be centered on</param>
    /// <param name="centerLongitude">Longitude that the map should be centered on</param>
    /// <param name="zoomLevel">Zoom level of the map image</param>
    private void RenderMap(double centerLatitude, double centerLongitude, int zoomLevel)
    {
        Image mapImage = (Image)this.FindControl("Image_Map");
 
        // Create a new MapUriRequest
        VEImageryService.MapUriRequest mapUriRequest = new MapUriRequest();
         
        // Create a new Credential object and provide the token
        mapUriRequest.Credentials = new VEImageryService.Credentials();
        mapUriRequest.Credentials.Token = Utils.Token(Request.UserHostAddress);
 
        //Set the Center point for the imagery request
        mapUriRequest.Center = new VEImageryService.Location
        {
            Altitude = 0,
            Latitude = centerLatitude,
            Longitude = centerLongitude
        };
 
        // Set the size and ZoomLevel we want on the returned map
        mapUriRequest.Options = new MapUriOptions
        {
            // Specify the map size, we get this from the size of the image on the web page
            ImageSize = new VEImageryService.SizeOfint
            {
                Height = (int)mapImage.Height.Value,
                Width = (int)mapImage.Width.Value
            },
            // Set the ZoomLevel for the returned map
            ZoomLevel = (int)zoomLevel,
 
            //Set the Map Style (only road and aerial types are available)
            Style = MapStyle.AerialWithLabels
        };
 
        // Create a new ImageryServiceClient to make the service request
        ImageryServiceClient imageryServiceClient = new ImageryServiceClient();
 
        // Execute GetMapUri
        MapUriResponse mapUriResponse = imageryServiceClient.GetMapUri(mapUriRequest);
 
        // Display the map on the web page.
        mapImage.ImageUrl = mapUriResponse.Uri;
 
        // Write out the uri to the page
        this.WriteInfo("<b>Map uri: </b>" + mapUriResponse.Uri);
    }

And finally add a handler for when people change the zoom level and a small helper function

/// <summary>Event handler for the Zoom level drop down list, re-renders the map at the specified zoom level</summary>
   /// <param name="sender">The sender</param>
   /// <param name="e">Event arguments</param>
   protected void DropDownList_ZoomLevel_SelectedIndexChanged(object sender, EventArgs e)
   {
       this.RenderMap(Convert.ToDouble(this.TextBox_Latitude.Text),
           Convert.ToDouble(this.TextBox_Longitude.Text),
           Convert.ToInt32(this.DropDownList_ZoomLevel.SelectedValue));
   }
 
   /// <summary>Writes information to the UI</summary>
   /// <param name="html">HTML to write to the UI</param>
   protected void WriteInfo(string html)
   {
       this.Div_Info.InnerHtml += html + "<br/>\n";
   }

and Bam there you have a map coming at you from a longitude latitude. you need to do this from a address look at this example.

http://blog.geoffreyemery.com/post/Virtual-Earth-Web-Services----GeoCoding-and-Reverse-GeoCoding.aspx

After you geocode it you can then send in another request to get a map.

Download the code here.

image

  

Have fun!


Related posts

Comments are closed