ThinkGeo.com    |     Documentation    |     Premium Support

V14 rendering much slower than v13

Hello. I just updated the following thinkgeo packages I’m using from v13 to v14.1.2 image
(Note: NauticalCharts, Gdal, and Kml packages could only be upgraded to v14.1.1 for some reason)

After going through and changing the old methods to the new (like Refresh() to RefreshAsync(), ZoomIn() to ZoomInAsync(), etc.), I launched the app.

By default I’m loading the common countries shapefile (about 6 megabytes) as the lowest layer.
Then there are a bunch of inmemory layers in other overlays on top.v13 vs v14.zip (1.3 MB)

Zooming in and out is much slower compared to v13. I’m not sure if there are new properties that I should be setting to fix this? Here’s what I set on the overlays:

overlay.TileType = TileType.MultiTile;
overlay.WrappingMode = WrappingMode.None;
overlay.WrappingExtent = GlobalObjects.Instance.WorldRectangleDegrees;
overlay.DrawingQuality = DrawingQuality.HighSpeed;

In v13, there was an additional overlay property called RenderMode which I set to RenderMode.Skia. But I see this was removed. Are there any gachas with this upgrade I should be on the lookout for?

I uploaded a zip containing two small videos to show what I’m seeing. the v13Rendering.mp4 file is noticeably faster than v14 with the same data. In v14, it looks like it’s rendering the bottom over top of the overlays above it initially, and then the top layers are redrawn on top of it?

Hi Dan,

The difference is that in v13, overlays are drawn concurrently, while in v14, by default, overlays are rendered one by one. In your video, the green overlay takes the most time to render, so in v14, it doesn’t start rendering the other overlays until the green one is fully completed. In contrast, v13 renders all overlays simultaneously.

In v14, you can set the DefaultOverlaysRenderSequenceType to either Concurrent or Sequential (which is the default setting) as shown below. This property is only available in the beta branches (NuGet Gallery | ThinkGeo.UI.Wpf 14.2.0-beta043), not in v14.1.2. We plan to release a new version later this month that includes this feature.

MapView.DefaultOverlaysRenderSequenceType = OverlaysRenderSequenceType.Concurrent;

In v13, we were using non-async methods (such as Refresh ) to render layers asynchronously. This led to some issues because it was difficult to determine when a layer had finished drawing.

Don’t worry about the property of RenderMode. It’s set to Skia in v14.

Thanks,
Ben

Hi Ben, thanks for the response. Just curious, what was the reasoning for drawing overlays sequentially vs concurrently? And how does it determine the order of overlays to render? Is it just “bottom” to “top”?

Hi Dan,

Using Concurrent mode is not advisable if you have numerous overlays, as this would cause the system to render all overlays simultaneously. Additionally, if the overlays share resources or are resource-intensive, it could lead to conflicts or high peak memory usage.

If you opt for Sequential rendering, the overlays will indeed be rendered from the bottom to top.

As a best practice, it’s generally better to limit the number of overlays. From the videos you’ve shared, it appears possible to combine several overlays into a single one. By doing so and then using Concurrent mode, you could enhance performance—since there would be fewer overlays—and also maintain a cleaner map appearance, with backgrounds displaying more uniformly.

Thanks,
Ben

Hi Ben, wanted to get some more clarification on this. V14 adds a bunch of async methods, but you’re saying the overlays are rendered one by one? That doesn’t make sense to me. I would assume they could be rendered independently of each other.

Hi Dan,

Most async methods are run one by one, if you do

await RenderOverlay1Async()
await RenderOverlay2Async()

The overlay2 will be rendered after overlay1 even both are rendered asynchronously.

Instead, if you add both of the renderring tasks to a list and do
await Task.WhenAll(tasks)

Then the 2 overlays will be rendered simultaneously.

Which part doesn’t make sense to you?

Thanks,
Ben

Previously you said the above. Does the default zoom/pan not render the overlays simultaneously?

Hi Dan,

Correct, the zoom/pan also respects the property MapView.DefaultOverlaysRenderSequenceType, which by default is Sequential. We default it to this to be conservative (to avoid high memory peak or racing conditions as mentioned above), and the users can easily make it concurrent.

And by the way here are something more about Zoom/Pan:

  1. Zooming:
    After the zooming animation(stretching the existing tiles), users can choose to immediately show the overlays while they are rendering, or wait until all the overlays finished rendering. You can switch between them by setting MapView.StretchMode (ShowNewTilesOnStart by default):

    public enum MapViewStretchMode
    {
     /// <summary>
     /// After stretching existing tiles, new map tiles are shown immediately as they start rendering.
     /// This mode allows for a more dynamic and responsive user experience by incrementally
     /// displaying new tiles as soon as they are available.
     /// </summary>
     ShowNewTilesOnStart = 0,
    
     /// <summary>
     /// After stretching existing tiles, new map tiles are shown only after all new tiles have finished rendering.
     /// This mode ensures a consistent view by waiting until all new tiles are ready, avoiding incremental updates.
     /// </summary>
     ShowNewTilesOnComplete =  1
    }
    
  2. Panning:
    In MultiTile Mode, the drawn tiles will not be redrawn during panning. Only the new tiles will be rendered.

