OpenLayers: How to detect the map view is completely loaded?
Asked Answered
F

4

13

I'm implementing map exporting functionality using OpenLayers 3.

But there is one problem: one cannot determine whether the map view is completely loaded or a few tiles is missing yet.

It seems there is no such API or event. The close one is tileloadstart - tileloadend pair. But OpenLayers loads tiles asynchronously, and before the tile is actually loading the tileloadstart is not fired - that is, a tile that is queued in the tile queue does not fire the event before actually loading.

Hot can I detect the map view is completely loaded?

Felten answered 16/12, 2015 at 11:58 Comment(0)
F
4

I eventually implemented the export function successfully. Below is the rough explanation.

  1. Register tileloadstart, tileloadend, tileloaderror event handlers on the ol.sources using ol.source.on(), and start managing the tile load count.
  2. Register postcompose event handlers on the ol.Map using ol.Map.once().
  3. call ol.Map.renderSync(). This triggers the tile loading, so from now if there is no tile loading, it will mean that all tile have been loaded.
  4. On postcompose event handler, capture the map content from event.context using event.context.canvas.toDataURL(), and register postrender function using event.frameState.postRenderFunctions.push() (a bit hacky).
  5. On the registered postrender function, check the tile load count (which can be managed by the tileload* event handlers). If the count is not zero, abandon the captured content. Else, the capture is done.
  6. On tileloadend and tileloaderror, if the tile load count becomes zero, retry from the step 3 above.
Felten answered 5/12, 2017 at 1:36 Comment(1)
I second the above comment. A code example would be great.Klos
L
16

postrender event seems to do the trick, like this:

map.once('postrender', function(event) {
    doyourmagic();
});

Works at least from OpenLayers 3.8.2. There is fine answer there about the subject.

Liggins answered 14/4, 2016 at 6:57 Comment(2)
keep in mind this will also be triggered every time the map moves.Melatonin
If you use once like this example does it will only be triggered once whereas map.on('postrender'... would trigger every time the map moves until it's taken off with unDomain
F
4

I eventually implemented the export function successfully. Below is the rough explanation.

  1. Register tileloadstart, tileloadend, tileloaderror event handlers on the ol.sources using ol.source.on(), and start managing the tile load count.
  2. Register postcompose event handlers on the ol.Map using ol.Map.once().
  3. call ol.Map.renderSync(). This triggers the tile loading, so from now if there is no tile loading, it will mean that all tile have been loaded.
  4. On postcompose event handler, capture the map content from event.context using event.context.canvas.toDataURL(), and register postrender function using event.frameState.postRenderFunctions.push() (a bit hacky).
  5. On the registered postrender function, check the tile load count (which can be managed by the tileload* event handlers). If the count is not zero, abandon the captured content. Else, the capture is done.
  6. On tileloadend and tileloaderror, if the tile load count becomes zero, retry from the step 3 above.
Felten answered 5/12, 2017 at 1:36 Comment(1)
I second the above comment. A code example would be great.Klos
E
4

Meanwhile, OpenLayers provides a much sought after rendercomplete event which may be handy.

Ezequieleziechiele answered 30/1, 2019 at 12:54 Comment(0)
A
1

Basically to make sure everything is rendered on your map you need to listen for loadend events for each layer you have on the map. For wms and wfs layers this is clear and I guess you know how to do it. For the tile layers , check this example here

Attire answered 17/12, 2015 at 11:41 Comment(1)
tileload* events do not work for this problem. Since the tile queue manager queues the tiles asynchronously for loading, event if there is no tile loading it does not necessarily mean that all tiles are loaded.Felten

© 2022 - 2024 — McMap. All rights reserved.