Using BruTile and MapsUI to Enable WeoGeo Previews

A few weeks ago, my company announced the availability of the first beta version of WeoGeo Tools for ArcGIS. Unlike the previous version, which opened a separate browser window, this new release allows a user to order a data set from WeoGeo Market or a library from inside ArcMap.

One of the challenges was enabling data set previews. If you browse data sets using the WeoGeo online tool, you can get an idea of what the data set contains by using the data set preview images supplied by the data set provider.

When we developed the first version of WeoGeo Tools for WeoGeo, they used kamap to create preview tiles for data sets. This was accomplished by used either one of two desktop tools: the weoapp (command line) or gWeoApp (GUI). The first version of WeoGeo Tools used the weoapp in the background to create tiles when uploading data.

In between the two versions, WeoGeo switched to a ZYX tile structure similar to Google Maps or TMS (although not always using spherical mercator). This change made the idea of integrating ordering much easier.

Part of the challenge was implementing support for preview tiles in a manner that provided a smooth user experience inside ArcMap. Luckily, my experience with SharpMap pointed the way. It’s been a while since I’ve blogged SharpMap but, in the intervening time, the project added support for map tiles by way of another .Net-based open-source project called BruTile. It was through SharpMap that I was first exposed to BruTile and the two projects have developed something of a symbiotic relationship.

A while back, BruTile branched, with its UI aspects being spun off into another project called MapsUI. Between these two projects, I had what I needed to added support for WeoGeo previews. I’ve been building the UI elements of WeoGeo tools using Windows Presentation Foundation (WPF) from the beginning. MapsUI provided exactly what I needed in a simple WPF map control to embed tile support into my application.

Order window showing preview tiles for Maryland census tracts

Because WeoGeo chose well-known tiling schemes for their previews, most of what I needed was already there. For data sets with preview tiles in spherical mercator, there was already a BruTile schema defined for working with Google Maps that I could leverage. For tiles in WGS84, there was also a schema defined based on the work documented at the MapTiler site (which is the same schema WeoGeo uses for WGS84 tiles).

The primary customization that was required was to create custom request classes that formatted tile request URLs for WeoGeo. To get a tile from WeoGeo, you need to know two pieces of information in addition to the Z, Y and X positions of the tile: you also need to know the data set (identified by a GUID) for which you want tiles and the file format (JPG or PNG) of those tiles. So you end up with a URL that looks like this:

http://weodata.weogeo.com/dataset_tiles/{dataset_token}/xyz/{Z}/{Y}/{X}.{format}

Beyond the request, you can fine-tune the tile schema by using information from the data set metadata to set the tile extent and remove unused scale levels. For spherical mercator tiles, for example, I defined custom tile source, tile schema and request classes that defined these additional pieces of information. The result was the ability to very easily create a TileLayer for use by the MapsUI control:

[sourcecode language=”csharp”]
//_dataSet is deserialized from JSON and contains the data set metadata

//Create schema based on data set format, min and max scaled and tile extent
var weoSchema = new WeoGeoSchema(_dataSet.TileFileFormat, _dataSet.Scales[0], _dataSet.Scales[_ds.Scales.Count – 1], new BruTile.Extent(_dataSet.Boundaries.Tiles.West, _dataSet.Boundaries.Tiles.South, _dataSet.Boundaries.Tiles.East, _dataSet.Boundaries.Tiles.North));
var weosource = new WeoGeoTileSource(new WeoGeoRequest("http://weodata.weogeo.com", _dataSet.Token, _dataSet.Scales[0], _dataSet.Scales[_dataSet.Scales.Count – 1], _dataSet.TileFileFormat), weoSchema);
var tl = new TileLayer(weosource); //the layer to be added to the map control
[/sourcecode]

Using BruTile, this aspect of adding support for ordering went very quickly and smoothly. I like that they have native WPF UI components as I generally avoid using WinForms anymore when doing Windows desktop development. There’s a lot of good work between BruTile and MapsUI and I’ll be using these tools more in the future.