Skip to content

Clean up initial map load, disable zoom animation#168

Closed
easbar wants to merge 3 commits intomasterfrom
clean_up_initial_map_load
Closed

Clean up initial map load, disable zoom animation#168
easbar wants to merge 3 commits intomasterfrom
clean_up_initial_map_load

Conversation

@easbar
Copy link
Copy Markdown
Member

@easbar easbar commented Nov 22, 2021

Instead of actually fixing #162, which seems not so trivial, I thought we could just disable the 'zoom to info bbox' feature entirely for now. The info bbox is always equal to the entire planet view anyway, except for local development with smaller maps. We could re-consider this for example in #117, but right now the initial page load seems a lot more important, especially because we also still need to decide which map library we should continue working with (#159).

Therefore, I disabled the viewport update that is triggered by the /info endpoint here. I also disabled the viewport transition animation to reduce the initial map flickering as much as possible. Reloading a url that includes points still does not work perfecty though, because for raster tiles we still see a very quick view transition from the world view to the route bbox. To get rid of this maybe we even have to delay the map loading until we received the route response(?).

@easbar
Copy link
Copy Markdown
Member Author

easbar commented Nov 22, 2021

Reloading a url that includes points still does not work perfecty though, because for raster tiles we still see a very quick view transition from the world view to the route bbox. To get rid of this maybe we even have to delay the map loading until we received the route response(?).

Maybe we could just parse the url first, and then choose the bbox given by the parsed points as initial map view. Even without actually calculating the route first.

@karussell
Copy link
Copy Markdown
Member

To get rid of this maybe we even have to delay the map loading until we received the route response(?)

Yes, I think this is the only way to avoid this when points are specified. (For the old GH maps the world wide view still loads but shows up only very quickly and so it is not really disruptive.)

@easbar
Copy link
Copy Markdown
Member Author

easbar commented Dec 4, 2021

(For the old GH maps the world wide view still loads but shows up only very quickly and so it is not really disruptive.)

For this PR it is kind of the same, but unfortunately we see the world view a bit longer compared to GH maps 1 and it is therefore more distracting. Strangely, I see a blurred 'Deutschland' label when I use a route in Germany, as if some intermediate tiles between the world view and the route bounding box were loaded. At least this happens for a longer route like this:

http://localhost:3000/?point=52.933932%2C9.936341&point=48.786663%2C12.418884&profile=bike&layer=OpenStreetMap

But for a shorter one like this:

http://localhost:3000/?point=49.131117%2C12.296425&point=48.786663%2C12.418884&profile=bike&layer=OpenStreetMap

it seems fine and I do not even get to see the world view. For the ol_exp branch (OpenLayers) it is similar. I also briefly see the world view and the blurry 'Deutschland' label.

Yes, I think this is the only way to avoid this when points are specified.

I think you are right. First I thought we could just estimate the bounding box from the url points before we send the route query. Unfortunately it is hard to get a good estimation for this in all cases. It turns out that the tricky thing is that if we do not get a good estimate for the bounding box from the url points and then update the map view again when the routing request returns we are at risk of loading even more tiles than we would load if we did not try to estimate the bounding box at all. This is because the higher level tiles are larger than e.g. the world view tiles, because they show far more details.

I tried delaying the map rendering until the route request returns using Mapbox here:
a9c51b2
and using OpenLayers here:
22ac0c3
With these changes I no longer see any map flickering in both cases.

You can compare this here:
http://gh-maps-react.s3-website.eu-central-1.amazonaws.com/master/?point=51.73643%2C9.512061&point=50.722208%2C10.517404&profile=bike&layer=OpenStreetMap
http://gh-maps-react.s3-website.eu-central-1.amazonaws.com/load_map_after_route/?point=51.73643%2C9.512061&point=50.722208%2C10.517404&profile=bike&layer=OpenStreetMap
http://gh-maps-react.s3-website.eu-central-1.amazonaws.com/ol_exp_render_map_after_route/?point=51.73643%2C9.512061&point=50.722208%2C10.517404&profile=bike&layer=OpenStreetMap

Compared to master there is no longer an animation from a larger to the route bbox view for load_map_after_route. We only load the tiles we actually need to show the route bbox. ol_exp_render_map_after_route does the same using OpenLayers.

