Geoffrey Emery
Tech Goodness

Amazon Announces Map Reduce To Allow Bid Data To Get Crunched in the cloud

April 2, 2009 10:26 by Geoffrey Emery

 

Amazon announced the beta availability of Elastic MapReduce, which is essentially an automated Hadoop deployment.

Amazon Elastic MapReduce is a web service that enables businesses, researchers, data analysts, and developers to easily and cost-effectively process vast amounts of data. It utilizes a hosted Hadoop framework running on the web-scale infrastructure of Amazon Elastic Compute Cloud (Amazon EC2) and Amazon Simple Storage Service (Amazon S3).

While I am sure there are folks who will find this very useful, I am hoping it is just the start.

There are some really good applications/frameworks available today that have been written to be scalable services such as CouchDb and Solr. While it is possible for individuals and businesses to host these kinds of applications on the EC2 (and other places) on their own, there is a significant opportunity for others to automate the process.

While there is more to it, in a nutshell, what I would be looking for:

  • Click button deployment (maybe with an optional IP address/domain name)
  • Reporting (how much data and resources am I consuming)
  • Very easy growth (more click buttons and maybe even automation)
  • All backups (if necessary/) and other related maintenance to just work.

An early example of this is FathomDB. FathomDB is essentially an automated/managed MySQL in the cloud. Just tell it (via a slider) your data needs and it does the rest.

We really are getting closer to building applications by simply composing a set of (already hosted) third party services.


FREE Public Data Sets On AWS = Free Data For You BI Cube

April 1, 2009 11:46 by gemery

amazon web services Public Data Sets on AWS provides a centralized repository of public data sets that can be seamlessly integrated into AWS cloud-based applications. AWS is hosting the public data sets at no charge for the community, and like all AWS services, users pay only for the compute and storage they use for their own applications. An initial list of data sets is already available, and more will be added soon.

Previously, large data sets such as the mapping of the Human Genome and the US Census data required hours or days to locate, download, customize, and analyze. Now, anyone can access these data sets from their Amazon Elastic Compute Cloud (Amazon EC2) instances and start computing on the data within minutes. Users can also leverage the entire AWS ecosystem and easily collaborate with other AWS users. For example, users can produce or use prebuilt server images with tools and applications to analyze the data sets. By hosting this important and useful data with cost-efficient services such as Amazon EC2, AWS hopes to provide researchers across a variety of disciplines and industries with tools to enable more innovation, more quickly.

How It Works

Select public data sets are hosted on Amazon EC2 for free as Amazon Elastic Block Store (Amazon EBS) snapshots. Amazon EC2 customers can access this data by creating their own personal Amazon EBS volumes, using the public data set snapshots as a starting point. They can then access, modify and perform computation on these volumes directly using their Amazon EC2 instances and just pay for the compute and storage resources that they use. If available, researchers can also use pre-configured Amazon Machine Images (AMIs) with tools like Inquiry by BioTeam to perform their analysis.

To get started using the Public Data Sets on AWS, simply perform these three easy steps:

  1. Sign up for an Amazon EC2 account.
  2. Launch an Amazon EC2 instance.
  3. Create an Amazon EBS volume using the Snapshot ID listed in the catalog above for your chosen snapshot.

The ElasticFox Getting Started Guide provides a simple walkthrough of how to launch an instance and create an Amazon EBS volume using ElasticFox, a convenient FireFox plug-in. Or, see the Amazon EC2 Getting Started Guide

Types

BIOLOGY

  • Annotated Human Genome Data provided by ENSEMBL
    An annotated form of the Human Genome, perfect for biological research, which was released as of December 10, 2008. The first snapshot, called the main Ensembl data, includes human and approximately 40 other species (see www.ensembl.org for a list) as well as comparative genomics data (550GB). The second snapshot, called the Ensembl Biomart, is a denormalized, query-optimized database that facilitates complex queries of one or more datasets (172GB).
    • Main Ensembl (Linux/UNIX): snap-c78360ae
    • Ensembl BioMart (Linux/UNIX): snap-c48360ad
  • GenBank provided by the National Center for Biotechnology Information
    An annotated collection of all publicly available DNA sequences including more than 85.7B bases and 82.8M sequence records (250GB)
    • Linux/UNIX: snap-e249a38b (updated 03/20/2009)
  • UniGene provided by the National Center for Biotechnology Information
    A set of transcript sequences of well-characterized genes and hundreds of thousands of expressed sequence tags (EST), last updated as of December 9, 2008. (10 GB)
    • Linux/UNIX: snap-5ad83b33
    • Windows: snap-60d83b09

