1. Introduction + WebAPI for map tiles
2. Visual Studio Online
3. Loading data to Vector Tiles
4. Rendering image tiles
5. CDN Caching for map tiles
6. Adding Units and Basic Interaction
7. Attacks and Explosions
8. Performance checkpoint
9. Bootstraping
10. Real-time with SignalR
11. Persistence and Authentication
12. Scaling up the loader process
13. Polishing the experience
2. Visual Studio Online
3. Loading data to Vector Tiles
4. Rendering image tiles
5. CDN Caching for map tiles
6. Adding Units and Basic Interaction
7. Attacks and Explosions
8. Performance checkpoint
9. Bootstraping
10. Real-time with SignalR
11. Persistence and Authentication
12. Scaling up the loader process
13. Polishing the experience
Work-in-progress: https://site-win.azurewebsites.net
New iteration, tons of new stuff:
- Create a mixed-approach for the problem of having data pre-generated vs generated on-the-fly
- Binary Vector Tiles
- Render image tiles
- Blending with Bing Maps
- Improved loader process to fix/optimize roads and railways
So, let me explain each of these items:
Create a mixed-approach for the problem of having data pre-generated vs generated on-the-fly
On my previous posts I presented one of my major concerns: choosing a proper data-store for the hexagon data. I thought about Redis, Table Storage or eventually pre-generating the whole lot: both vector tiles and image tiles.
On my last post I was tending to just generate the vector tiles and generate the image tiles dynamically. As I was implementing it I had an even better idea:
- Store the vector tiles for the furthest way zoom level (in my case 7) on the Azure blob-storage.
- Then, when a zoom level other than 7 is requested, simply dividing consecutively by 4 provides the required tile, due to the nature of the map-tiles.
Reference: Bing Maps Tile System |
Just to provide some comparison data on the impact of this, if I stored the whole world in zoom level 7 that would correspond approximately to 20.000 tiles, which is pretty reasonable. Storing everything until level 13 (which is what I plan to support) would require about 90.000.000 tiles. But even worse than the space occupied would be the time required to generate all these tiles. Without a proper infrastructure it could take months, with the added impact of making changes nearly impossible.
Performance-wise I'm currently quite happy with the loader process. Loading terrain, altitude, roads, railways, forests, country-info and urban areas for Portugal (including persisting the vector tiles on Azure Blob Storage) takes about 30 seconds. Not brilliant but not a bottleneck. Eventually loading big countries like the United-States could take a couple of hours.
Note: To optimise it even further I only store the vector-tiles that contain any data. Eventually, when I've mapped the whole world, only about 1/3 will require tiles as 2/3 is water.
Binary Vector Tiles
On my first approach the vector tiles were being stored on Azure Blob Storage as text/json. I then changed the implementation to also support binary data. The results were satisfactory: less size occupied on the blob storage (and on the wire when uploading) and faster serialization/deserialization. I still support the JSON format but the default is now the binary one.
Added Drawing-logic to generate image tiles
On my previous post I've described what a vector tile is. For example, a simple one:
http://tile-2.azurewebsites.net/v2/tile/11/975/785.json
Inspecting the content one can see that it has various info, including a road element (with a numerical element that represents a mask with the edges that are crossed by the road)
http://tile-win.azurewebsites.net/v2/tile/11/975/785.png
Other examples of image tiles generated on-the-fly based on the Vector Tiles:
http://tile-win.azurewebsites.net/v2/tile/10/491/388.png |
http://tile-win.azurewebsites.net/v2/tile/8/122/95.png |
http://tile-win.azurewebsites.net/v2/tile/11/974/779.png |
http://tile-win.azurewebsites.net/v2/tile/9/245/193.png |
I'm currently supporting:
Forests
Roads, including intersections. I'm currently just loading motorways.
Altitude information, currently shading the hexagons according to this value. In the short-term I'm going to do something different, eventually on my next blog post.
Railways, following a similar logic to the roads
Urban areas. This is a little bland and I'm not exactly sure on how to make this represent urban-like stuff.
The most basic info of all: land.
I've got tons of other ideas, like displaying labels, cities, borders, administrative areas.
Blending With Bing Maps
As I've mentioned above, I only generate hexagon tiles from zoom level 7. Below that (i.e, with lower zoom levels) the hexagon edge size wouldn't even be 1 pixel wide thus not making much sense to display them. Thus, one of my concerns was:
"What map layer should I display between zoom level 0 and 6?"
I thought on various alternatives, including generating my own tiles from real vector data (using TileMill / Mapnik) or splitting a real satellite image. Anyway, the most important requirement was tha between zoom 6 and 7 the transaction needed to be as seamless as possible.
Then I had a cool idea:
Between zoom levels 7 and 10 blend my hexagons with the Bing Maps colors on the the various components: water, land, forests and roads.
So, here's the effect while zooming out:
Unaltered |
Colours start fading |
The hexagons are now much brighter, mostly noticeable on the forest hexagons. |
Most of the colours are now pretty much similar to the Bing maps ones |
The hexagon layer is hidden and the Bing Maps imagery is displayed |
Still not perfect but good enough for now.
Improved loader process to fix/optimize roads and railways
One of the problems that I had with the roads and railways was the fact that, as the hexagons have a finite range of options for displaying roads it's incredibly likely that lots of strange hexagons are generated, particularly as the process is totally automatic.
A picture is better than a thousand words, so take a look a this example. Portugal is actually a great candidate for this problem as it has an incredible amount of motorways given its small size:
I've created a "road-fixer" process that cleans-up the roads. After execution the same area now looks like this:
Not perfect but MUCH better.
I've deployed all of this on Azure.You can try it out at: http://site-win.azurewebsites.net/Map/V2 (link no longer working)
Note: Randomly some tiles are generated without any data. That's a GDI+ problem that I haven't yet fixed
A picture is better than a thousand words, so take a look a this example. Portugal is actually a great candidate for this problem as it has an incredible amount of motorways given its small size:
I've created a "road-fixer" process that cleans-up the roads. After execution the same area now looks like this:
Not perfect but MUCH better.
I've deployed all of this on Azure.
Note: Randomly some tiles are generated without any data. That's a GDI+ problem that I haven't yet fixed
No comments:
Post a Comment