Published by breki on 29 Sep 2008
Kosmos And Large Maps
This weekend I was playing around with Kosmos by trying to load large maps (by “large” I mean country-size large). I have never really done this before, since I was more concentrated on smaller areas when I developed the software.
The initial results weren’t really encouraging – Kosmos managed to load the OSM extract of Austria (25 MB of .osm.bz2 file), but the GUI was burning around 1 GB or RAM and it took some time to load. Then I got into investigating how this could be improved.
I managed to do a few things which greatly improved the performance:
- OSM tags were stored as C# generic Dictionaries (for each OSM element). This is a problem, since typically there are no more than few tags for an element. It turns out the ListDictionary class is better suited for small dictionaries, since it uses linked lists instead of hash tables.
- A lot of memory was being taken by “created_by” tags for each OSM node. Since this tag isn’t really much used when rendering maps, I decided to ignore it when loading OSM files (OSMXAPI ignores it too, by the way). This can save a lot of space, since most nodes do not have any other tags – which means the tags dictionary doesn’t even have to be created for such a node.
- Immediately after loading the map, the garbage collector is now called to dispose of any temporary objects. I know, GC isn’t supposed to be called manually by applications, but I guess in these extreme circumstances it can be forgiven – especially since it frees up several MB of RAM immediately.
- The last thing to do was to write a custom OSM XML loader. Until now I used XmlSerializer classes autogenerated from OSM XSD. This has several disadvantages: you have to load the whole OSM file into memory in order to (de)serialize it and also produces a large quantity of intermediate objects which then have to be translated into “proper” OSM objects. But by writing a custom loader which reads XML sequentially (using XmlReader) both of these obstacles can be overcome. Still, writing XML parsing using XmlReader isn’t easy (in fact is real pain in the you know where).
Anyway, after these modifications Kosmos loads Austria data more quickly and with much less memory footprint (around 400 MB). It’s still a slow experience on my machine (E6400, 4 GB RAM), but at least it’s improvement.
I tried to load progressively larger country extracts – the largest one that did load so far without throwing the OutOfMemoryException was France (54 MB). The screenshot above shows Czech Republic (43 MB).
NOTE: by doing this I wasn’t really aiming to achieve some kind of “planet coverage” with Kosmos – it’s virtually impossible for Kosmos GUI to draw the whole planet interactively. But I would like for non-interactive Kosmos Console at least to be able to generate tiles for larger areas (UK or Germany, for example, or even the whole of Europe) in some reasonable time – but there’s a lot of things to do before this is possible. I guess the first steps have been made…