Note that my implementations are more of a hack to try this out. For example we won't see a map at all if the route request fails, e.g. if one of the points cannot be found. We would have to implement this more thoroughly and probably this is also related to #167. I think we need the following logic:

  1. Load /info. If there is no response show the world map with a clear error (the app won't work when there is no routing backend)
  2. load /route if there are url points and delay the map rendering until we receive the route bbox. If there are either no url points or if the route request fails show the /info bbox.

But unfortunately, even with this approach there is a problem: When we add the custom model editor we have to deal with requests that take a lot longer than what we are used to right now. This might mean that delaying the map rendering until the initial route request returns will no longer be an option. Or we need to show some kind of loading animation for this case and maybe show the map for a preliminary bounding box that is based on the url points for such slow requests.

@karussell
Copy link
Copy Markdown
Member

karussell commented Dec 5, 2021

Thanks for this!

But unfortunately, even with this approach there is a problem:

Ah, indeed this is problematic and also the implementation seems to be rather tricky.

and maybe show the map for a preliminary bounding box that is based on the url points for such slow requests.

Yes, sounds good. This would also (often) reduce the required animation time and might reduce flickering even when enabled for fast returning routes? (And for the most routes the initially loaded map tiles won't change due to the route geometry.)

Another possibility is to store the current bbox in the URL. And if none exists in the URL we load the bbox from /info. And if we calculate a route and auto zoom to it we attach this bbox to the URL or update the old. This way one could share the URL with an arbitrary bbox (could be seen as an advantage :) ).

@easbar
Copy link
Copy Markdown
Member Author

easbar commented Dec 5, 2021

This would also (often) reduce the required animation time and might reduce flickering even when enabled for fast returning routes? (And for the most routes the initially loaded map tiles won't change due to the route geometry.)

I'm not sure. Like I said, first I thought it is a good idea to use the url points as a first estimation, but when I tried this I found that even when the final bounding box only changed a bit there was still some kind of flickering effect and many more tiles were loaded. I just meant for slow routing request we might have no other option if we don't want to show the map at all until the route was calculated. But this would make the implementation a lot more complicated indeed.

Another possibility is to store the current bbox in the URL. And if none exists in the URL we load the bbox from /info. And if we calculate a route and auto zoom to it we attach this bbox to the URL or update the old. This way one could share the URL with an arbitrary bbox (could be seen as an advantage :) ).

Yes, this could be a very good solution indeed. Would you keep the url in sync with the camera position all the time? Qwant Maps does this too. They store the zoom level and center point, which might be the easiest option, but I also wonder how this works when sharing urls between devices with different screen sizes:

https://www.qwant.com/maps/#map=13.24/47.2111331/7.2227028

And yes, this way it would be possible to share a location even without calculating a route. For GH maps 1 we were able to do this with a single marker: https://graphhopper.com/maps/?point=51.404036%2C13.521234. For maps 2 this does not work as well, because the map is zoomed out to the world view currently: https://graphhopper.com/maps2/?point=51.404036%2C13.521234

@easbar
Copy link
Copy Markdown
Member Author

easbar commented Dec 5, 2021

Like I said, first I thought it is a good idea to use the url points as a first estimation, but when I tried this I found that even when the final bounding box only changed a bit there was still some kind of flickering effect and many more tiles were loaded.

I just pushed this here: 5aff626 and you can try it here:

http://gh-maps-react.s3-website.eu-central-1.amazonaws.com/clean_up_initial_map_load_estimate_bbox/?point=51.73643%2C9.512061&point=50.722208%2C10.517404&profile=bike&layer=OpenStreetMap

Actually, now it does not look so bad to me anymore?!

@easbar
Copy link
Copy Markdown
Member Author

easbar commented Dec 5, 2021

... and to complete this little collection here is the version where we estimate the bbox from the url points using OpenLayers: 844d7d5

http://gh-maps-react.s3-website.eu-central-1.amazonaws.com/ol_exp_estimate_bbox/?point=51.73643%2C9.512061&point=50.722208%2C10.517404&profile=bike&layer=OpenStreetMap

@karussell
Copy link
Copy Markdown
Member

but I also wonder how this works when sharing urls between devices with different screen sizes

The center and zoom should solve this (?) and would be probably better than my proposed bbox.

One question then is when we store a new history state (for back button vs. up-to-date URL).

I just pushed this here: 5aff626 and you can try it here

Nice 👍

But indeed it loads further tiles and cancels the older ones. Wouldn't have this expected for most cases.

btw: Unfortunately it does not fix the problem for the mapbox version that when you open the URL in a background tab it does not update to the bbox of the route compared to the situation when you open it in a foreground tab. (the OL version does not have this problem)

@easbar
Copy link
Copy Markdown
Member Author

easbar commented Dec 6, 2021

The center and zoom should solve this (?) and would be probably better than my proposed bbox.

Not necessarily, because the visible map area depends not only on the center and zoom, but also on the map size (in pixels). So it could happen that the zoom level that is calculated on a larger screen is too large (too far zoomed in) to show the entire route on a smaller screen.

One question then is when we store a new history state (for back button vs. up-to-date URL).

Yes, good question, but maybe we can just not create a history state when we zoom/pan the map, but do create a history state whenever we calculate a new route?

But indeed it loads further tiles and cancels the older ones. Wouldn't have this expected for most cases.

As long as the older ones are canceled it should be ok (?). Can you notice a difference in performance for all these approaches and also Mapbox vs. OpenLayers?

Unfortunately it does not fix the problem for the Mapbox version that when you open the URL in a background tab it does not update to the bbox of the route compared to the situation when you open it in a foreground tab

When I right-click and choose 'Open Link in New Tab' it works, but not when I use the middle mouse button of my laptop:

http://gh-maps-react.s3-website.eu-central-1.amazonaws.com/clean_up_initial_map_load_estimate_bbox/?point=51.73643%2C9.512061&point=50.722208%2C10.517404&profile=bike&layer=OpenStreetMap

No idea why, but this could be something unrelated? I also don't know what the difference between using the middle mouse button and choosing 'Open Link in New Tab' is. The tab is opened in the 'background' in both cases. And yes, for the OL version it works for both Mapbox and OL.

This 'estimate bbox from url points' approach seems like the easiest thing we can do right now and at least it is an improvement over the current master? But yes, it is still not ideal. The next best thing is probably storing the camera state in the URL.

@karussell
Copy link
Copy Markdown
Member

karussell commented Dec 6, 2021

Not necessarily, because the visible map area depends not only on the center and zoom, but also on the map size (in pixels). So it could happen that the zoom level that is calculated on a larger screen is too large (too far zoomed in) to show the entire route on a smaller screen.

Ah, ok. Now I understand what you mean. Yes, indeed. So the bbox is better in this regard as we can say that the specified bbox should be taken as the minimum bbox.

Yes, good question, but maybe we can just not create a history state when we zoom/pan the map, but do create a history state whenever we calculate a new route?

Yes, still we would have to update the URL as otherwise the shared URL is something different. Or we have a separate "share" button like before. (probably unavoidable due to the custom model anyway)

As long as the older ones are canceled it should be ok (?)

It is a bit an overhead we could avoid but yes this should be fine.

Can you notice a difference in performance for all these approaches and also Mapbox vs. OpenLayers?

between the mapbox versions: not really.
between the openlayer versions: not really.
between mapbox and openlayers: openlayers seems to be a bit faster (and mapbox is still ugly for rasters ;) )
Could it be that for mapbox the routes are sequentially drawn after the map is drawn? And openlayers draws the routes as fast as it gets them and then somehow is able to plot the map later. So OL feels more responsive. (comparing here "estimate_bbox" branches)

