I've been playing with Virtual Earth
a little bit like most other people probably have over the last week or so since
it was launched.
Note: This is just a sample application that I was playing with for
my own fun. Take care to read the terms and conditions for the Virtual Earth
service before you go making use of their content for any purpose beyond
playing around with it for personal use.
I was interested that the programmability for Virtual Earth (
http://www.viavirtualearth.com )
seems to be largely aimed at people building Javascript applications in the
browser. There's a library that you can reference from the website and then that
gives you a "control" that you can embed in your browser applications.
Taking a different tack, I wanted to try and write some code that would let
me make use of Virtual Earth from a Windows Forms application rather than just
from a browser and so I had a little bit of an attempt at it. I've not spent a
tonne of time on it as I started to realise that if I wanted to do it "properly"
then it was going to consume a whole tonne of time. I might come back to it and
revisit it at a later point.
This is my simple Windows Forms application;

It's hard coded to start at a particular latitude and longitude (the Statue
of Liberty) and then all it's capable of doing is of zooming in and out (via the
mouse wheel) and moving left and right (move the mouse near to an edge and then
left button click to scroll) and it'll also switch between the
Roadmap/Satellite/Combined view from the right mouse menu.
That's it. I'll probably find it useful to use for demonstration applications
in the future. There's one or two "interesting" things in the way that I built
it. The first is that it caches the tiles that come back from the Virtual Earth
servers in a couple of places. The first is that it caches them in a local SQL
Server 2005 database and it also further caches those in memory whilst the
session is active.
The way in which it works is that the Windows Form requests a "Tile" of the
image from an instance of an interface called ITileProvider which looks
like this;
public interface ITileProvider
{
IAsyncResult BeginGetTile(TileInfo tile, AsyncCallback
asyncCallback, object asyncState);
byte[] EndGetTile(IAsyncResult result);
void ChainProvider(ITileProvider chainedProvider);
ITileProvider NextProvider
{
get;
set;
}
ITileProvider PrevProvider
{
get;
set;
}
}
The idea being that the Form doesn't know where these "Tiles" come from and I
provide 3 locations where I get/store them - namely in-memory, SQL Server
2005 and then the Virtual Earth web server.
Using the ChainProvider method we can build up a list of providers
that are called in order. What I've implemented are three providers;
HashtableCacheTileProvider --> SqlTileProvider
--> HttpTileProvider
The HashtableCacheTileProvider and SqlTileProvider also
implement a secondary interface called IPersistentTileProvider which
looks like this;
public interface IPersistentTileProvider : ITileProvider
{
IAsyncResult BeginStoreTile(TileInfo tile, byte[] image,
AsyncCallback asyncCallback,
object asyncState);
void EndStoreTile(IAsyncResult result);
}
and the SqlTileProvider and HttpTileProvider both implement
this so that tiles that are ultimately returned from the Virtual Earth server
will be stored in SQL Server and in-memory whilst the application is running.
Other than that, there's not too much that's of interest in the application
but it could provide a basis for someone to take it a little further. There's a
few things that I'd add to it if I was taking it further;
1) A layered pro-active caching service on the front of the existing
cache so that when you ask for Tile X it also goes and grabs TileX-1, X+1
and so on and at other zoom levels and map types.
2) A set of classes to manage the various co-ordinate systems kicking
around inside the application. The code needs re-organising to make that
stuff simple by adding some extra classes.
3) Decent scrolling!
4) Some kind of proper Least-Recently-Used cache rather than the
HashtableCacheProvider which, ultimately, uses a lot of memory.
5) Some kind of HTTP throttling rather than just letting all HTTP calls
go straight into the asynchronous calls provided by HttpWebRequest.
That's all. The zip file (Visual Studio 2005 Beta 2 and SQL Server 2005) is
here. In the project file
there's a simple Windows Forms application, a class library and a script to run
against SQL 2005 for the SQL table and the simple stored procs.
If you do take it further then drop me a mail and let me know - bear in mind
to read those terms of use up at
http://www.virtualearth.com
Posted
Mon, Aug 1 2005 3:49 PM
by
mtaulty