Welcome to MSDN Blogs Sign in | Join | Help

I love my Garmin 275 nüvi! I’ve always put off buying a SatNav as it somehow seems a sign of weakness to not know where you are, but now I have one I wouldn’t be without it.

What I also like is the integration with Windows Live Maps, in particular the way you can save your collections as Favorites on your device. This makes it trivially easy to find where you’re going to on the site beforehand and then download the location to the GPS.

Communication with the device is handled by a browser plug-in provided by Garmin which can be downloaded from http://www8.garmin.com/products/communicator/

Once the plug-in is installed and the Garmin is connected, then saving a collection to the GPS is as easy as going to the Actions->Send To->GPS menu in the Collections window

The Garmin Communicator Plugin API is available for use on your own website – full details can be found at http://developer.garmin.com/web-device/garmin-communicator-plugin/

There is a great demo page at http://developer.garmin.com/web/communicator-api/apidemo/garminDeviceControlDemo.html which shows all the functionality available via the plug-in, including reading and writing the saved points of interest, and also the tracks of previous journeys made with the GPS.

This is all good stuff, but all the example code uses Google Maps so I thought it might be interesting to adapt the code to get it to work with Windows Live Maps instead.

You can see the results of my experiments on my website at http://www.metanetsolutions.co.uk/Garmin/ and you can see below a screenshot of the page showing my journey home from my office in building 109 in Redmond back to the hotel I’m staying in in Bellevue:

The code is hopefully reasonably understandable and is fairly closely based on the sample Garmin code so I won’t go into too many details here, but here are some of the highlights…

  • There are various issues with the current version of Windows Live Maps in IE8 Beta 1, so you need to run the code in compatibility mode. Rather than expecting the user to know this, I now realise you can force IE into IE7 mode by adding the header
  • <meta http-equiv="X-UA-Compatible" content="IE=7" />

    to the page.

  • When creating a VELatLong object, you need to ensure the latitude and longitude parameters are floats, so I wrapped the parameters in the JavaScript parseFloat() function
  • My only real addition to the Garmin code was to add a “last known location” function to the code. All this does is:
    • Loop through all of the track data on the device
    • Find the track with the latest end date
    • Get the last valid sample location of the latest track
  • I’m only currently using that last known location in the UI, but it won’t take much work to be able to hook this up to be saved at FireEagle – watch this space!

If you’re so inclined, please feel free to use and extend this code however you wish. Let me know if you do, or if you find any bugs!

I’ve always used the Windows Live Toolbar to sync favorites across my multiple machines, so it was a bit disappointing when the previous beta removed that functionality with the demise of http://favorites.live.com

That meant I was pleased to see the service had been added to the latest beta of the toolbar in the new Windows Live Essentials pack, but then very frustrated when it failed to install properly on a couple of my PCs.

However after a bit of playing about I stumbled on a fix, so I thought I’d share the solution here as I couldn’t find any other references online.

After setting up the sync on my work laptop, after what I thought was a successful install on my home PC there was no option for setting up the sync in the left hand side of Toolbar options - see the picture below:

I had no idea what the problem was, and was going to try the trusted uninstall/reinstall route, but when I went to the uninstall control panel I realised I still had the old Favorites toolbar add-in installed:

On one PC simply uninstalling the “Windows Live Favorites for Windows Live Toolbar” did the trick, and the sync options magically appeared.

On another PC I had to reinstall the toolbar too, but then finally I was in sync across all my PCs.

I hope you found that helpful!

Update (23/12/2008): There has been some discussion on Liveside about this issue that you should check out. One thing I didn’t know is that the Favorites sync isn’t available in all markets at the moment.

Update 2 (18/02/2009): I’ve upgraded a couple of machines to Windows 7 and on one of them I just couldn’t get the sync to appear. They were both fresh installs so the issue above didn’t fix it. I also made sure everything on the failing machine was “en-us”, but to no avail.

Actually I was getting frustrated with the way the sync wouldn’t handle deletes properly, so I’ve given up and am just using the superior Live Mesh to sync my favorites directory.

The next stage in my plan to let the whole world know where I am has been to hook up my Fire Eagle location to Twitter, so every time my location changes a Tweet is sent to everyone following me.

I thought for a while about hooking up my code to Twitter using the Twitter API, but then realised there is a much simpler way.

  1. Expose my Fire Eagle location via an RSS feed
  2. Use TwitterFeed to post changes to the feed to my Twitter account

For the RSS feed part, it was relatively simple to adapt my existing code to make my own feed, but there are several existing Fire Eagle services that will do this for you.