No idea why, but this could be something unrelated?

It also occurs in master and is unrelated but I thought that it was related to how master handles the bbox and hoped it was fixed here.

This 'estimate bbox from url points' approach seems like the easiest thing we can do right now and at least it is an improvement over the current master? But yes, it is still not ideal. The next best thing is probably storing the camera state in the URL.

Yes and yes :)

@easbar
Copy link
Copy Markdown
Member Author

easbar commented Dec 7, 2021

Ah, ok. Now I understand what you mean. Yes, indeed. So the bbox is better in this regard as we can say that the specified bbox should be taken as the minimum bbox.

Yes, better in this regard, but also a bit more complicated, i.e. we need to calculate the bbox all the time using the center point, zoom level and current screen width/height. But that should be doable.

Yes, still we would have to update the URL as otherwise the shared URL is something different

Yes, but this has always been like this. When we calculate a route in GH maps 1, and then change the camera position and share the url, our updated camera position won't be included.

Or we have a separate "share" button like before. (probably unavoidable due to the custom model anyway)

Yes, probably. This is related to: #25

between mapbox and openlayers: openlayers seems to be a bit faster

Ok, my main motivation for this PR was to get rid of any overhead, like the additional zoom to the info bbox and the zoom animation so we can rule out these factors to be the cause of the slow map loading. If OpenLayers is still faster with these changes that is an argument against Mapbox.

(and mapbox is still ugly for rasters ;) )

Do the rasters look ugly only in your Browser or also on your phone?

Could it be that for mapbox the routes are sequentially drawn after the map is drawn? And openlayers draws the routes as fast as it gets them and then somehow is able to plot the map later. So OL feels more responsive. (comparing here "estimate_bbox" branches)

I don't know why the route rendering is so slow.

@karussell
Copy link
Copy Markdown
Member

Do the rasters look ugly only in your Browser or also on your phone?

Yes, I think the reason is that mapbox allows the partial zoom

Actually, now it does not look so bad to me anymore?!

Feel free to merge this as this is certainly an improvement over master.

@easbar
Copy link
Copy Markdown
Member Author

easbar commented Dec 8, 2021

Yes, I think the reason is that mapbox allows the partial zoom

I thought on my iPhone it's not as bad as on my Laptop. Maybe because of different screen resolutions and maybe this means we could improve this also for Desktop still. But the issue with the partial zooming will remain anyway (I think).

Feel free to merge this as this is certainly an improvement over master.

I opened #171 now. Will leave this here as is for later reference. Closing for now.

@easbar easbar closed this Dec 8, 2021
@easbar easbar deleted the clean_up_initial_map_load branch January 19, 2022 09:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants