Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix bug preventing full map from rendering when viewport is < 512px #3055

Closed
anandthakker opened this issue Aug 23, 2016 · 23 comments · Fixed by #9028
Closed

Fix bug preventing full map from rendering when viewport is < 512px #3055

anandthakker opened this issue Aug 23, 2016 · 23 comments · Fixed by #9028

Comments

@anandthakker
Copy link
Contributor

mapbox-gl-js version: master

Steps to Trigger Behavior

  1. Create a map using, e.g., Mapbox Streets, in a div that is smaller than 512x512.
  2. Zoom 'all the way out' (i.e. initialize the map to center: [0, 0], zoom: 0

Expected Behavior

The whole world is shown.

Actual Behavior

The whole world is not shown.

Repro: https://bl.ocks.org/anandthakker/raw/0e9afc1d09356f87449b5ffa3e49bd82/

@anandthakker
Copy link
Contributor Author

From what I can tell, Leaflet behaves essentially the same way (for containers smaller than 256x256).

@lucaswoj @mourner do you think the 'correct' solution here is basically to handle negative zoom values?

@eddydg
Copy link

eddydg commented Jan 12, 2018

Any news on this bug?
Using mapbox on a tile-base design page often leads to tiles smaller than 512x512.

@juho-hanhimaki
Copy link

juho-hanhimaki commented Jul 18, 2018

We find this behavior troublesome for our mobile users as the devices are usually between 320px and 400px wide in portrait view.

Rotating the device landscape allows the user to see larger area of the globe longitude wise (polar regions aren't that important for our users). However the app is rarely used in landscape so its not natural experience for the user.

So we hope this can be improved in the future.

@charliemcgrady
Copy link

Is preventing the entire world from appearing on small screens expected behavior?

I want to show clusters which span the entire world. It's a confusing UX to not have all the pins / clusters appear at once.

This is how my map currently looks:
Screen Shot 2019-04-10 at 7 30 28 PM

For reference, this is how mapbox.js + Leaflet handled this case:
Screen Shot 2019-04-10 at 7 24 16 PM

There are some downsides to showing the full world. Specifically, the grey area above and below the map look strange. I think the ideal option is to add a configuration value for disabling this behavior.

@supersteves
Copy link

I don't suppose anyone at Mapbox can give any idea for if and when this is likely to be resolved. Our use case is a world map potentially any size below 512 on a mobile device, and it must fit an arbitrary region of the world. We are currently considering whether we need an alternative library and it would help if we knew a fix was around the corner (or not).

@chloekraw
Copy link
Contributor

@charliemcgrady, thanks for the screenshots. Is that <512px map interactive, or is its purpose to link to a larger interactive map in the mobile app/website?

@supersteves could you give us some more information about your use case as well? If I'm understanding correctly, it is possible to currently show "an arbitrary region of the world" on a <512px map, just not one that shows the entire world.

@supersteves
Copy link

@chloekraw Thanks for responding so promptly.

Our app allows users to place charts on a page. The chart has the user's data, and fits/zooms to show all their data. The page scales to fill any device - a big PC screen, down to a small mobile - using configurable rules regarding responsiveness. As such a map can easily be under 512px on-screen. Consumers of this report can then filter data and the zoom adapts dynamically, so you cannot try to solve this problem by designing your page layout in a specific way.

So if the user places a map and happens to have data points spanning the entire global lat and/or lon range:

  • you only see a small part of the zoom=0 tile at 100% scale, there is no way to show a scaled-down world below zoom 0
  • if the map placement (i.e. viewport) is a letterbox or pillarbox aspect, and the region of interest (zoom) is a different rectangular shape/aspect, you cannot see the entire region of interest. (I want to see a letterbox or pillarbox effect with some plain fill outside the mercator bounds) - In dev speak, it's as if the map is using a 'cover' rather than 'contain' css background-size property, were the map a simple image.

At entire-world level, I'm not fussed about having a -1 and -2 (for example) tile which has been rendered with labels and line widths appropriate to that zoom level. I'll easily settle for the ability to simply scale-down the zoom-0 tiles using a simple transform, but have markers sized correctly on top (I don't want to simply use a CSS transform on the entire map, as marker size would be inconsistent across zooms).

@supersteves
Copy link

By the way we are a commercial licensee.

@charliemcgrady
Copy link

@chloekraw - It's an interactive map with clusters (similar to https://docs.mapbox.com/mapbox-gl-js/example/cluster/). The clusters are for photos taken around the world.

I want the map to show the entire world on mobile - my user testing has shown that users are not aware of (i.e. do not navigate to) sections of the map which do not appear initially on mobile.

Thanks for the response!

@krispy-visokio
Copy link

@chloekraw can you please give us an estimate of if/when this is likely to be fixed. CSS transforms are not going to work unless we can find an easy way to ensure markers/labels are not effected.

@krispy-visokio
Copy link

Can anyone provide an update on when/if this is likely to be fixed please?

@chloekraw
Copy link
Contributor

chloekraw commented Sep 27, 2019

@supersteves @charliemcgrady thanks for all the context! Helpful for us to understand the problem. We're planning to address this bug this quarter and are aiming to have it fixed before the end of the year.

@supersteves
Copy link

@chloekraw Great news! I wonder how you intend to solve it - simply downscaling the zoom zero tile, without down-scaling marker overlays etc.? Or introducing negative zoom vector tiles? We'd be happy with either.

@chloekraw chloekraw added this to the release-t milestone Oct 1, 2019
@chloekraw
Copy link
Contributor

@supersteves, we don't know yet, that will be part of our investigation of this issue when it's picked up in one of our sprints. Will keep you posted when we have a clearer proposal.

@supersteves
Copy link

Great, thanks.

@ryanhamley
Copy link
Contributor

ryanhamley commented Nov 15, 2019

I've done some investigation on this issue and there are some significant conceptual issues and downsides to implementing this.

The reason that the entire world cannot be shown in a div that is less than 512px wide by 512px tall is because GL JS uses tiles which are that size. Any div smaller than that will necessarily cut off part of the tile. Leaflet uses 256x256 tiles which is why their maps can display the entire world in a smaller div than GL JS.

In order to show an entire tile in a div smaller than 512x512, we'd have to effectively zoom out to a negative zoom level. This creates a couple of undesirable trade-offs. We could expose negative zoom levels and allow the map to move to -1 zoom (which corresponds to a 256x256 tile) but this is extremely unintuitive, messy and as far as i know not done by any other map service. Having a hash of -1/0/0 is pretty awkward. It also is a breaking change because all zoom-dependent styling up to this point has depended on 0 being the lowest zoom level so negative zooms will break many styles.

Alternatively, we could "underscale" a tile in an analogous way to how we "overscale" tiles as we move between discrete zoom levels or show tiles past their max zoom. The issue this introduces is that overscaling also increases the actual zoom level so underscaling theoretically should decrease the zoom, but this brings back negative zooms. You could imagine artificially clamping the display zoom at 0 but this is also highly unintuitive. The map would look like it's zooming even though the zoom doesn't change. And how far should a user be able to zoom out at zoom 0? Should this be optional behavior? It's not obvious.

Finally, there's two other considerations. First, it seems like no other map service shows the entire world at arbitrarily small sizes. Testing on an iPhone, the major map services seem to not be able to display the world at 0 zoom. On a Mac with the window sized down, they either don't show the entire world or they turn into a globe, but even on the globe, you can only see one hemisphere at a time. That doesn't mean we shouldn't do this, but it's something to consider. More importantly though, this may conflict with changes we want to make when we implement 3D maps. I know there are going to be changes to the way the camera works among other things.

I'm wondering if something like a scroll indicator would work better to indicate to users that there is more to the map in small containers. This is probably not something we'd implement in the library but I could put together a small example.

cc @vakila

@supersteves
Copy link

Thanks for investigating. Does this issue still arise regardless of basemap? Presumably the 512 tile size is an architectural hardcode regardless of basemap?

@ryanhamley
Copy link
Contributor

@supersteves That's correct. The 512 tile size is an internal architectural detail of GL JS. It is possible to have raster tiles of a different size (the Mapbox Satellite style uses 256 tiles for example) but we effectively scale them up by one so that at 0/0/0 you actually see 4 tiles that form a 512px view of the entire world, as shown below. GL JS isn't set up to display 256x256 tiles that display the entire world.

Screen Shot 2019-11-15 at 12 51 05 PM

@supersteves
Copy link

Thanks again @ryanhamley. I think I can read between the lines and conclude this is unlikely to be implemented, ever. Probably a proper support for negative zooms is the way to go, but I can understand the complexity of the URL syntax. We'll have to fix this ourselves by down-scaling via a CSS transform, or using a specialist mapping library, for this scenario.

@chloekraw
Copy link
Contributor

@supersteves @charliemcgrady @krispy-visokio @juho-hanhimaki @eddydg

Thanks for providing your feedback on this issue! We have a proposal up that renders maps with the camera at a negative zoom levels (up to -2) in containers <512px when zoomed out all the way: #9028

With this change, much more of the world is rendered, but the behavior does not exactly match what's possible on mapbox.js + Leaflet, in part due to the limitations @ryanhamley outlined here. I've pasted a few visual examples below.

Questions:

  • Would you consider this change to solve enough of your use case such that you don't feel the need to implement additional workarounds?
  • If not, would you still consider this change to be an improvement from the current behavior?

Examples:

With #9028, the amount of the world that's shown depends on the aspect ratio of the viewport in containers <512px. Even when zoomed out all the way, the map will still fill the vertical space of the container. For example:

Screen Shot 2019-11-26 at 3 03 43 PM

image

This would be instead of the following behavior, which was originally requested above:

Screen Shot 2019-04-10 at 7 24 16 PM

@supersteves
Copy link

Wow. This seems like a workable solution. To solve the last screenshot, could one shrink the height of the mapbox instance?

@ansis
Copy link
Contributor

ansis commented Nov 27, 2019

Wow. This seems like a workable solution. To solve the last screenshot, could one shrink the height of the mapbox instance?

Yep, the change lets you zoom out far enough to see the entire height of the map. Not necessarily the entire width.

@ansis
Copy link
Contributor

ansis commented Nov 28, 2019

1.6.0-beta.1 has been released with this fix if you are interested in testing the fix:
https://api.tiles.mapbox.com/mapbox-gl-js/v1.6.0-beta.1/mapbox-gl.js

The final release should come next week.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

10 participants