Then TwitterFeed – which is a simple but excellent service – does the work of watching the feed for updates, and then posting any changes to my Twitter feed.

All pretty simple in the end.

Some fairly vaguely related thoughts…

1. The power of both Twitter and Fire Eagle are only really exposed by the services and applications that use them. Fire Eagle is designed specifically to work in that way, but my use of Twitter has really taken off since finding applications like TwitterFeed and Tweet Deck.

2. I’m really impressed with the updated Windows Live web sites, and in particular the web activities. It’s great that my tweets are now exposed to my contacts who are much less likely to use Twitter. Although after the work I’ve done above means I don’t really need it, it would be fantastic if Fire Eagle was a future web activity.

3. TwitterFeed used Open ID as it’s authentication scheme, and it was the first time I’d used it. If I didn’t have half an idea what was going on it would have been a very confusing experience. All the talk of “what’s your URL?” didn’t make any sense until I realised I could just go to Yahoo! and use my account there to generate my ID. Definitely wouldn’t have passed the “can your Mom use it?” test.

P.S. If you want to follow me on Twitter, you can at http://twitter.com/yeltzland

Not that you’d really notice, but I’ve updated the code to show my current location on the map on this blog to use Fire Eagle to store my current location.

If you haven’t heard of it before, Fire Eagle is a service provided by Yahoo! which lets you store your current location, and then allow different applications read or write access that location at an accuracy level that you control.

This is a simple service which is actually really cool, and there are already multiple applications on different platforms (web, client and mobile) which allow you to read and/or update your location dynamically. So if you really want to – and I do! – you can track and expose your location however you want.

The full developer details are at http://fireeagle.yahoo.net/developer (you need a Yahoo! account to access this) so I won’t explain too many of the low-level details here. However here’s a few things to note if you want to investigate yourself:

1. Fire Eagle uses OAuth for securing access to their API, which means:

  • First get the application token by registering your application at Fire Eagle
  • Using the application token you get a request token for an individual user, from which a URL is created to send the user to Fire Eagle to both confirm access permissions to their location for your application, and at the level of accuracy the application may show
  • Once the user has confirmed permission, your application gets a user-specific token which it should store and use to access the Fire Eagle API to get that user’s location

2. There are various libraries available for both OAuth and Fire Eagle access:

  • I used the C# Fire Eagle library at Google Code
  • However there are a couple of bugs in the library that I had to fix:
    • The response can’t be serialised properly because the Error object uses IDictionary which can’t be serialised
    • A couple of the values in the location hierarchy - “exact” and “region” weren’t available
  • Also, the library didn’t expose the latitude and longitude of the locations returned – the main thing I was interested in so I could display the position on my Virtual Earth map!
  • Update (8th Dec 2008) I’ve checked in fixes for both issues and the library extensions I made to the code repository at http://code.google.com/p/fireeaglenet/ If you find any problems, let me know and I’ll take a look ASAP.

 

Once all of the access token details have been obtained and stored in my web.config file (I know, not the most secure practice and not one I’d use on a real production site), then using the C# library it’s very easy to get my location with a few lines of code:

