Thursday, August 20, 2015

As time flies by, we are closer and closer to the end of this year's Google Summer of Code. I had a lot of fun and learned many things this summer thanks to the program. My main field of interest is computer graphics and rendering, so working on a project focused on this was a great challenge for me, that I think I barely - due to some unexpected events - but somehow, overcame.

Speaking of what I learned, there are just too many things to list, but if I have to name three things, I would say: Qt, the basic geography and the math related to it, but there are so many more beside those. For example I struggled during almost the entire summer to implement an acceptable form of street name labeling in real time, performance-wise and looks-wise. I realized that there is almost a whole field of study dealing with it. But more on that later.

Improvements made this summer

Decorations

Implementing the decoration system for the GeoDataGraphicsItem class was my favourite task, because this class (and those derived from it) is responsible for the OSM Vector Tile rendering in Marble. This decoration system is responsible for the outlines of the streets and highways and for the - now even further improved - (fake) 3D building rendering.

Street and building decorations visible on a loaded .osm file in Marble.

A close-up from the previous picture.
The improved building decoration is visible more visible here
(top right corner, bottom left cornet)

The best thing about these decorations is that every GeoDataGraphicsItem can be improved this way. After some refactoring and improving the solution since midterms, a GeoDataGraphicsItem nowcan have multiple decoration, decorations can have decorations, which can have multiple decorations, so there is more potential for further improving the rendering of these items.

Street labels

As I mentioned above, getting the best results for the street name label placement was a pretty hard task. Not because it is hard to understand the principle, the math behind it is not that difficult, but because we needed it to work in real time with almost no performance impact on the rendering. This was further complicated by the fact that Qt doesn't provide a function to draw text along curved paths. Finally I came up with a solution, then another, then another, then ... , and now we have a pretty good looking (but in the future improvable) implementation. Additionally I had to implement some style setting functionality for these labels, like color and font settings.

Before my work on this project. Street labels are "just there".

The latest version. Text along curved paths is drawn now.

The funny thing is when your solution has 200 lines of code, but the results don't satisfy you in terms of performance, so while improving the same code several times you get a much better performance and result with only cca. 40 lines of code in the end. This happened to me with the task above :)

Better zoom with the mouse wheel

When I first tried out Marble, I was a little disappointed by the blurry zoom on the openstreetmap map theme. The program downloads the texture tiles used on the openstreetmap website and then projects them with the current projection (the one used by openstreetmap is the Mercator projection). In my project proposal I had an intention to fix this, so when I saw a comment on my first blog post requesting this fix I was sure that this is a pretty needed one.

After some work on it I completed the fix. I even made a little video demonstrating it, but in some days you will be able to try it out yourself. The second part of the video shows the rendering improvements on a new, empty map theme.

Improving printing support

Making Marble dpi-aware (and so preparing it for better printing)

I told you in my previous post that I will start to work on improving Marble's printing support, but this proved to be a pretty big task for the remaining time, because first we need to make Marble more dpi-independent. This is needed because if we just simply scale up the map to a higher resolution, then every icon and text will be much smaller in proportion to the original map. This could be overcome if we change Marble's internal dpi resolution before painting. Another argument along this task is the fact that this summer Marble was successfully ported to Android by Gábor Péterffy and developing an application for a smart-phone always comes with the struggle of the UI's dependenccy on the screen's dpi resolution (density).

I already made Marble recognize the current dpi resolution of the screen and to respond to it's change(e. g. when printing). Next step will be to supply Marble with icons and bitmaps for different dpi resolutions (ldpi, mdpi, hdpi at least). I look forward to working on this in the next months, and if we achieve more progress, I'll let you know in a next blogpost.

Other minor improvements

Several color style tweaks and changes in the OSM Vector Tile rendering, my goal was to match the default color style on the openstreetmap website.

When my time allowed I was looking for unincluded OSM map features, like highway=cycleway, highway=pedestrian, highway=road etc. and added them to the list with the right style.

I've created a simple empty map theme to load, view and edit these .osm files, though it's mainly for developer purposes.

Some bug fixes and refactoring in the source code.

Some finishing words

Before I started, I was pretty confident in my programming skills, I had experience with Qt and C++, but looking back from now I see that there is a lot more to learn for me than I thought. And I think this is one of the most beautiful things to realize: to realize that you can learn new things as long as you are willing to.

I'm glad that I got such a great project to work on. If the Google Summer of Code program's goal is to encourage people (students) to work on open source projects in their free time even after the end of summer, then the Marble team is one which definitely achieved this goal with me. I look forward to work with them in the future, maybe I'll join some other KDE projects too :)