Click here to Skip to main content
Click here to Skip to main content

GPS Runner Maps: My First Windows Azure Application

, 20 Dec 2009 CPOL
Rate this:
Please Sign up or sign in to vote.
It is "cloud" Web application to display GPS tracks on Google or Bing maps

Introduction

It is "cloud" Web application to display GPS tracks on Google or Bing maps, based on the latest Windows Azure Software Development Kit (November 2009). This code may be useful to you if you want to start a new Windows Azure application or want to find code to display GPS data with server code on a Google/Bing map. It is not a complete application such as professionally designed sites like Every Trail. The application uses ASP.NET providers that work with Azure Table Storage (AspProviders sample from Windows Azure Code Samples), so it is not so much different from a traditional Web application. It uses Table Storage to store data. SQL Azure was not available when I started developing. I would highly recommend SQL Azure because Table Storage has several limitations (although it is supposed to be faster).

Application Description

I started the application as a clone of the PersonalWebSite sample. It has the standard functionality of register/login. With the Add Track page, you can add a track by uploading a standard GPX file and giving a name, your country and a description. You can also select if the track will be public. In the Tracks page, you can see all the public tracks and your private ones, or filter by user and country. The View button displays the track in the selected map (Google or Bing). If you login as a registered user, a delete button will appear for your own tracks.

The details button displays the track, its points as dots and some statistics. The "map animation" feature offers you a virtual "journey" of the track. The map centers to successive track points with an adjustable speed. A pause/continue button is offered. Bing Bird's eye view is particularly attractive in this mode. Finally a link to display a full Google/Bing web page of the area is offered.

Using the Code

The code works in the local development fabric provided by the SDK. Table Storage is simulated by a database in the default SQL express installation. If you want to publish it in the Windows Azure environment, replace the key values in the ServiceConfiguration.cscfg configuration file.

Table Storage is used for storing track/coordinate data. See the Windows Azure Platform Training Kit for tutorials about Table Storage. You simply derive your entity classes from the base TableServiceEntity class and query with LINQ code. Unfortunately, Count and Take operations are not supported. Paging can be implemented with custom headers, as shown below. For more information, see the video here.

private void DataBindTracks()
{
  try
  {
    DataServiceQuery<trackrow /> tracksQuery = this.GetTracks(this.PageSize);
    // int c = tracksQuery.Count(); --> unfortunately count is not supported
    var continuation = Request["ct"];
    if (continuation != null)
    {
      string[] tokens = continuation.Split('/');
      string partitionToken = tokens[0];
      string rowToken = tokens[1];
      tracksQuery.AddQueryOption("NextPartitionKey", partitionToken).
        AddQueryOption("NextRowKey", rowToken);
    }
    QueryOperationResponse res = (QueryOperationResponse)tracksQuery.Execute();
    string nextPartition = null;
    string nextRow = null;
    res.Headers.TryGetValue("x-ms-continuation-NextPartitionKey", out nextPartition);
    res.Headers.TryGetValue("x-ms-continuation-NextRowKey", out nextRow);
    dtlTracks.DataKeyField = "TrackId";
    dtlTracks.DataSource = res;
    // bind data list
    dtlTracks.DataBind();
    if (nextPartition != null && nextRow != null)
    {
      navNext.NavigateUrl = string.Format("?ct={0}/{1}", nextPartition, nextRow);
    }
    else
    {
      navNext.Enabled = false;
    }
    if (continuation == null)
    { navPrev.Enabled = false; }
  }
  catch (Exception ex)
  {
    System.Diagnostics.Debug.WriteLine(ex.Message);
    throw ex;
  }
  //Checking for enabling/disabling next/prev buttons.
  //Next/prev button will be disabled when it is the last/first page of the pageobject.
}
    
    /// <summary>
    /// Gets the public tracks from all users filtered by country.
    /// </summary>
    /// <returns></returns>
    public static DataServiceQuery<trackrow> GetPublicTracks(string country)
    {
        try
        {
            GpsDataContext svc = GetGpsDataContext();
            DataServiceQuery<trackrow> rows = (DataServiceQuery<trackrow>)
              from tr in svc.Tracks where tr.IsPublic == true select tr;
            if (!string.IsNullOrEmpty(country))
            { rows = (DataServiceQuery<trackrow>)rows.Where
		(tr => tr.Country == country); }
            return rows;
        }
        catch (Exception ex)
        {
            Log.Write(EventKind.Error, "Could not get tracks" + ex.Message);
            throw ex;
        }
    }

The Back button simply calls the history.go(-1) JavaScript code to return to the previous page.

Here I have to make a confession. Paging does not work in my application although the continuation headers are returned and used. It always shows the first page. If anyone finds out why, please leave a comment in the article.

The display of the Google map is done server side, using a user control named Google Maps for ASP.NET published at CodeProject in two articles: Part 1 and Part 2. It is a very clever code that optimizes performance by emitting only the coordinate differences of maps between postbacks to the client. It was modified to run in a web application.

For the Bing maps, I used the Virtual Earth server control of the Windows Live SDK. It is not provided anymore by Microsoft but it still works! Additionally, the IPToCountry code, also from CodeProject, is used to find the country of the anonymous visitor.

As far as the rest of the code is concerned, it has no solid architecture, just quick and dirty implementation! Track coordinates are stored in the users' session and the IMapDisplay interface is used to remove repetitive if(google) else ... decisions. GoogleMapDisplay and VEMapDisplay provide the actual map display functionality. Some classes like Panoramio and ExtJsJsonHelper are not actually used, they belong to never implemented features!

History

  • 20th December, 2009: Initial and most probably final version of the application!
    I hope you will find some parts of it useful.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Philipos Sakellaropoulos
Web Developer
Greece Greece
Software developer and Microsoft Trainer, Athens, Greece (MCT, MCSD.net, MCSE 2003, MCDBA 2000,MCTS, MCITP, MCIPD).
Follow on   Twitter   Google+

Comments and Discussions

 
Generalcode running problems! PinmemberKanwal Shehzad21-Dec-09 19:38 
GeneralRe: code running problems! PinmemberPhilipos Sakellaropoulos22-Dec-09 8:35 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.1411023.1 | Last Updated 20 Dec 2009
Article Copyright 2009 by Philipos Sakellaropoulos
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid