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("http://a.tile.openstreetmap.org"), "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

The Target

Played location based game The Target in Utrecht last sunday. And the news is, it is a real location based game, it works and it is fun.

The Target is played with 4 nokias with gps. Each nokia is manned with a team of 2 or 3 players. One team is the target, the others are agents hunting for it. To win the target has to collect one million by stealing money at several predefined locations over town. The agents have to catch the target to prevent it.

The game designers did a nice job keeping the game very simple yet fun. The players have a shoot button with which they can kill the enemy when within a certain range. Further, they can collect several types of items (e.g. knife, lorry, ladder) which are placed on several spots over town. With those items they can robe money at other locations. But for each robbery a different combination of items is needed. When the target takes an item the agents get a message stating which item was taken. But because every item can be found at a number of different locations it leaves a number of alternatives. In practice the agents spend a lot of time guessing where the target is, what he is up too, and which items he will go for next. At some interval the agent and target also get the know the exact position of their opponents.

The good things about this game are:
– Simple user interface. The user controls the game mostly through the way they move over town. You can make choices by walking to specific location on the map, with little need for buttons.
– The playing area is a fixed square in the center of town. This is represented with a fixed map on the Nokia. Although you can zoom into each of the 16 parts of the map this is not really necessary. This keeps it simple.
– Partial information about what is going on. The concept of the items needed for a robbery is great. It leaves enough room for guessing and enough information to make a fair guess.
– You rent the game for 2 hours actual playing. The game keeps track of the time so it only measure actual playing time and you do not have to worry about when to bring it back.

Not so good:
– It is basically a running game. Real fast runners will do best. I can imagine that for some people this is too demanding. You need players with a sports mentality. We happened to have a number of those in our group but even for them it took some effort to get into sports mode on a cold day walking around in heavy clothing. I would love to play this game again on a sunny day dressed in my running outfit.
– When an agent is far removed from the target the game is not so interesting anymore. It becomes harder to motivate oneself for running. Maybe the agent should have some alternative things to do in those cases.

The Target

Code Conventions

The main reason to have code conventions within your developers group is that it can stop the discussion about code conventions. For some reason those discussions never converge on mutual agreement. In my environment the topic has not come up for a while, I like to keep it that way, but secretly I try to stick to some my own code conventions.

I have been following these rules

1) If you work on existing code adopt whatever conventions they seem to be using
2) If code conventions differ from file to file use the conventions of that file don’t work toward conventions throughout the library.
3) If you start anything new, go with the flow. Do whatever the majority is doing (spaces not tabs) or what big guys do (for c# I try to stick to the Microsofts guidelines, see this too).
4) If for some (maybe good) reason you defer from the convention, do not invent a rule why you did this, just say you were lazy.

BTW, so please don’t tell anyone this, because it could start the discussion again.

Code Conventions