Thanks,
Ben

Hi Dan,

Just for your information, we are doing the test / code review for v14.2 release and decided to default to:

MapView.StretchMode = MapViewStretchMode.ShowNewTilesOnComplete;
MapView.DefaultOverlaysRenderSequenceType = OverlaysRenderSequenceType.Concurrent;

This is better for simple projects. However, for projects with a large number of overlays, OverlaysRenderSequenceType.Sequential could be a better choice.

Thanks,
Ben

Hi Ben, thanks for the information! I’ll test out those two properties you mentioned. I’m using around 10 overlays. All of these contain static layers, but one overlay contains a layer with very fast updates that moves a point around the map. My worry was that this point would not be displayed if it was waiting for other overlays to render.

I’m curious, is there any kind of built-in mechanism with overlays where I could force them to only refresh at specific intervals?

Hi Dan,

10 overlays sounds a bit too many. You can consider merging multiple static layers into one overlay if possible to improve the performance. Also don’t forget to use cache for the static overlays. And don’t worry, all the overlays will be displayed even they are rendered fast.

We used to offer interval refresh APIs like Overlay.RefreshAsync(TimeSpan bufferTime) , but we’ve deprecated them and will be removing them soon. We found that there are many different use cases, and it’s much more flexible for users to manage interval refreshes themselves. For example, if you’re refreshing the map every second and the first refresh isn’t finished before the next one starts, you can choose to cancel the first, skip the second, wait for the first to finish, or handle it in another way that fits your needs.

Since all async APIs in ThinkGeo now have an overload that accepts CancellationToken , you can easily set up a timer for interval refreshes, use the cancellation pattern, and achieve the same functionality with complete control.

Thanks,
Ben

Thanks for the info Ben! What is the reason for keeping Overlays low? I believe I started using ThinkGeo back in version 10. Overlays are what I used to group related layers together. For instance, I might have 5 pointshape layers, so they are in a single point overlay. Same with lines and polygons. Then separate layers for “types” of data like KML, databases, etc. Are you suggesting that’s not a good practice? I’m not sure how the internals of the overlay rendering works.

Hi Dan,

Each Overlay behind the scenes is an independent image costing resources to store and manage. We want to reduce the number of those images if possible. For your case, you can put all the points layer, as well as line and polygons into one overlay, it would boost the performance.

So when do we need to use multiple overlays? the answer is when certain layers have different drawing tactics than others. For example, if you have 10 layers, 9 of them are for static background and one of them is “dynamic” something like a moving vehicle. In that case we put the 9 static layers to one overlay and put the vehicle to another overlay, which allows us to only redraw the vehicle when needed.

I hope that make sense. Let me know if you have more questions.

Thanks,
Ben

1 Like

Thanks Ben, appreciate it all the information!

Sure, no problem! Just let us know if you have any questions.

Hi Ben,

For you guys it’s just a simple change. But me unfortunately is has a great impact.
We have a lot of overlays in out database (over 300). Many times users have way more than 10.
For us it had a great impact and I have been searching what part of my code was nog proper Async/Await anymore, because of the terrible responsivenes of the map.

I think this setting does not have any impact on simple projects, so I don’t understand the choice.

I’m glad I found this post, so I can make my users happy again.

BTW With zooming the overlays are rendered one by one on the screen (the map is build up per layer).
With panning the new tiles are only visible when all overlays have been rendered.
Is it possible to have the overlays also become visible one by one when panning?

Kind regards,
Guido van den Boom (NL)

Hi Guido,

Do you mean it became less responsive when upgrading from v13 to v14 switching to async APIs which draw the overlay one by one? Each overlay is drawn asynchronously so drawing them sequentially would be slower than concurrent drawing but should not make the map irresponsive anyway, meaning for example you should pan/zoom even before the drawing is finished. Please let me know if you see otherwise.

Or do you mean after zooming or panning it waits for all overlays to finish rendering before updating? Would you prefer that the overlays begin to display as soon as each one is ready, rather than waiting for all to complete?

There are more settings opened up after zooming to async APIs, sorry it’s not what you expected. As mentioned earlier in the post the following settings are by default in v14.2.

MapView.StretchMode = MapViewStretchMode.ShowNewTilesOnComplete;
MapView.DefaultOverlaysRenderSequenceType = OverlaysRenderSequenceType.Concurrent;

“I think this setting does not have any impact on simple projects, so I don’t understand the choice.”
which setting specifically were you referring to? It’s the above default settings, or something else?

For v14.2, setting MapView.StretchMode = MapViewStretchMode.ShowNewTilesOnStart will cause overlays to display one by one during both zooming and panning. Additionally, using multitile ensures that tiles already displayed will not be rerendered.

And at last, 10 overlays sounds like a bit too many, we talked about it earlier in the post how it affects the performance, please check it out see if that helps with your scenario.

Thanks,
Ben