CHEMISTRY

  • A 3D Version of the PubChem Library provided by Rajarshi Guha at Indiana University
    A 3D (single conformer) version of Pubchem, a public database of chemical structures in SD Format (70 GB)
    • Linux/UNIX: snap-a8dd3dc1
    • Windows: snap-40dd3d29
  • UGI Virtual Conformer Library provided by Rajarshi Guha at Indiana University
    80GB of data in SD format on conformers for 500,000 molecules that can be used for virtual screening (85 GB)
    • Linux/UNIX: snap-59d33330
    • Windows: snap-48ce2r21
  • PubChem Library provided by by the National Center for Biotechnology Information
    A data set of information on the biological activities of small molecules (230 GB)
    • Linux/UNIX: snap-e6df3c8f
    • Windows: snap-63d83b0a

ECONOMICS

  • Various US Census Databases provided by The US Census Bureau
    United States demographic data from the 1980 (2 GB), 1990 (50 GB), and 2000 US Censuses (200GB), summary information about Business and Industry (15 GB), and 2003-2006 Economic Household Profile Data (220 GB)
    • 2000 US Census (Linux/UNIX): snap-92d333fb
    • 2000 US Census (Windows): snap-36ce2e5f
    • 1990 US Census (Linux/UNIX): snap-33f8185a
    • 1990 US Census (Windows): snap-8cf818e5
    • 1980 US Census (Linux/UNIX): snap-9df717f4
    • 1980 US Census (Windows): snap-b6f818df
    • 2003-2006 Economic Data (Linux/UNIX): snap-0bdf3f62
    • 2003-2006 Economic Data (Windows): snap-4edd3d27
    • Business and Industry Summary Data (Linux/UNIX): snap-5cf81835
    • Business and Industry Summary Data (Windows): snap-8af818e3
  • Various Labor Statistics Databases provided by The Bureau of Labor Statistics
    Statistics on Inflation & Prices, Employment, Unemployment, Pay & Benefits, Spending & Time Use, Productivity, Workplace Injuries, International Comparisons, Employment Projections, and Regional Resources (15 GB)
    • Linux/UNIX: snap-30f81859
    • Windows: snap-8df818e4
  • Various Transportation Databases provided by The Bureau of Transportation Services
    Data and statistics from the US Department of Transportation on Aviation, Maritime, Highway, Transit, Rail, Pipeline, Bike/Pedestrian and other modes of transportation (15 GB)
    • Linux/UNIX: snap-e1608d88
    • Windows: snap-37668b5e