Token userToken = new Token(appSettings["fireeagle_usertoken"], appSettings["fireeagle_usersecret"]);
FireEagle fireEagle = new FireEagle(appSettings["fireeagle_consumertoken"], appSettings["fireeagle_consumersecret"], userToken);
User fireEagleUser = fireEagle.User();
Location bestLocation = fireEagleUser.LocationHierarchy.BestGuess;

    I can then use that Location object (after my extension to the library) to get the latitude and longitude to drive my JavaScript implementation of Virtual Earth shown in an earlier post.

    As an aside – which I may come back to in a future post – I wanted to protect some of the pages I built (the ones where I expose my Fire Eagle token details). To do this I used Windows Live ID using code from the Web Authentication SDK – see http://dev.live.com/liveid/ for details.

    This was almost trivially easy, and having banged my head against earlier Passport implementations, this was a pleasure to use (if that’s not overstating things!). Kudos to the Live ID team, and if you’ve been put off using WLID after being scarred by previous attempts with Passport, I definitely recommend taking another look.

    I got this tip in the pub on Friday from my friend Bobby who works on the MSDN team. He told me he’d worked on implementing a low bandwidth version of the site, which is simpler and much, much faster than usual view.

    I’d never heard of this, but a quick Live Search found a few relevant blog posts, including an excellent post explaining this feature and quite a bit more on John Galloway's blog.

    I’d definitely recommend checking out that article, but the key point is simply add “(loband)” before the “.aspx” in any MSDN library URL e.g. http://msdn.microsoft.com/en-us/library/system.object(loband).aspx

    You can also set a cookie that can persist this view for future calls to MSDN without having to insert the (loband) part.

    I’m sure many people who spend a lot of time in the MSDN libraries (including myself) will definitely find this feature very useful. This should definitely be publicised more widely!

    As I’m often switching location between my home in the UK and working out in Redmond, I’ve been thinking for a while about how best to easily let people know where I am. As you can hopefully see, I’ve added a map to every page on this blog and I thought that maybe people might be interested how I did this, as I learnt a few things on the way that were reasonably interesting.

    The first challenge was to figure out the best way around the limitations of adding a map to the blog page. Although the Community Server software that this site runs on is pretty flexible, you can only add elements to every page in various sections – in my case in the News section. Luckily there don’t appear to be any restrictions on the actual HTML you can add, so I was left with a choice of options.

    My first thought was to add an <IFRAME… /> section that would call out to a page on my own server that would use Windows Live Maps to display where I am by adding a pushpin at the appropriate location. However this didn’t really work very well, as the map code didn’t really like being in an IFrame and the flow of the page around the map was broken.

    Therefore the solution I hit on was to add the following code:

    <h3>LIVE LOCATION</h3>
    <div id='myMap' style="position:relative; width:150px; height:200px;"></div>
    <script type="text/javascript" src=http://www.metanetsolutions.co.uk/mapscript.aspx?mapElement=myMap defer=”true”></script>

    The ‘myMap’ element is the div where the map will be placed by the JavaScript that I create on my server. Note that I am passing the name of this element into my script so I can use it.

    Interesting point to note is adding the defer=true on to the script call. Without it, I was occasionally hitting a known issue in Internet Explorer due to a bug in the IE parser :-(

    The ASPX page that generates the JavaScript is shown below. I won’t show the pretty simple code behind just yet, as I’m hoping to add more functionality to this soon before I share the code. However in this initial version it just creates a “LocationEntry” object from an XML file held on the server, and then uses this object to set various parts of the script.

    The interesting things of note in the JavaScript are:

    • Note the excellent "delayed loading of the map code" that was written by Soul Solutions that I used here. This:
      • Sets an animated GIF as the background to the map div while the code is loading
      • Dynamically adds the Virtual Earth required JavaScript files to the head element of the page
      • Sets a callback to the function to setup the map once the VE API scripts have loaded
    • The onscriptload callback function removes the dashboard and scalebar to make the map cleaner, sets the zoom level – defaults to 10 but can be overwritten by setting a zoom=n on the query parameters to the page request, and then simply adds a pushpin at the location set by the LocationEntry in the code behind

    Hopefully this is pretty self-explanatory – see http://dev.live.com/virtualearth/ for more details about the Virtual Earth API.

     

    Here’s the ASPX/JavaScript code:

    <%@ Page Language="C#" AutoEventWireup="true" CodeFile="MapScript.aspx.cs" Inherits="DefaultPage" %>
    var mapElementName = '<%= this.MapElementName %>';
    var mapControlVersion = '6.2';

    // Dynamic loading script from http://www.soulsolutions.com.au/examples/VE62/loadondemand.htm
    var loaded = false;
    var map = null;

    function onscriptload()
    {
      // Get rid of our load animation
      document.getElementById(mapElementName).style.background = "";

      var locationLatLong = new VELatLong(<%= this.CurrentLocation.Latitude %>, <%= this.CurrentLocation.Longitude %>);

      map = new VEMap(mapElementName);
      map.LoadMap(locationLatLong, 1, VEMapStyle.Road, true, VEMapMode.Mode2D, false, 0);
      map.HideDashboard();
      map.HideScalebar();
      map.SetZoomLevel(<%= this.MapZoomLevel %>);

      AddLocationPushpin(locationLatLong);
    }

    function loadVEAPI()
    {
      if (!loaded)
      {
        loaded = true;
      
        // Set a nice animated gif to show the map is loading
        document.getElementById(mapElementName).style.background = "url(images/ajax-loader.gif) center center no-repeat";
        
        if (!(window.attachEvent))
        {
          appendJS("http://dev.virtualearth.net/mapcontrol/v" + mapControlVersion + "/js/atlascompat.js");
        }
      
        appendJS("http://dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=" + mapControlVersion + "&onScriptLoad=onscriptload");
      }
    }

    function appendJS(filename)
    {
      var fileref = document.createElement('script');
      fileref.setAttribute("type", "text/javascript");
      fileref.setAttribute("src", filename);
      document.getElementsByTagName("head")[0].appendChild(fileref);
    }

    function AddLocationPushpin(myLocation)
    {
      map.SetCenter(myLocation);

      var myPushpin = new VEShape(VEShapeType.Pushpin, myLocation);

      myPushpin.SetTitle("<%= this.CurrentLocation.Title %>");

      var description = "<p><%= this.CurrentLocation.Description %></p>";
      description += "<p><%= this.CurrentLocation.UpdateTime.ToString("u") %></p>";
      myPushpin.SetDescription(description);

      map.AddShape(myPushpin);
    }

    // Start the loading
    loadVEAPI();

     

    Future plans (which I suspect are overly ambitious!) for this application involve:

    • A JavaScript and VE enabled form to easily update my location
    • Mesh-enabling the application
    • Hooking up my GPS so I can automatically update my location when I’m on the move
    • Possibly hooking everything up to FireEagle

    We found an interesting issue today regarding our use of pre-compiled ASP.Net websites that I thought I would share, as we learnt something that we didn’t know before.

    In our particular setup (for reasons too complicated to go into here), we have an ASP.Net website that:

    1. We want to pre-compile before deploying to the live servers for the usual reasons of performance (no delay on first hit) and security (source code not hosted on the servers)
    2. Before starting the web application, we automatically generate its web.config file
    3. By default we want to disable view state in all the pages by adding a <pages enableViewState=”false” /> node in the generated web.config

    Our issue was that even though the generated web.config file had the correct setting in it, the view state wasn’t being disabled. This had us confused for quite a while.

    It turns out that the default setting when a website is compiled by the ASP.Net compiler doesn’t allow subsequent updates to the site.

    In our particular case, this meant the compiled pages were using the (default) value in our non-existent web.config at compile time, not the one actually on the server at runtime.

    Once we realised that, the solution was easy: simply add a –u parameter to the compiler flags which meant:

    -u specifies that the Aspnet_compiler.exe should create a precompiled application that allows subsequent updates of contents such as .aspx pages.

    If this option is omitted, the resulting application contains only compiled files and cannot be updated on the deployment server. You can update the application only by changing the source markup files and recompiling.

    (Stolen from http://msdn.microsoft.com/en-us/library/ms229863(VS.80).aspx from where you can see all the available compiler parameters)

    I guess a more common scenario is that you want to hot fix your web.config file – perhaps your database connection strings need changing immediately – but unless you’ve compiled with the –u flag, you’ll have to do a full build and redeployment.

    Well “relaunch” is a little grand, but I thought I’d try to make a bit better use of this blog. The plan is to try to post more regularly, still trying to share code or ideas I’ve found useful which hopefully others may find useful too.

    Looking back at my introductory post written nearly 3 years ago, I realise how much my career has changed over that time.

    Not long after I posted that message, I moved on from the MSN team based in London to working on the sadly missed (by me anyway!) Windows Live Expo. Technically Expo was an interesting challenge, as we were attempting to build a scalable system dealing with some pretty large data sets. The working environment was great too, as we were a small, almost start-up like team within Microsoft.

    The other big change was that the Expo team was almost completely based in Redmond, whereas I was working from home in the UK. This worked out better than we hoped, and although I spent about two weeks in every eight out in Redmond, my quality of life has improved greatly as I no longer spend 4 hours every day commuting up to London from Hove.

    I’m now working in the Live Search team, specifically on the Commerce team. I don’t think there could be a more exciting field to be working in at the moment in Microsoft than in Search as there is a fantastically talented bunch of people working really hard to try to beat an excellent competitor in Google. I’m still doing the 75%/25% split between home in the UK and the office in Redmond, and thankfully still enjoying doing that.

    Technically, as you’d expect my focus is on building highly scalable web sites, so I suspect a lot of my posts will be on challenges in that area. For the last 6-9 months I had been working in C++ for the first time in about 15 years which was surprisingly fun in the end, but my current project is taking me back to C# and managed code (which I’m pretty happy about!)

    However not everything will be directly work related, as I’m interested in most things online, in particular Windows Live services, and even more specifically location based services. I’ve a few side projects I’m currently working on that I hope to share on here when I’ve made more progress.

    I think that’s enough about me for now – hopefully my next post will be a little more useful!

    As usual, this may well be common knowledge but I found this useful.

    In a stored procedure we were passing in a parameter (say @maxRows) which we wanted to use to dynamically limit the number of rows returned by the query.

    For ages we couldn't find a way to do this without building up the SQL in a string using the parameter and then executing it e.g. something horrible like 'SELECT TOP ' + CAST(@MaxRows AS varchar(10)) + '...'

    Now it turns out you are supposed to put the value used by the TOP in brackets anyway - see http://msdn2.microsoft.com/en-us/library/ms189463.aspx - so putting the parameter in brackets e.g. SELECT TOP (@MaxRows) ... is not only correct but gets around the horrible cast.

    I don't do much client-side JavaScript programming, and I've always had intermittent issues when trying to attach a Visual Studio debugger to a instance of IE when I'm trying to figure out what's going on.

    However in August 2007's MSDN Magazine (doesn't seem to be available online yet - page 52 in magazine) it talks briefly about the debugger JavaScript command, which forces the browser to bring up the elusive "debugger dialog". Very useful!

    I'm not sure how well this is supported across different browsers, but for my non-expert use knowing about the debugger command certainly will make my life easier when I step into the crazy world of JavaScript.

    Some more details at http://support.microsoft.com/kb/816173 

    I found the following page interesting when having issues setting a value in a SqlParameter constructor.

    From http://msdn2.microsoft.com/en-us/library/0881fz2y.aspx:

    When you specify an Object in the value parameter, the SqlDbType is inferred from the Microsoft .NET Framework type of the Object.

    Use caution when you use this overload of the SqlParameter constructor to specify integer parameter values. Because this overload takes a value of type Object, you must convert the integral value to an Object type when the value is zero, as the following C# example demonstrates

    Parameter = new SqlParameter("@pname", Convert.ToInt32(0));

    I guess it makes sense once it's explained, but it's not immediately clear when you just use 0 rather than Convert.ToInt32(0) why it doesn't work as expected

    Recently had some issues setting up some custom perf counters to install and run from an ASP.Net page that I thought I'd share.

    We began by using the information in http://support.microsoft.com/kb/555129 which states:

    "It turns out that the permission set required to update performance counters is much smaller than running as an Administrator or Power User.  In the registry key HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Perflib, set the Access Control List so that the necessary user has Full Control. In our original example, the ASPNET user would be granted Full Control, but access can be granted to anyone who needs to update a performance counter."

    However I mistakenly assumed that as that setting those permissions would also enable the counters to be created, which is wrong. From the comments in http://objectsharp.com/cs/blogs/bruce/archive/2003/12/05/222.aspx we found out it's more complicated than that:

    "For 2003 I did the following changes:
    HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Perflib\009 - Added permissions for Network Service
    HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services - Added permissions for Network Service
    C:\WINNT\system32\perf*009.dat - Added full permissions for Network Service on all matching files.
    After that it worked like a charm."

    We didn't try the above solution, as after a little more thinking we gave up trying to install the counters on the fly and wrote some code that runs as part of the site installation (and hence runs as an Administrator which means it will definitely have permission to create the counters).

    It's a lot cleaner doing it that way, and changes less permissions on the server which is always a good thing from a security point of view.

    If you're interested. the code uses the System.Diagnostics.CounterCreationData class to create the counters on the web server if they're not already installed - see the documentation if required as it's pretty easy to use.

     

    Is this a well known trick and I'm just completely out of touch? Probably, but I was very excited when I found out that holding down CTRL when clicking a link in IE7 will open the link in a new tab.

    To think all this time I was using right click and then "Open In New Tab". I guess my productivity has just gone up by 0.1% :-)

    I was struggling to install some new software (the superb new Live Local 3D view - I had an early internal beta already installed) and then remembered a handy tip.

    To find all currently installed MSIs, use the (hidden) folder c:\windows\Installer. It gives you a nice browseable view of the current state of the system, and can be invaluable in tracking down what the system currently thinks is installed.

    As I've posted before, I really don't like the Visual Studio interface for running unit tests. This is mainly because it's not as clean (no hierarchy tree or big green line!), makes a copy of the files every time a test is run and is pretty slow (probably because of the file copies).

    However I was very happy to find out the latest version of NUnit (http://www.nunit.org) supports Visual Studio Unit tests, so you can just point the Nunit GUI at VS Unit Test DLLs and run the tests there.

    Both interfaces have their pros and cons, and I tend to go back and forth between VS (especially when debugging through the tests) and NUnit (when I want to run tests quickly) but it's definitely a big productivity gain being able to choose the most productive UI.

    More Posts Next page »
     
    Page view tracker