Cutting Tiles for ArcGIS Server Using TileMill

There’s been a lot of talk about TileMill and CartoCSS lately, with good cause. TileMill makes it very easy generate beautiful map tiles using the Mapnik engine and CartoCSS provides a familiar method to author the cartographic representation of spatial data. As Brian Timoney points out, CartoCSS has the added bonus of making best practices shareable via copy-and-paste.

Naturally, the best way to take advantage of TileMill is to export your tiles to MBTiles and use MapBox hosting. If that’s not an option, you can pretty easily self-host with TileStream. That said, there are some organizations that, due to larger GIS workflows, IT policies, and a host of other legitimate reasons, need or choose to use ArcGIS Server to do map hosting. For those organizations, TileMill is still an option to create attractive basemaps, within certain constraints.

So I set out to see if I could bridge the gap between the two. Two blog posts pointed the way. A while back, Dan Dye blogged about how he had forked mb-util and added support for exporting WeoGeo tilepacks from MBTiles. Also, a co-worker of mine, Eric Mahaffey, had blogged some time ago about how to use Arc2Earth to manage tile caches across air-gapped networks. Using these posts for guidance, I was pretty sure I had all the pieces I needed.

First, I decided to fork Dan’s code (I love GitHub) and add support for exporting ArcGIS tiles. Essentially, I followed Dan’s pattern and added a choice for an ArcGIS schema as a command-line option. My forked version can be found on GitHub.

I then fired up TileMill (0.10.0 for Windows) and created some tiles at zoom levels 4 through 8 using the “Control Room” sample that comes with TileMill. I chose this for two reasons: First, I am not very good at cartography and this sample looks attractive and distinct from the generic ArcGIS sample I used. Second, it’s very well-known to TileMill users so it worked well for this demo. I won’t go into how I created the tiles as this post is not intended to be a TileMill tutorial.

Once I had exported the tiles to an MBTiles file, I ran the updated mb-util Python utility to export the tiles in an ArcGIS structure. The command-line usage is shown below. One note: I did not generate the “level” folders in accordance with ArcGIS convention. If you are familiar with ArcGIS, you know that the level numbers are relative so that, if your service only contains levels 3, 4 , and 5, the will be levels L00, L01, L02 respectively. Instead, the utility names them according to their original TMS levels (L03, L04, L05 in this case). So, you may need to rename your level folders when you rehost to ArcGIS Server but this should entail a maximum of 19 manual edits, which seemed like a reasonable compromise.

So mb-util created the “_alllayers” folder and its child file system for us. Because I’m not creating a conf.xml yet, I can create it by hand or use ArcGIS to create some dummy tiles with a configuration. Once that’s done, we are simply engaged in a file copy operation (picking up at step 4 of Eric’s post). For this demo, I created an actual map using one of the ArcGIS samples so that it would be apparent that the operation worked. In practice, I wouldn’t go to that much trouble up front. The image below shows the map service using the original tiles.

ArcGIS map service as created from the original MXD.

After I copied the tiles from TileMill into the correct location, I was able to refresh the window and see the boundary between the original tiles and the those from TileMill. Again, this was just for demo purposes. In practice, the whole cache would be from TileMill. The image below shows the updated cache, displayed using the ArcGIS Javascript API.

ArcGIS map service showing tiles from TileMill.

I apologize for screenshots but my EDN license precludes making my ArcGIS Server public for a live demo.

So, it’s perfectly possible to create nice basemaps using TileMill for use in ArcGIS server, provided you adhere to two constraints: 1) You use Web Mercator for your spatial reference and 2) You make sure your ArcGIS cache is the “exploded” variety.

Why would you do this? It is certainly possible to build great cartographic representations in ArcGIS but those representations are locked away in ArcGIS map documents, styles, layer packages and such; all of which are some proprietary binary format such as persisted COM objects. While this may not be the worst thing in the world, CartoCSS, being a text format, more easily lends itself to configuration control. Organizations that want to maintain configuration control over map templates and such can take advantage of standard tools such as git or SVN to do so. I have found that organizations with strict IT policies are also exactly the same kinds of organizations that to maintain control over content and styling so this is actually a surprisingly important factor.

I’ll probably play with this more as time and customer demand allow, but it’s good to know this option is available for providing flexibility with ArcGIS Server.