ENCYCLOPEDIC

  • DBpedia Knowledge Base provided by DBpedia.
    DBpedia is a community effort to extract structured information from Wikipedia and to make this information available on the Web. The DBpedia knowledge base currently describes more than 2.6 million things, including at least 213,000 persons, 328,000 places, 57,000 music albums, 36,000 films, 20,000 companies. The knowledge base consists of 274 million pieces of information (RDF triples). It features labels and short abstracts for these things in 30 different languages; 609,000 links to images and 3,150,000 links to external web pages; 4,878,100 external links into other RDF datasets, 415,000 Wikipedia categories, and 75,000 YAGO categories (67GB).
    Semantic extraction by DBpedia with contributions from the DBpedia Community, using data from Wikipedia.org. Snapshots prepared by the infochimps.org team using community curated metadata. Released under the GNU Free Documentation License.
    • Linux/UNIX: snap-63cf3a0a (updated 03/20/2009)
    • Windows: snap-09b75e60
  • Freebase Data Dump provided by Freebase.com.
    A data dump of all the current facts and assertions in the Freebase system. Freebase is an open database of the world’s information, covering millions of topics in hundreds of categories. Drawing from large open data sets like Wikipedia, MusicBrainz, and the SEC archives, it contains structured information on many popular topics, including movies, music, people and locations – all reconciled and freely available. This information is supplemented by the efforts of a passionate global community of users who are working together to add structured information on everything from philosophy to European railway stations to the chemical properties of common food ingredients. For more answers check the Freebase FAQ (26GB).
    Data aggregated, processed and reconciled by freebase.com using data from Wikipedia.org, the freebase community, and many other open data sets. Snapshots prepared by the infochimps.org team using community curated metadata. Released under Creative Commons Attribution (CC-BY) license and the Freebase Terms of Service and Licensing Policy.
    • Linux/UNIX: snap-86c93cef (updated 03/20/2009)
    • Windows: snap-ab957cc2
  • Wikipedia Extraction (WEX) provided by Freebase.com.
    The Freebase Wikipedia Extraction (WEX) is a processed dump of the English language Wikipedia. The wiki markup for each article is transformed into machine-readable XML, and common relational features such as templates, infoboxes, categories, article sections, and redirects are extracted intabular form. Freebase WEX is provided as a set of database tables in TSV format for PostgreSQL, along with tables providing mappings between Wikipedia articles and Freebase topics, and corresponding Freebase Types (66GB.
    Semantic extraction by freebase.com, using data from Wikipedia.org. Snapshots prepared by the infochimps.org team using community curated metadata. Released under the GNU Free Documentation License.
    • Linux/UNIX: snap-1781757e (updated 03/20/2009)
    • Windows: snap-a6957ccf

 

 


Virtual Earth Web Service – Get your search on

January 23, 2009 08:28 by gemery

In this tutorial we are going to look at what you need to get search going using virtual earth web services. Search provides a robust way to find local businesses and attractions around a given location.

 

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>VE Web Services Search Sample</title>
</head>
<body style="font-family:Arial; font-size:small">
    <form id="form1" runat="server">
    <div style="font-weight:bold">
        Virtual Earth Web Services Search 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>
                <table>
                    <tr>
                        <td>What:</td>
                        <td><asp:TextBox runat="server" ID="TextBox_What" Width="250" /></td>
                    </tr>
                    <tr>
                        <td>Where:</td>
                        <td><asp:TextBox runat="server" ID="TextBox_Where" Width="250" /></td>
                    </tr>
                    <tr>
                        <td></td>
                        <td align="right">
                            <asp:Button runat="server" Text="Search and show map" ID="Button_SearchWithMap" 
                                onclick="Button_SearchWithMap_Click" />
                        </td>
                    </tr>
                </table>
 
                <table>
                    <tr>
                        <td>
                            <div runat="server" id="Div_SearchResults" style="width:300px; height:400px; overflow:auto"></div>
                        </td>
                        <td>
                            <asp:Image runat="server" ID="Image_Map" Visible="false" Height="400" Width="400" />
                        </td>
                    </tr>
                </table>
            </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 user key and password out of the web.config 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

Geocode Service

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

Imagery Service

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

Search Service

http://staging.dev.virtualearth.net/webservices/v1/searchservice/searchservice.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

Now for the fun stuff Getting the map from Microsoft

protected void Page_Load(object sender, EventArgs e)
 {
     if (Page.IsPostBack == false)
     {
         this.TextBox_What.Text = "Coffee Shops";
         this.TextBox_Where.Text = "Fullerton California";
     }
 }

 

protected void Page_Load(object sender, EventArgs e)
  {
      if (Page.IsPostBack == false)
      {
          this.TextBox_From.Text = "State College Blvd , Fullerton, CA 92831";
          this.TextBox_To.Text = "Golden Gate Bridge";  //Safeco Field
      }
  }

 

And finally add a handler for the button click there are a ton of comments in here so ill those be your guide feel to ping me with more questions plus down load the code and run it is the best way to go.

 

Start our search request

/// <summary>Executes a search with the what and where supplied in the UI</summary>
    /// <returns>SearchResponse for the executed search</returns>
    protected SearchResponse ExecuteSearch()
    {
        // Create a SearchRequest with a StructuredQuery
        SearchRequest searchRequest = new SearchRequest();
        searchRequest.Credentials = new VESearchService.Credentials();
        searchRequest.Credentials.Token = Utils.Token(Request.UserHostAddress);
 
        //Create a structured Search Query object
        VESearchService.StructuredSearchQuery structuredQuery = new StructuredSearchQuery();
        structuredQuery.Keyword = this.TextBox_What.Text.Trim();
        structuredQuery.Location = this.TextBox_Where.Text.Trim();
 
        searchRequest.StructuredQuery = structuredQuery;
 
        // Execute the search
        SearchServiceClient searchServiceClient = new SearchServiceClient();
        SearchResponse searchResponse = searchServiceClient.Search(searchRequest);
 
        return searchResponse;
    }

Now add the search results to a map!

/// <summary>Executes a search and creates a map that displays the search results.</summary>
  /// <param name="sender">The sender</param>
  /// <param name="e">Event arguments</param>
  protected void Button_SearchWithMap_Click(object sender, EventArgs e)
  {
      // Clear our results output
      this.Div_SearchResults.InnerHtml = "";
 
      // Execute a search
      SearchResponse searchResponse = this.ExecuteSearch();
      bool foundSearchResult = false;
 
      // Create a map, specify search results with the map request so pushpins will be rendered on the map
      if (searchResponse != null)
      {
          // 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 size of the map requested to the size of the image control
          mapUriRequest.Options = new MapUriOptions
          {
              ImageSize = new VEImageryService.SizeOfint
              {
                  Height = Convert.ToInt32(this.Image_Map.Height.Value),
                  Width = Convert.ToInt32(this.Image_Map.Width.Value)
              }
          };
 
          // Create a new pushpin list
          List<VEImageryService.Pushpin> pushpinList = new List<Pushpin>();
 
          // Add each of the search results to the pushpin list
          foreach (SearchResultSet searchResultSet in searchResponse.ResultSets)
          {
              int businessCounter = 0;
              foreach (BusinessSearchResult busniessSearchResult in searchResultSet.Results)
              {
                  foundSearchResult = true;
 
                  // Write the search result data to the info box
                  this.WriteInfo(++businessCounter + ") <b>" + busniessSearchResult.Name + "</b>");
                  this.WriteInfo("&nbsp;&nbsp;&nbsp;&nbsp;" + busniessSearchResult.Address.FormattedAddress);
                  string website = "";
                  if (busniessSearchResult.Website != null)
                      website = "<a href='" + busniessSearchResult.Website.ToString() + "'>Website</a>";
                  this.WriteInfo("&nbsp;&nbsp;&nbsp;&nbsp;" + busniessSearchResult.PhoneNumber + "&nbsp;&nbsp;&nbsp;&nbsp;" + website);
                  this.WriteInfo("");
 
                  // Build out the pushpin and add it to the list
                  Pushpin pushpin = new Pushpin();
                  // push pin labels only support 2 characters
                  pushpin.Label = businessCounter.ToString(); // += "asdf";
 
                  // Just get the first location returned
                  if (busniessSearchResult.LocationData.Locations.Length > 0)
                  {
                      //this.WriteInfo("Location: " + busniessSearchResult.LocationData.Locations[0].Latitude + "," + busniessSearchResult.LocationData.Locations[0].Longitude);
                      pushpin.Location = new VEImageryService.Location();
                      pushpin.Location.Latitude = busniessSearchResult.LocationData.Locations[0].Latitude;
                      pushpin.Location.Longitude = busniessSearchResult.LocationData.Locations[0].Longitude;
                  }
 
                  pushpinList.Add(pushpin);
              }
          }
 
          // Add the pushpin list (as an array) to the MapUriRequest
          mapUriRequest.Pushpins = pushpinList.ToArray();
          ImageryServiceClient imageryServiceClient = new ImageryServiceClient();
 
          // Get the map and render it on the UI
          MapUriResponse mapUriResponse = imageryServiceClient.GetMapUri(mapUriRequest);
          this.Image_Map.ImageUrl = mapUriResponse.Uri;
          this.Image_Map.Visible = true;
      }
 
      if (foundSearchResult == false)
          this.WriteInfo("No search results for query");
  }

One Little helper function

/// <summary>Writes information to the UI</summary>
 /// <param name="html">HTML to write to the UI</param>
 protected void WriteInfo(string html)
 {
     this.Div_SearchResults.InnerHtml += html + "<br/>\n";
 }

 

Bam there you have Search with map imagery of where everything is.

There is a ton more information that you can pull out of the objet I kept to just a few things for simplicity.

Download the code here.

image

One Last look at the finished Product

image

 

 

 

 

 

 

 

 


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!


Virtual Earth Web Service – Get Routing information

January 22, 2009 08:01 by gemery

In this tutorial we are going to look at what you need to get Routing information from a start and end point and then display them.

 

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>Vritual Earth Web Services Route Sample</title>
</head>
<body style="font-family:Arial; font-size:small">
    <form id="form1" runat="server">
    <div style="font-weight:bold">
        Vritual Earth Web Services Route 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>
                <table>
                    <tr>
                        <td>From Address:</td>
                        <td><asp:TextBox runat="server" ID="TextBox_From" Width="250" /></td>
                    </tr>
                    <tr>
                        <td>To Address:</td>
                        <td><asp:TextBox runat="server" ID="TextBox_To" Width="250" /></td>
                    </tr>
                    <tr>
                        <td></td>
                        <td align="right">
                            <asp:Button runat="server" Text="Get Directions" ID="Button_GetDirections" onclick="Button_GetDirections_Click" />
                        </td>
                    </tr>
                </table>
                <br />
 
                <div runat="server" id="Div_Directions" />
                <br />
                <asp:Image runat="server" ID="Image_Map" Visible="false" />
            </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 user key and password out of the web.config 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

image

Geocode Service

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

Imagery Service

http://staging.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

Now for the fun stuff Getting the map from Microsoft

protected void Page_Load(object sender, EventArgs e)
  {
      if (Page.IsPostBack == false)
      {
          this.TextBox_From.Text = "State College Blvd , Fullerton, CA 92831";
          this.TextBox_To.Text = "Golden Gate Bridge";  //Safeco Field
      }
  }

 

And finally add a handler for the button click there are a ton of commonts in here so ill those be your guide feel to ping me iwth more questions plus down load the code and run it is the best way to go.

/// <summary>Displays directions from a point to another point based on the address supplied in the UI</summary>
    /// <param name="sender">The sender</param>
    /// <param name="e">Event arguments</param>
    protected void Button_GetDirections_Click(object sender, EventArgs e)
    {
        // Create a new RouteRequest and set our credentials
        RouteRequest routeRequest = new RouteRequest();
        routeRequest.Credentials = new VERouteService.Credentials();
        routeRequest.Credentials.Token = Utils.Token(Request.UserHostAddress);
 
 
        // Create a new list of Waypoints and add start and end locations to the list
        List<Waypoint> wayPointList = new List<Waypoint>();
        wayPointList.Add(this.GetWayPointFromAddress("Start", this.TextBox_From.Text.Trim()));
        wayPointList.Add(this.GetWayPointFromAddress("End", this.TextBox_To.Text.Trim()));
 
        // Add the list of waypoints to the route request
        routeRequest.Waypoints = wayPointList.ToArray();
 
        // New up a RouteServiceClient
        RouteServiceClient routeServiceClient = new RouteServiceClient();
 
 
        //and calculate the route
        RouteResponse routeResponse = routeServiceClient.CalculateRoute(routeRequest);
 
        // Write the route directions back to the UI
        int legCounter = 0;
        foreach (RouteLeg routeLeg in routeResponse.Result.Legs)
        {
            foreach (ItineraryItem itineraryItem in routeLeg.Itinerary)
                this.WriteInfo((++legCounter) + ") " + itineraryItem.Text);
        }
    }
 
    /// <summary>Returns a waypoint given from the specified address</summary>
    /// <param name="description">Waypoint description</param>
    /// <param name="address">Address to geocode against</param>
    protected Waypoint GetWayPointFromAddress(string description, string address)
    {
        // Create a waypoint, new up the a location object and set the description
        Waypoint wayPoint = new Waypoint
        {
            Description = description,
            Location = new VERouteService.Location()
        };
 
        // New up a geocode request and supply the credentials 
        GeocodeRequest geocodeRequest = new GeocodeRequest();
        geocodeRequest.Credentials = new VEGeocodeService.Credentials();
        geocodeRequest.Credentials.Token = Utils.Token(Request.UserHostAddress);
 
        //pass the address of the location
        geocodeRequest.Query = address;
 
 
        // Create a GeocodeService client and execute the Geocode method
        GeocodeServiceClient geocodeServiceClient = new GeocodeServiceClient();
        GeocodeResponse geocodeResponse = geocodeServiceClient.Geocode(geocodeRequest);
 
        // If we have a geocode result, set the first result to our waypoint location
        if (geocodeResponse.Results.Length > 0)
        {
            if (geocodeResponse.Results[0].Locations.Length > 0)
            {
                wayPoint.Location.Latitude = geocodeResponse.Results[0].Locations[0].Latitude;
                wayPoint.Location.Longitude = geocodeResponse.Results[0].Locations[0].Longitude;
            }
        }
 
        return wayPoint;
    }

One Little helper function

/// <summary>Writes information to the UI</summary>
   /// <param name="html">HTML to write to the UI</param>
   protected void WriteInfo(string html)
   {
       this.Div_Directions.InnerHtml += html + "<br/>\n";
   }

Bam there you have a routing simply from two peoples address… Sweet.

There is a ton more information that you can pull out of the objet I kept to just a few things for simplicity.

Download the code here.

image

One Last look at the finished Product

image

 

 

 

 

 

 

 


Virtual Earth Web Service - Get Server Tile Information

January 21, 2009 23:35 by gemery

In this tutorial we are going to look at what you need to get Tile information from a lat 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>VE Web Services Imagery Tile 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 Tile 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" />
                <br />
                <asp:Button runat="server" Text="Load Tile" ID="Button_LoadTile" 
                    onclick="Button_LoadTile_Click" />
                <br /><br />
                <div runat="server" id="Div_Info" />
                <asp:PlaceHolder runat="server" ID="PlaceHolder_MapImages" />
            </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 user key and password out of the web.config 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

Now for the fun stuff Getting the map from Microsoft

/// <summary>Loads a tile map tile that contains the specified latitude and longitude</summary>
   /// <param name="sender">The sender</param>
   /// <param name="e">Event arugments</param>
   protected void Button_LoadTile_Click(object sender, EventArgs e)
   {
       // Clear our outputs before we start.
       this.PlaceHolder_MapImages.Controls.Clear();
       this.Div_Info.InnerHtml = "";
 
       // Create a ImageryMetadataOptions object
       ImageryMetadataOptions imageryMetadataOptions = new ImageryMetadataOptions
       {
           // Specify the location, this will not necessarly be the middle of the tile
           Location = new Location
           {
               Altitude = 0,
               Latitude = Convert.ToDouble(this.TextBox_Latitude.Text),
               Longitude = Convert.ToDouble(this.TextBox_Longitude.Text)
           },
           ReturnImageryProviders = true,
           ZoomLevel = Convert.ToInt32(this.DropDownList_ZoomLevel.SelectedItem.ToString()),
       };
 
       // Create the metadata request, set the credentials, options and a map style
       ImageryMetadataRequest imageryMetadataRequest = new ImageryMetadataRequest
       {
           //add the metadata options object from above
           Options = imageryMetadataOptions,
           Style = MapStyle.AerialWithLabels
       };
 
       //New up a credentials object and set the token
       imageryMetadataRequest.Credentials = new VEImageryService.Credentials();
       imageryMetadataRequest.Credentials.Token = Utils.Token(Request.UserHostAddress);
 
       // Create the ImageryServiceClient
       ImageryServiceClient imageryServiceClient = new ImageryServiceClient();
 
       //and make the request
       ImageryMetadataResponse imageryMetadataResponse = imageryServiceClient.GetImageryMetadata(imageryMetadataRequest);
 
       // Write out the tile metadata to the UI
       foreach (ImageryMetadataResult imageryMetadataResult in imageryMetadataResponse.Results)
       {
           Image image = new Image();
           image.ImageUrl = imageryMetadataResult.ImageUri;
           this.PlaceHolder_MapImages.Controls.Add(image);
 
           this.WritePair("Image URI", imageryMetadataResult.ImageUri);
           if (imageryMetadataResult.Vintage != null)
           {
               this.WritePair("Vintage From", imageryMetadataResult.Vintage.From.ToString());
               this.WritePair("Vintage To", imageryMetadataResult.Vintage.To.ToString());
           }
           this.WritePair("Zoom Range From", imageryMetadataResult.ZoomRange.From.ToString());
           this.WritePair("Zoom Range To", imageryMetadataResult.ZoomRange.To.ToString());
           this.WriteInfo("");
       }
   }

And finally add a handler for the button click

/// <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 there you have a map coming at you from a longitude latitude and you are spitting out the the map tiles information.

If 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

One Last look at the finished Product

image


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!


Virtual Earth Web Services - Using HTTPS Secure Socket Layer (SSL) Protocol

January 21, 2009 21:45 by gemery
If you want to send and receive Virtual Earth Web Services requests using Secure Socket Layer (SSL), follow the steps below.

Follow this post to get you token

http://blog.geoffreyemery.com/post/Virtual-Earth-Web-Services---Requesting-a-Token.aspx

Follow this post to find web services

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

 

  1. Generate proxy classes using the staging or production service metadata URLs listed above by adding a service reference using the Visual Studio User Interface or by using the svcutil.exe tool. More information about this is found in the Generating Client Proxy Classes topic.
  2. Edit the service endpoint address URLs found in your configuration file to begin with "https" instead of "http".
  3. If you are using Visual Studio 2008 and the .NET Framework 3.0, you also need to change the BasicHttpSecurityMode to Transport. To do this, either set the mode of the security tag in your Visual Studio 2008 configuration file to Transport, or initialize your service variable with this security mode.

Add this to the config

<!-- Visual Studio 2008 configuration settings for SSL -->
<system.serviceModel>
   <bindings>
      <basicHttpBinding>
         <binding name="BasicHttpBinding_IImageryService" closeTimeout="00:01:00"
            openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
            allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
            maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
            messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
            useDefaultWebProxy="true">
            <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
            maxBytesPerRead="4096" maxNameTableCharCount="16384" />
            <security mode="Transport">
               <transport clientCredentialType="None" proxyCredentialType="None" realm="" />
               <message clientCredentialType="UserName" algorithmSuite="Default" />
            </security>
         </binding>
      </basicHttpBinding>
   </bindings>
   <client>
      <endpoint address="https://staging.dev.virtualearth.net/WebServices/v1/ImageryService/ImageryService.svc" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IImageryService" contract="IImageryService" name="BasicHttpBinding_IImageryService" />
   </client>
</system.serviceModel>

 

// Instead of setting the security mode in the configuration file, 
//    initialize the service client variable with the Transport
//    security mode.
SearchServiceClient client = new SearchServiceClient(new BasicHttpBinding(BasicHttpSecurityMode.Transport), new EndpointAddress("https://staging.dev.virtualearth.net/webservices/v1/searchservice/searchservice.svc");
 
 
 
 

MSDN Refrence


Virtual Earth Web Services

January 21, 2009 21:40 by gemery

Ok this a repost but ill be dammed if I try to find it one more time on microsofts site so I posting it here for SEO sake.

To call one of the Virtual Earth Web Services, you need to generate proxy classes on your client. This is described in detail in the Generating Client Proxy Classes topic. If you are using Visual Studio 2008, use the svcutil.exe command-line utility (http://msdn.microsoft.com/en-us/library/aa347733.aspx) or add service references to the Virtual Earth Web Services from the Visual Studio user interface. The Virtual Earth Web Services metadata defines the format of messages that the Virtual Earth Web Services send and receive.

You can use either the standard HTTP protocol or the HTTPS Secure Sockets Layer (SSL) protocol to call the Virtual Earth Web Services. Note that using the SSL protocol adds latency for each call to the Virtual Earth Web Services. The latency duration depends on how the SSL infrastructure is implemented on your servers; the minimum additional latency is five milliseconds.

Virtual Earth provides both staging and production environments, which are two functionally identical, yet separate, service environments.

Staging Environment

The Virtual Earth Web Services staging environment is a testing environment that is separate from, but complementary to, the production environment that you use when your application goes live. You can use the staging environment to prototype, develop, and test new applications.

Note The staging environment is not scaled for the volumes that the production environment is designed to provide. Any application stress or performance testing is limited to a certain number of requests per second and time of day.

The following table lists the staging service metadata URLs for each of the Virtual Earth Web Services. Note that you will need to have valid credentials to make staging service calls. More information about getting and setting credentials can be found in the Accessing the Virtual Earth Web Services topic.

Service Name
Staging Service Metadata URL

Geocode Service

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

Imagery Service

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

Route Service

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

Search Service

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

Production Environment

The Virtual Earth Web Services production environment is fully scaled for all Virtual Earth customers. You use this environment when your application is made available to the public through the Internet, including live, beta, evaluation, and prerelease types of applications.

Note Activity in the production environment is billable. Do not use the production environment for performance and stress testing beyond your expected volumes.

The following table lists the production service metadata URLs for each of the Virtual Earth Web Services. Note that you will need to have valid credentials to make production service calls. More information about getting and setting credentials can be found in the Accessing the Virtual Earth Web Services topic.

Service Name
Production Service Metadata URL

Geocode Service

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

Imagery Service

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

Route Service

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

Search Service

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