Geoffrey Emery
Tech Goodness

Virtual Earth Web Services - GeoCoding and Reverse GeoCoding

January 21, 2009 22:11 by gemery

In this tutorial we are going to look at what you need to go from a a Address to a Lat Long(GeoCode) and from a Lat Long to a Address(reverse 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 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 a blank AJAX project 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 blank project in VS

3) Add the UI

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. So go ahead and through 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>

4 ) Add page propeties

Now are going to add our table to the update content template

<table border="1">
                    <tr>
                        <td valign="top">
                            Address: <asp:TextBox runat="server" ID="TextBox_Address" Width="250" />
                            <br />
                            <asp:Button runat="server" Text="Geocode" ID="Button_Geocode" 
                                onclick="Button_Geocode_Click" />
                        </td>
                        <td>
                            Latitude: <asp:TextBox runat="server" ID="TextBox_Latitude" Width="250" />
                            <br />
                            Longitude: <asp:TextBox runat="server" ID="TextBox_Longitude" Width="250" />
                            <br />
                            <asp:Button runat="server" Text="Reverse Geocode" ID="Button_ReverseGeocode" 
                                onclick="Button_ReverseGeocode_Click" />
                        </td>
                    </tr>
                </table>
                <br />

then add a div we are going to inject our information that we get back from Virtual Earth

<div runat="server" id="Div_Info" />

 

5) Add a web reference to the VE Geocode Service

Now are going to add a web reference to the VE Geocode Service

This is the address at the time of writing this article


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

In our service refrence we now will have something that looks like this

image

Sweet that was easy.

6) Add a Utility class

Now that we have that we need to add a Utility class that will take our developer credentials and get us a token so we can start making requests against the web service api..

Here is a great  class for doing that.. I named it Utils.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Net;
using System.ServiceModel;
using VEWebServicesDemo.VEAuthenticationService;
using VEWebServicesDemo.VEGeocodeService;
using System.Configuration;
using System.Collections;
using System.Text.RegularExpressions;
 
namespace VEWebServicesDemo
{
    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);
          }
    }
}

Great so we have our auth service and we have our credentials class lets get into the fun stuff.

7) Give it Guts

Now have our front end our data access layer lets set up the middlish tier

First thing I am going to do is load up the page with some default values in the page_load so that when i demo this it I can click and show .

protected void Page_Load(object sender, EventArgs e)
   {
       // Set a default address to search for.
       if (this.IsPostBack == false)
       {
           // Default for the address box
           this.TextBox_Address.Text = "1313 S Figueroa St, Los Angeles, California 90015, United States";
 
           //LACC
           this.TextBox_Latitude.Text = "34.0404";
           this.TextBox_Longitude.Text = "-118.2688";
 
       }
   }

 

Next I am going to add functionality to the button to get a gecode from a address all information on the function are in the comments

/// <summary>Geocodes the address specified in the UI</summary>
       /// <param name="sender">The sender</param>
       /// <param name="e">Event arguments</param>
       protected void Button_Geocode_Click(object sender, EventArgs e)
       {
           // Clear any existing data from our div
           this.Div_Info.InnerHtml = "";
 
           GeocodeRequest geocodeRequest = new GeocodeRequest();
           
           // Create a new Credential object and provide the token
           geocodeRequest.Credentials = new VEGeocodeService.Credentials();
           geocodeRequest.Credentials.Token = Utils.Token(Request.UserHostAddress);
 
           // Set the address from the UI on the request
           geocodeRequest.Query = this.TextBox_Address.Text.Trim();
 
           // Create a new geocode client
           GeocodeServiceClient geocodeServiceClient = new GeocodeServiceClient();
 
           // Execute the geocode request
           GeocodeResponse geocodeResponse = geocodeServiceClient.Geocode(geocodeRequest);
 
           // Iterate through each of the results and send write some data to the UI
           foreach (GeocodeResult geocodeResult in geocodeResponse.Results)
           {
               this.WritePair("Formatted Address", geocodeResult.Address.FormattedAddress);
               this.WritePair("Display Name", geocodeResult.DisplayName);
               this.WritePair("Confidence", geocodeResult.Confidence.ToString());
 
               // Iterate through each location within the result and send back the Lat/Long
               foreach (GeocodeLocation geocodeLocation in geocodeResult.Locations)
               {
                   this.WritePair("Calculation Method", geocodeLocation.CalculationMethod);
                   this.WritePair("Longitude", geocodeLocation.Latitude.ToString());
                   this.WritePair("Latitude", geocodeLocation.Longitude.ToString());
               }
               this.WriteInfo("");
           }
       }

I am going to add the reverse geocode functionality

 

