DrawStatus changes on LocationDisplay

530
7
01-11-2024 01:14 AM
sveinhal
New Contributor II

I'm using .onDrawStatusChanged to observe when the map is loading and not. While the status is .inProgress, I'm showing a spinner. There are two problems with this approach:

  1. When the spinner is stopped, that causes the area below the spinner to be redrawn, which changes the status from .completed back to .inProgress, which causes the spinner to come back into view, ad absurdum. 
  2. When the user's LocationDisplay "blue dot" is moving, this causes the status to change to .inProgress. In practice, this means that the spinner is always showing. 

Questions:

  • Is this the right approach to indicate to the user that the map is loading or can I use some other mechanism to more accurately grab loading state? Back in the 100.x days, I used AGSNetworkActivityDelegate and showed/hid the spinner in response to networkActivityInProgress and networkActivityEnded
  • The first problem, I've been able to mitigate by delaying the showing of the spinner by a short time.
  • Can I somehow make the location display independent of the draw status?
0 Kudos
7 Replies
Ting
by Esri Contributor
Esri Contributor

Hi Svein, thanks for the question and welcome to Esri Community (for Swift 😉)!

Before we come up with an answer, I'd like to know what are the exact conditions that you want to show a spinner for the map/scene view?

There are many stages for a map/map view to be "loaded" - loading a map from a portal over network; drawing the map view - basemap tiles, features, and more; waiting for the panning animation to stop on a map view; waiting for the viewpoint change animation, etc.

Depending on what you want to show a spinner on, there might or might not be a variable currently available. From there our engineers can provide more thoughts.

I'd like to add that for most cases when you aren't using a huge dataset (with 10k+ features, for example), the "loading" time would be minimal. So depending on the usecase, a spinner might not be a must have.

Thanks!

sveinhal
New Contributor II

Thanks for your answer. We are developing a mobile app for use in the forestry industry with relatively large number of layers, and used over relatively slow networks. That is, spotty cellular reception deep inside the forest, far from public infrastructure.

The maps are often available offline, but we do also support online maps, which are often very slow. In fact, we must assume that the maps are very slow, and both loading layer metadata, as well as individual tiles, are error prone.

An entrepreneur is using our app to harvest timber, and need to be relatively sure that the map in front of them is accurate, finished drawing, and up-to-date. A layer may e.g. be showing endangered species' habitats, or culturally significant spots that are illegal to driver over with heavy forestry machinery, due to regulatory reasons. Or property borders, and the entrepreneur cannot harvest timber from a neighboring property, due to legal reasons. 

We can use layer state to know if the layer itself is loaded, visible, and without errors or warnings, but we can't use it to tell (as far as I can tell) if the viewport is finished rendering. This can sometimes take several seconds, sometimes part of the requests even time out (in which case drawing is complete, but we'll see warnings, methinks)

Typically the user will pan the map around with their finger, and a spinner is displayed as the map loads tiles and rasters, until finally coming to a rest a some time later, and the spinner goes away.

If we remove the "blue dot", or the user is looking at an area that does not include himself, the `drawStatus` seems to work as expected. Ideally, I think I'd like to have the layer state include some kind of tile loading status.

0 Kudos
sveinhal
New Contributor II

Here's an example of user interaction.

Notice as the user pans the map, the spinner appears. After about 30 seconds, the map would seem "done", had it not been for the spinner. But there are still about 15 more seconds of loading/drawing afterwards.

These extra seconds of the spinner does nothing to the map, since all tiles that are loading happen to be empty, but the spinner give the user important clues that the map is indeed not done loading yet.

 

Ting
by Esri Contributor
Esri Contributor

Thank you for the details. This is an issue that we've logged before but haven't revisited for a while. The reason why the location display triggers a draw status change is that, the blue dot itself is rendered as a symbol-graphic, which also goes through the rendering pipeline, so it triggers an update whenever it redraws.

I'll keep you updated as our team discuss the potential fixes in the SDK. Meanwhile, workarounds might be either don't show the location display, or disconnect the data source, while the data is loading. However, they are not ideal fwiw. Ultimately we need to fix it in the SDK.

sveinhal
New Contributor II

For now, we've solved this in the network layer, by pipelining map layers through a proxy, and keeping track of incoming, outgoing and cancelled requests. This is not ideal, but it works as long as we only show one map view at a time.

0 Kudos
Ting
by Esri Contributor
Esri Contributor

After some discussion here are a few things…

  • We won't be releasing a fix to this problem in the next release 200.4. Currently we don't have available developers for redesigning the APIs in this area.
  • In order to get this request prioritized, we encourage you to contact Esri Technical Support at https://support.esri.com/en-us/contact . By getting a support ticket, the issue will gain more priority in our next release planning.
  • In term of the fix, there are 2 different directions…
    • While the current onDrawStatusChanged behavior is not aligned with what you expect, after some debate we still find it kind of making sense, as the location display is also part of the rendering.
    • Therefore, we won't make change to this existing event handler, but possibly provide an alternative to it that doesn't include the location display updates.
    • From your user story, it seems the ultimate goal is to decide whether all the data (metadata, vector tiles, feature table, etc.) are loaded. While the draw status may report completed, it is possible that under bad network, some data might fail to load and give warnings, while the draw status can still become completed in the end. Ideally we need a way to report if every resource in the map is fetched over the network successfully, which we don't have right now. So I think your workaround actually makes more sense than using the draw status.
  • We'll take the "all data loaded" event into consideration for future development.
sveinhal
New Contributor II

@Ting wrote:

From your user story, it seems the ultimate goal is to decide whether all the data (metadata, vector tiles, feature table, etc.) are loaded. While the draw status may report completed, it is possible that under bad network, some data might fail to load and give warnings, while the draw status can still become completed in the end. Ideally we need a way to report if every resource in the map is fetched over the network successfully, which we don't have right now. So I think your workaround actually makes more sense than using the draw status.

We also display warnings and errors to the user, so there should be no question whether the map is "complete" or not.

  • We'll take the "all data loaded" event into consideration for future development.

Thanks for your update. Given that we have a working workaround, I'm not going to use my limited influence to try to convince you to spend your also limited developer resources on this for now. 

0 Kudos