August ended and so did the coding for GSoC. Now all the pieces have to fit perfectly and that’s what we are working on. By the time writing this entry, all the code has been submitted to review and some of the parts have already been included in Marble’s master branch.
Here are the review requests for parts in which the code has been separated:
Extension for the .osm file parser
Kothic Json parser for vector data tiles
New dgml tag , with its parser and new GeoScenes
Remaining code changes>
So for this entry, I will summarize all the process done during this GSoC and how the new features work.
- Teaching Marble a new tag for it to create vector tile layers.
A new tag <vectortile> has been added to the dgml parser. When using it to create a vector tile layer, the backend needs to be set also to “vectortile” (just the same as when we use another tag like texture (for image tiles), filter…)
Booth <vectortile> (for data tiles) and <texture> (for image tiles) tags, extend an abstract class called GeoSceneTiled which contains the common information for tiled layers and then each one creates its GeoSceneVectorTile or GeoSceneTextureTile.
Tests where made with Kothic’s JS tiles hosted on http://osmosnimki.ru/vtile. These tiles have a JSON-P-like format similar to the one OSM Data Tile Server will have (http://wiki.openstreetmap.org/wiki/Google_Summer_of_Code/2012/Data_Tile_Service/Tile_Format)

{
“scale”: 100,
“features”: [
{"geometry": {
"type": "Point",
"coordinates": [50, 50] },
“properties”: { “color”: “orange” }
},
{ “geometry”: {
“type”: “LineString”,
“coordinates”: [[25, 25], [75, 25], [75, 75]]},
“properties”: { “color”: “blue” }
},
{“geometry”: {
“type”: “Polygon”,
“coordinates”: [ [[10, 50], [50, 90], [10, 90], [10, 50]],
[[20, 70], [20, 80], [30, 80], [20, 70]]] },
“properties”: { “color”: “green” }
},
{ “geometry”: {
“type”: “MultiLineString”,
“coordinates”: [
[[80, 10], [80, 0]], [[100, 20], [90, 20]]] },
“properties”: { “color”: “purple” }
}
]
}
OpenStreetMap’s server still is not ready but once it is, only minor changes will be needed.
Here’s the dgml example:
<layer name=”vectorosm” backend=”vectortile” >
<vectortile name=”geojson_data” expire=”604800″ >
<sourcedir format=”JS”> earth/vectorosm </sourcedir>
<tileSize width=”256″ height=”256″ />
<storageLayout levelZeroColumns=”1″ levelZeroRows=”1″ maximumTileLevel=”18″ mode=”OpenStreetMap” />
<projection name=”Mercator” />
<downloadUrl protocol=”http” host=”osmosnimki.ru” path=”/vtile/” />
<downloadPolicy usage=”Browse” maximumConnections=”20″ />
<downloadPolicy usage=”Bulk” maximumConnections=”2″ />
</vectortile>
</layer>
Important tags:
backend: Needs to be set to “vectortile” just like when we use other tags like “texture” or “filter”. When trying to create the layer it will check that the inside tag (in this case <vectortile>) is the same as the backend value.
expire: Sets in seconds when a tile will expire, in other words, when it will be considered as outdated and downloaded a new version of it.
format: Currently the format is not taken into account as the layer will try to open the file with all the available parsers in Marble. But if in the future this seems to be a bad idea, only the parser able to open this file format could be used.
sourcedir: folder where the tiles will be downloaded.
tileSize: tile size is needed in order to calculate which zoom level is being displayed and tiles that have to be downloaded to fit the screen. For OpenStreetMap tiles, its 256×256.
For this piece of code to work, (as also is needed for OSM images layer) you will need to create a base 0 tile inside the maps folder. Here’s a new earth map based on atlas layer and this vector data layer that can be used. by extracting the zip file into maps/earth/ folder. (Note that this will only work once all the code has been merged to Marble’s branch).
EXAMPLE VECTOR TILE MAP FOR MARBLE
- Now that a new layer has been parsed, it’s time to create it.
Marble already had a TextureLayer class for downloading and mapping the image tiles and depending on the selected map projection (Globe, Plane Map or Mercator), called a different image mapper (EquirectScanlineTextureMapper, MercatorScanlineTextureMapper or SphericalScanlineTextureMapper) that does different operations to generate the world’s image.
For data tiles, all vector data is inserted into the maps TreeModel (a class inside MarbleModel that renders vector data) and this class already manages projection changes. In addition, logic for vector tile downloading and storing is different (due to the amount of memory vector data needs compared to images). So in this case a new class VectorTileLayer completely independent from TextureLayer has been created.
When creating or changing the map theme, MarbleMap will ask if the new selected theme has any GeoSceneTiled. If it does it will iterate through them and by checking their <backend> tag it will distinguish between an image tile layer (texture) and vector tile layer (vectortile) adding them to the layer manager.
- How VectorTileLayer works.
It has the logic for downloading, rendering and managing vector tiles. The main problem with this is the amount of memory and process it needs. The layer has a pointer to the maps TreeModel (the class that renders vector data) and an extra cache that will store all the tiles that are being displayed in screen in each moment.
When the map is moved every tile that doesn’t intersect with the screens bounding box will be removed from the extra cache and theTreeModel, to avoid having to process geometries that are not inside the screen. Tiles are only removed from the extra cache, not deleted because they will be also in Marble’s main cache.
Everytime the map is moved or updated, the layer will calculate if the zoom level has changed and if it did change, all tile geometries will be removed and new tiles for the new zoom will be loaded by calling VectorTileMapper class. If the zoom didn’t change, it will check the screen and tile’s intersection to remove not displaying tiles as previously explained.
- VectorTileMapper downloads data tiles.
Image tile layers use different mappers depending on the maps projection but for vector tiles, changes between different projection are already managed by the TreeModel so only one mapper is enough. When the map is moved, VectorTileMapper will calculate the new screens X and Y. Comparing them to the previous ones it will know in which direction the map has been moved, download the required tiles and create a StackedTile. Marble’s main tile cache uses the class StackedTile to store tiles.
- StackedTile “wraps” image and vector tiles.
The StackedTileLoader stores tiles, manages them and launches their download if missing or expired. In the beginning it only supported image tiles but now StackedTile supports two types of tiles TextureTile and VectorTile. Booth extend the Tile class, created to contain the common attributes from a tile such as format or tile ID. Then TextureTile contains an image and VectorTile geometries.
When a tile is missing, StackedTileLoader calls MergedLayerDecorator to download it, by looking at the GeoSceneTiled’s nodetype() method it chooses between creating a TextureTile (if it is a GeoSceneTextureTile) or a VectorTile (if it is a GeoSceneVectorTile) and it wraps it inside a StackedTile.
Some demos of how it works:
As you can see not all the tiles have been created yet.
There are tiles up to 5MB size and it takes a little to load them and move the map. With the new OSM server, tiles will be about 200KB big.
There are still some little changes that I want to work on but if anyone wants to know more about how vector tiles work or why some things have been made in a certain way they can contact us on IRC #marble channel (ander) or ander.pijoan(at)deusto.es
I would also like to thank everyone involved in the project, all the KDE and Marble community and specially my mentor Earthwings, Tackat, Idis, Shentey, Cezar, Javi and all the anonymous people who share their knowledge on the net.

















