Ian Blackburn

July 2008 Entries

Silverlight Managed Wrapper for Virtual Earth

I have been doing a lot of work with this wrapper (called VIEWS, and available here: http://codeplex.com/views) - it really makes life a lot easier for working with VE in Silverlight, and will no doubt point the way towards how the final Silverlight VE control will work.

I recommend checking it out, and watching this intro video from Jared Bienz is a good start


Virtual Earth Mapping in Silverlight with VIEWS

 

Cheers

Ian

Technorati Tags: ,

Silverlight Wcf: The remote server returned an unexpected response: (404) Not Found.

Keep getting this error on a Silverlight 2 B2 project that is referencing a WCF service in a Web Site (not web project).

error

There doesn't seem to be any reason for it, and it happens intermittently, however the workaround I have for it currently is to simple open up the cs class for the service and make any edit (e.g. just add a comment line) and then build.  This seems to fix it for a while.

Hope there is a better solution long term, or a fix for this somewhere...

Ian

 

Technorati Tags: ,

The Amazing Album Cover Atlas

http://theamazingalbumcoveratlas.org/

The Amazing Album Cover Atlas

The excellent Word Magazine recently created an album cover atlas which shows locations of famous album covers.  Cool idea, but I didn't like the basic google maps interface. 

So as an exercise and to also help spike out some work we are doing on www.lovecleanstreets.org I created a quick Virtual Earth and Silverlight version that make use of the VIEWS VE managed wrapper for Silverlight.

Luckily the original developer, Ian Reeves used a REST service to get the data, so I was able to work with the same live data for my project.  There was no cross-domain policy that could be used by Silverlight though, so I created a WCF bridge service instead on my web project and referenced that from the Silverlight project:

[OperationContract()]
 public List<AlbumCover> GetAlbums()
 {
 
     const string rootUrl = "http://www.wordmagazine.co.uk/album_atlas/";

     WebClient client = new WebClient();
     string result= client.DownloadString(rootUrl + "xmlGeneratorAlbums.php");
     XDocument data = XDocument.Parse(result);
     IEnumerable<AlbumCover> albums = from cover in data.Elements("albumcovers").Elements()
                                      where cover.Attribute("ident").Value != "1"
                                      select new AlbumCover { 
                                          Ident = SafeIntParse(cover.Attribute("ident").Value), 
                                          Album = cover.Attribute("album").Value, 
                                          Latitude = SafeDoubleParse(cover.Attribute("latitude").Value),
                                          Longitude = SafeDoubleParse(cover.Attribute("longitude").Value),
                                          Artist=cover.Attribute("artist").Value,
                                          Link=cover.Attribute("link").Value,
                                          AddedBy=cover.Attribute("addedby").Value,
                                          Details=cover.Attribute("details").Value, 
                                          Location=cover.Attribute("location").Value,
                                          ImageUrl=rootUrl 
                                             + "getimage.php?ident=" 
                                             + SafeIntParse(cover.Attribute("ident").Value) };
     return albums.ToList();
 }

 

This worked fine on the development server, but I hit an issue when it was hosted on IIS.  The service threw an exception: "This collection already contains an address with scheme http" - turns out this is an issue if you have more than one host header with the Wcf service.  The solution is to write a custom host factory as described here by DiscountAsp support (we are not using DiscountAsp - but this is a good explanation that will work with any hoster)

Another issue I came across was to do with the images.  There are already over 400 album covers in the database, and I thought it would be nice to store those in Isolated Storage for fast re-use - unfortunately although you can serialise the data into isolated storage, there does not currently seem to be a way to get the Silverlight Image control to display them (you can't create an image from a stream - only from a Uri), so I have had to rely on browser caching instead.

Source code is available below, and offers no guarantee of anything but might be worth a look if you are trying this sort of thing.

 

Cheers

Ian

Being enticed by Live Mesh

Live Mesh is in early days yet, but having had it installed for a while, I am starting to see the possibilities

The mobile web client is now available (though the full mobile client is still "coming soon") at http://m.mesh.com and using this to upload an image and then see it appear almost instantly on your other devices is compelling.

The real power of Mesh will come with the api - then we can start to really create apps that live on and offline easily.  I am eagerly anticipating when that will be available (my guess: the PDC).  In particular I am hoping that we can plug into the framework and process files during sync - resizing images on upload for example, and then downloading the full version from another desktop on request.

For now, I am happily syncing music between devices, playing them online using the Live Desktop Silverlight Media Player, and downloading any tracks I want on demand on my mobile device ;-)

image

Ian

Technorati Tags:

Linq Performance with Generic Lists

** UPDATE * - this is messed up!  read the comments for more details...

A question came up today on MsWebDev as follows:

I have two lists of integers, each with approximately 300,000 integers in them. I need to work out which integers are in List A but not in List B.

Their first thought was to "literate through List A and ask if List B contains the current integer. If it doesn’t then I add it to a third list and return that at the end", but this was giving poor performance (10 minutes!)

The use of a Hashtable was suggested, and this gave dramatic performance improvements taking the operation down to 1 second!

 

foreach (int current in listB)
            {
                htB.Add(current, current);
            }

            List<int> cList2 = new List<int>();

            foreach (int current in listA)
            {
                if (htB[current] != null)
                {
                    cList2.Add(current);
                }
            }

 

However I was intrigued to see how Linq would perform.  The code was beautifully simple:

var cList = from c in aList
            where bList.Contains(c)
            select c;

 

And when I ran a simple test, Linq was significantly faster than the Hashtable too:

clip_image002

That is quite interesting and at some point I will investigate how it is so. 

For now if you want to play with the very rough and ready test code, you can download it from my sky drive here:

Cheers

Ian

 

Technorati Tags: ,