BruTile on Surface progress

Great to see the Microsoft Surface blog mentioning the BruTile library. It refers to my previous blog about our very first experience with the Surface back in februari. I am happy to say that since then the Surface team at Geodan has made a lot of progress building an application for disaster management as part of our Eagle suite.
The movie below demonstrates some of its capabilities. Apart from BruTile it uses the ERSI WPF controls and Bing Maps 3D as a secondary perspective.
BruTile on Surface progress

BruTile on the Microsoft Surface

Last month I had the fortune to work on one of the first Surfaces shipped to Europe. To test the Surface SDK we wrote a basic map application with pan an zoom through touch.

Using the Surface SDK’s ScatterView control it was very easy to get some touch controlled objects on the app, like a layer control. For panning and zooming we had to do a little bit more work, since we are not moving the map control itself but need to redraw the content instead. For this purpose the SDK provides the ManipulationProcessor. It is a little bit more coding but the documentation explains nicely how to do it. To top it off we added a little throw effect using the InertiaProcessor.
Our first meeting with the Surface was very enjoyable. The SDK met all our needs so far. Here is a little movie colleagues Steven and Martijn made of our first app.
BruTile on the Microsoft Surface

BruTile tiling library

Tiling is a way to store raster data as image tiles on a server so that they can be quickly retrieved by a client application. Examples of GIS clients that use tiling are Google Maps, Virtual Earth and OpenLayers. The tiles themselves are really just images sitting on a server, like this one.

A while back I added tiling functionality to SharpMapV1. Last month I extracted the tiling code to put it into a separate library, BruTile (LGPL), so it can be reused in other projects, like SharpMapV2.

With the BruTile library you can define the way the tiles are stored on the server (the TileSchema), request which tiles you need to fill a particular boundingbox up with tiles, and then retrieve those tiles from the server with a properly formatted request string. The rendering of the tiles is up to the client application. There are various protocols to store and retrieve tiles. The current implementation of BruTile only supports the Tms and WmsC protocol. I hope to support more protocols in the future like the OGC’s Wmts and Microsoft’s Virtual Earth protocol.

In the following example I describe how to draw a map onto a WinForms form using tiles.The sample uses the OpenStreetMap tile server which uses the Tms protocol. The result is the form below, no further interaction with the map is possible.

First some prerequisites. To do rendering in WinForms you need to override the OnPaint

protected override void OnPaint(PaintEventArgs e)
e.Graphics.DrawImage(buffer, 0, 0);

In it we draw a bitmap buffer onto the window. This bitmap is initialized to the window’s size in the constructor.

buffer = new Bitmap(this.Width, this.Height);

Everything else is done in the Load method. First a Transform class is created. This is used to calculate from screen positions to world coordinates and back. It is initialized to a center point somewhere in the Netherlands, a resolution wide enough to show the whole of the netherlands, and the width and height of the window. The transform class is not part of BruTile itself because something similar is already part of most GIS libraries.

Transform transform = new Transform(new PointF(629816f, 6805085f), 1222.992452344f, this.Width, this.Height);

Next you need to define how the tiles on the server are stored. The tile scheme needs a lot of information. Luckily the Tms service publishes this information. In future versions of BruTile I would like to automatically parse this info so it need not be specified on the client. So here I wont go into detail about what it all means.

private ITileSchema CreateTileSchema()
  double[] resolutions = new double[] {     
156543.033900000, 78271.516950000, 39135.758475000, 19567.879237500, 9783.939618750,
4891.969809375, 2445.984904688, 1222.992452344, 611.496226172, 305.748113086,
152.874056543, 76.437028271, 38.218514136, 19.109257068, 9.554628534, 4.777314267,
2.388657133, 1.194328567, 0.597164283};
  TileSchema schema = new TileSchema();
  schema.Name = "OpenStreetMap";
foreach (float resolution in resolutions) schema.Resolutions.Add(resolution);
schema.OriginX = -20037508.342789;
schema.OriginY = 20037508.342789;
schema.Axis = AxisDirection.InvertedY;
schema.Extent = new Extent(-20037508.342789, -20037508.342789, 20037508.342789, 20037508.342789);
schema.Height = 256;
schema.Width = 256;
schema.Format = "png";
schema.Srs = "EPSG:900913";
return schema;

Now you can request which tiles you need to fill up the entire view

ITileSchema schema = CreateTileSchema();
IList tiles = Tile.GetTiles(schema, transform.Extent, transform.Resolution);

Next you need to specify the RequestBuilder to use. In this case you need the RequestTms class because of the Tms protocol. As arguments you need to pass the url of the OpenStreetMap tile service and the format in which the tiles are stored.

IRequestBuilder requestBuilder = new RequestTms(new Uri(""), "png");

Finally we can request all tiles from the server and render them to our buffer Bitmap.

Graphics graphics = Graphics.FromImage(buffer);
foreach (TileInfo tile in tiles)
Uri url = requestBuilder.GetUrl(tile);
byte[] bytes = ImageRequest.GetImageFromServer(url);
Bitmap bitmap = new Bitmap(new MemoryStream(bytes));
graphics.DrawImage(bitmap, transform.WorldToMap(tile.Extent.MinX, tile.Extent.MinY, tile.Extent.MaxX, tile.Extent.MaxY));

The sample code above is part of the BruTile project on codeplex. The solution also includes a WPF project which demonstrates how to get a nice user experience with tile requests on a background thread and rendering tiles at the moment they arrive.

BruTile tiling library

Crayon Physics

This is just so cool! First look at the video, then think ‘wow this guy makes it look so awesome’, then download the prototype and find out it really is so awesome, and then start to think of all the cool stuff you yourself should do with such simple technology.

Apparently the full version, Crayon Physics Deluxe, will use the Farseer engine, which works with XNA and Silverlight. I really need to check that out because there are so many ideas I need to try out right now. Airhockey on the TouchTable being the first one.

Crayon Physics