mapper icon indicating copy to clipboard operation
mapper copied to clipboard

Rewrite level-of-detail handling for Android and desktop

Open dg0yt opened this issue 6 years ago • 5 comments

This is fairly complete for MapRenderables::draw(), but needs to be extented to drawOverprintSimulation() for consistency on desktop.

dg0yt avatar Dec 10 '18 09:12 dg0yt

Regarding relevance for desktops, I want to point out that OgrTemplate depends on this code, too. With complex map/template projects, being able to control the level of detail may become quite useful.

dg0yt avatar Dec 10 '18 19:12 dg0yt

Only now I had the chance to test this on my Android tablet. I tend to not merge this for master/v0.8.4, and rather come up with an improved solution for dev/v0.9 (or later). The general idea (filtering based on render config instead of per renderable) seems fine, but using/abusing pen width does not give me satisfying results, and I would rather make this a little bit more explicit.

dg0yt avatar Dec 14 '18 06:12 dg0yt

Code-wise the patch set looks good to me. I'm, however, still unsure about what is the goal for limiting the display detail level. Lemme share my thoughts on the topic anyway.

While playing with the current implementation I noticed that while zooming out some details disappear from screen at certain zoom level. That is expected. However, by that time all of my test map (1:15 000, 3 km x 2 km) is displayed on screen. That shows the filtering triggers late for any CPU cycle savings, as all the map objects have been rendered in full detail at slightly higher zoom level, and CPU load is a function of Mapper window size.

If savings are to be realized, perhaps rendering the map into a buffer and displaying the scaled buffer during zoom and pan operation might be viable. Depends whether the additional memory allocation is acceptable. Another solution might be painter path caching for individual objects.

Thanks and merry Christmas!

lpechacek avatar Dec 20 '18 15:12 lpechacek

Thanks for the feedback.

If savings are to be realized, perhaps rendering the map into a buffer and displaying the scaled buffer during zoom and pan operation might be viable. Depends whether the additional memory allocation is acceptable.

This is already implemented for two-finger zoom on Android, and adopted for all types of panning.

However, as soon as you finish the interaction, the display has to be updated, and this can take quite some time. The display is also update for each step when you use button/F7/F8/mouse wheel zooming. And this takes place on the main thread...

Another solution might be painter path caching for individual objects.

The line and area renderables are already based on QPainterPath.

The trouble is the incredible amount of renderables generated, for dashed lines, but most of all for area patterns like wine yard, and cultivated land. There are other ways to deal with these patterns, which would also reduce allocations, but I never found the time to make something else work. So for now, not even start to loop over 50000 tiny dots and line is still a very effective shortcut.

The UI in this PR is fine, but the filtering isn't. I will revert the few changes which are already in master, and tackle this in a future version.

dg0yt avatar Dec 20 '18 17:12 dg0yt

Thanks for the comments, Kai!

However, as soon as you finish the interaction, the display has to be updated, and this can take quite some time. The display is also update for each step when you use button/F7/F8/mouse wheel zooming. And this takes place on the main thread...

My proposal was to render the whole map area and display just cut outs from the large image. I know this sounds silly but this approach prevents the redraws. Code complexity and memory consumption is the price to pay.

The line and area renderables are already based on QPainterPath.

Now that I know where to look, I can see that this is already implemented. :)

lpechacek avatar Dec 21 '18 09:12 lpechacek