/// <summary>Reverse geocodes the latatitude and longitude specified in the UI</summary>
        /// <param name="sender">The sender</param>
        /// <param name="e">Event arguments</param>
        protected void Button_ReverseGeocode_Click(object sender, EventArgs e)
        {
            // Clear any existing data from our div
            this.Div_Info.InnerHtml = "";
 
            //Create a new ReverseGeoCode Request object
            ReverseGeocodeRequest reverseGeocodeRequest = new ReverseGeocodeRequest();
 
            // Create a new Credential object and provide the token
            reverseGeocodeRequest.Credentials = new VEGeocodeService.Credentials();
            reverseGeocodeRequest.Credentials.Token = Utils.Token(Request.UserHostAddress);
 
            //New a VEGeocode Location object and set it's properties
            reverseGeocodeRequest.Location = new Location
            {
                Latitude = Convert.ToDouble(this.TextBox_Latitude.Text),
                Longitude = Convert.ToDouble(this.TextBox_Longitude.Text)
            };
 
            // New up a new GeocodeServiceClient to make our request with
            GeocodeServiceClient geocodeServiceClient = new GeocodeServiceClient();
 
            // Execute the ReverseGeocode request
            GeocodeResponse geocodeResponse = geocodeServiceClient.ReverseGeocode(reverseGeocodeRequest);
 
            // Write out the response information to the UI
            foreach (GeocodeResult geocodeResult in geocodeResponse.Results)
            {
                this.WritePair("Display Name", geocodeResult.DisplayName);
                this.WritePair("Entity Type", geocodeResult.EntityType);
                this.WritePair("Confidence", geocodeResult.Confidence.ToString());
                this.WritePair("Address Line", geocodeResult.Address.AddressLine);
                this.WritePair("Locality (city)", geocodeResult.Address.Locality);
                this.WritePair("Admin District (state)", geocodeResult.Address.AdminDistrict);
                this.WritePair("Postal Code", geocodeResult.Address.PostalCode);
                this.WriteInfo("");
            }
        }

 

A couple of little helper functions

// <summary>Writes a name/value pair to the UI, name is bolded.</summary>
        /// <param name="name">Name of the name/value pair</param>
        /// <param name="value">Value of the name/value pair</param>
        protected void WritePair(string name, string value)
        {
            this.WriteInfo("<B>" + name + ":</B> " + value);
        }
 
        /// <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 we have a working demo. 7 Steps to Virtual Earth Web Services.

Here is a shot of the what the reverse geocode spits out

image 

image

Have Fun!


Related posts

Comments

July 29. 2009 08:46

Prakash

Hai i have followed your guidelines, but it is not working
where is CommonService and TokenSpecification Class created.

Prakash

September 9. 2009 04:42

george

in reverse geocode code you say:
"GeocodeResponse geocodeResponse = geocodeServiceClient.ReverseGeocode(reverseGeocodeRequest);"
where do you find ReverseGeocode? Because I can only find ReverseGeocodeAsync. And I get an error "cannot implicitly conert type void to GeocodeResponse".
Also in the Utils.cs you say "CommonService commonService = new CommonService" where do u find CommonService? I had to use CommonServiceSoapClient..
Thanks.

george

October 17. 2009 10:12

Equity Indexed Annuities

I like these code and your guild lines. Cheers.

Equity Indexed Annuities

October 20. 2009 02:29

how to beat a drug test

Now this is hghly recommeded post for me. I will surely email this to my friend.


Regards

Adom

how to beat a drug test

October 23. 2009 03:25

buy aion account

I bookmarked your post will read this latter


Regards

hops kalis

buy aion account

October 23. 2009 04:50

buy aion online gold

I posted your article to my myspace profile.


Regards

smith

buy aion online gold

October 24. 2009 04:17

Holiday Rentals Costa del Sol

Useful information shared..Iam very happy to read this article..thanks for giving us nice info.Fantastic walk-through. I appreciate this post

Holiday Rentals Costa del Sol

October 24. 2009 19:28

Cheap Aion kinah

I loved the way you exlained things. Much better many here


Regards

krich off

Cheap Aion kinah

October 24. 2009 21:40

aion gold

Hi nice site design


Regards

barry

aion gold

November 1. 2009 00:06

personal loans

Do you have any more info on this?

personal loans

November 5. 2009 05:36

payday loans

Like your writing! Still you can do some things to improve it.

payday loans

November 9. 2009 08:22

bladder infection symptoms

The blog was absolutely fantastic! Lots of great information and inspiration, both of which we all need!

bladder infection symptoms

November 9. 2009 10:17

Symptoms Of Panic Attacks

Your blog is extremely informational and for someone who really does not understand code too easily; I seem to understand your post. Just wanted to say thanks for this information.

Symptoms Of Panic Attacks

November 9. 2009 12:45

pay day loans

I just hope to have understood this the way it was meant

pay day loans

November 10. 2009 03:01

cash loans

Hmmm interesting stuff

cash loans

November 11. 2009 05:18

wow quest helper

I admire the valuable information you offer in your articles. I will bookmark your blog and have my children check up here often. I am quite sure they will learn lots of new stuff here than anybody else!

wow quest helper

Comments are closed