The Virtual Earth Web Services are Slow

I’ve been experimenting with the Virtual Earth Web Service for integrating mapping into a WinForms and/or WPF application.  The set of services, released in the latter half of last year, provides a well defined api for accessing some of the powerful capabilities of the VE platform.

Initially I didn’t set my ambitions too high – I just wanted to render a map.  To get started I needed to reference the four VE services (Geocode, Imagery, Route and Search (actually I only needed the Imagery service initially but added all four so I didn’t have to add them later).  These are all WCF services with details for both staging and production urls detailed here. I also needed to add a reference to the Common service, which is a traditional asmx web service – more information here

With the references to the VE services in place in went looking for the service I needed to call in order to retrieve a single map.  Turns out this is a function called GetMapUri that is part of the Imagery services.  In order to call this service I first needed to generate a token that is used to get access to the service.  This token is based on my credentials which I got after signing up for a staging account (more info here).

TokenSpecification spec = new TokenSpecification()
               {
                   ClientIPAddress = GetIPAddress(),
                   TokenValidityDurationMinutes = 60
               };

CommonService service = new CommonService();
service.Credentials = new NetworkCredential(Properties.Settings.Default.Username,
                                                             Properties.Settings.Default.Password);
virtualEarthToken = service.GetClientToken(spec);

 

Note that accessing the token service takes time, so it is best to cache the token for the full duration that the token is valid for.  In the above code the token is valid for 60 minutes.

The next thing to do is to build up a MapUriRequest object, which includes information about the map (ie center, zoom), as well as the image you want (ie width and height) and of course your token.

MapUriResponse mapUriResponse = imageryService.GetMapUri(mapUriRequest);

The mapUriResponse contains a property, Uri, that is the address of the image I wanted generated.

One thing I noticed is that this process is very time consuming.  Initially I thought it was the token service – I was calling this every time I wanted to refresh a map.  But after caching the token it was still taking a while for each map uri to be returned (30-60 secs in some cases).  This led me to look at the format of the returned uri.  Essentially the following code will generate a similar string that is much quicker and seems to work [Disclaimer: as I understand it, this is not a supported scenario and whilst it is significantly quicker than calling the imagery service, the format may change without notice]

return string.Format(@"http://staging.tiles.virtualearth.net/api/GetMap.ashx?c={0},{1}&w={2}&h={3}&z={4}", center.Latitude, center.Longitude, width, height, zoomLevel);

The big question is – why is it so slow for the Imagery service to do string.format and return me the uri of the image?  I’m guessing it could be either that it’s running on staging (and thus low resources), that it does more than just a basic string.format or some other reason.  Either way, the fact that it is so slow completely discourages developers from using it and encourages rouge behaviour (eg using String.Format to generate the uri).

Leave a comment