mapbox / mapbox-gl-native

Interactive, thoroughly customizable maps in native Android, iOS, macOS, Node.js, and Qt applications, powered by vector tiles and OpenGL
https://mapbox.com/mobile
Other
4.37k stars 1.33k forks source link

Rendering mixed-level data source #10545

Closed rinigus closed 6 years ago

rinigus commented 6 years ago

[Not sure its a right place to post this issue, please advice if it has to be moved]

I am working on adding Mapbox GL tiles support for an offline maps server OSM Scout Server (https://github.com/rinigus/osmscout-server) that would allow me to provide the tiles for rendering clients on device. While it has a great deal of overlap with the build-in offline functionality of Mapbox GL for some of the supported platforms, there are advantages of providing the tiles via that server (Mapbox GL tiles are just a part of all-in-one package covering the server functionality [rendering/search/routing]).

For offline support, I plan to distribute the first 7 z layers [0-6] as a part of world package with the rest [7-14] as packages split by territories (for example, Germany). As a result, user could select parts that (s)he needs in high resolution with the rest in low.

Now, as a result, my data source in terms of Mapbox GL style has a mixed zoom level support. There are parts which can be provided as [0-14] and parts that are provided as [0-6]. When I start zooming into the region which is covered only as [0-6] with zoom level z>=7, I get a blank map (I am using Qt bindings, but its probably related to all available bindings) and not just z=6 tile overzoomed. Is it possible to instruct Mapbox GL to overzoom the tiles if they are not available for this region? Maybe I just missed some setting (didn't have a chance to look into it in details, though).

brunoabinader commented 6 years ago

Related: https://github.com/mapbox/mapbox-gl-native/pull/10548

Also make sure that the sources and layers minzoom and maxzoom are properly set for your needs - see https://www.mapbox.com/mapbox-gl-js/style-spec/#sources and https://www.mapbox.com/mapbox-gl-js/style-spec/#layers for details.

rinigus commented 6 years ago

Great, I can test this PR later tonight. However, since its developed for speeding up the feedback, it looks to have fixed zoom delta instead of walking along zoom tree unless it gets some tile to show.

Question regarding min/maxzooms: I presume it should be 0-14, regardless to the fact that I have 0-6 in some parts, right?

rinigus commented 6 years ago

To be more specific regarding zoom levels:

For sources, I expect to set 0-14. Ideally, this would cover the parts where only 0-6 is available.

For layers, I expect to set as specified by the style - with layers going from 0 to 20.

As far as I can see, at present, Mapbox GL expects all tiles to be available in 0-14 range and there is no fallback to lower z values if some tile is missing. Would be great to have an ability to specify fallbackzoom that would be used if the tile at higher z values would not be available at particular data source.

rinigus commented 6 years ago

@brunoabinader - tested the changes in https://github.com/mapbox/mapbox-gl-native/pull/10548 together with additional proof-of-concept panZoom set to 6 for all tileZoom levels higher than 6 and used the server that provided tiles up to z=6 level. Unfortunately, while I can sometimes see the tiles from z=6, they are quickly covered with empty space (most probably when reply 404 arrived from server).

I presume that my case requires a fallback to either specified zoom (for example in the style json) or walking along z-tree by reducing z by one after a failure. It looks to me that I cannot reach the same goal by fiddling with the style file - just overdrawing low-zoom layers with the high-res tiles when available may probably result in some double land-sea edges.

rinigus commented 6 years ago

Looks like behavior of Mapbox GL JS and Mapbox GL Native is different in the aspect of mixed layer sources.

When I configured a small web server hosting the style and map page containing an example from https://www.mapbox.com/mapbox-gl-js/example/simple-map/, my mixed data source based map server was rendered depending on whether higher zoom tiles were available in cache. For higher zooms in the areas without high zoom data:

For Mapbox GL Native, always an empty tile was show,

rinigus commented 6 years ago

From reading the code, I found the way around this issue. Namely, by returning non 404 on the server side, but something else (like 418), Mapbox GL does not treat missing tile as an empty one but starts requesting the parent tiles until it finds one. An example trace from the version with debug messages:

MapboxGL requested URL: http://localhost:8553/v1/mbgl/tile?x=145&y=74&z=8
MapboxGL requested URL: http://localhost:8553/v1/mbgl/tile?x=145&y=73&z=8
MapboxGL requested URL: http://localhost:8553/v1/mbgl/tile?x=146&y=74&z=8
MapboxGL requested URL: http://localhost:8553/v1/mbgl/tile?x=146&y=73&z=8
MapboxGL requested URL: http://localhost:8553/v1/mbgl/tile?x=144&y=74&z=8
MapboxGL requested URL: http://localhost:8553/v1/mbgl/tile?x=144&y=73&z=8
[ERROR] {mapbox-qml}[Style]: Failed to load tile 8/145/74=>8 for source osmscout: HTTP status code 413
[ERROR] {mapbox-qml}[Style]: Failed to load tile 8/146/74=>8 for source osmscout: HTTP status code 413
[ERROR] {mapbox-qml}[Style]: Failed to load tile 8/146/73=>8 for source osmscout: HTTP status code 413
[ERROR] {mapbox-qml}[Style]: Failed to load tile 8/145/73=>8 for source osmscout: HTTP status code 413
[ERROR] {mapbox-qml}[Style]: Failed to load tile 8/144/74=>8 for source osmscout: HTTP status code 413
[ERROR] {mapbox-qml}[Style]: Failed to load tile 8/144/73=>8 for source osmscout: HTTP status code 413
MapboxGL requested URL: http://localhost:8553/v1/mbgl/tile?x=72&y=37&z=7
MapboxGL requested URL: http://localhost:8553/v1/mbgl/tile?x=72&y=36&z=7
MapboxGL requested URL: http://localhost:8553/v1/mbgl/tile?x=73&y=37&z=7
MapboxGL requested URL: http://localhost:8553/v1/mbgl/tile?x=73&y=36&z=7
[ERROR] {mapbox-qml}[Style]: Failed to load tile 7/72/36=>7 for source osmscout: HTTP status code 413
[ERROR] {mapbox-qml}[Style]: Failed to load tile 7/72/37=>7 for source osmscout: HTTP status code 413
[ERROR] {mapbox-qml}[Style]: Failed to load tile 7/73/37=>7 for source osmscout: HTTP status code 413
[ERROR] {mapbox-qml}[Style]: Failed to load tile 7/73/36=>7 for source osmscout: HTTP status code 413
MapboxGL requested URL: http://localhost:8553/v1/mbgl/tile?x=36&y=18&z=6

I presume it will be too much to change the current policy (404 means empty tile) which has been around for years, as far as I can see from the current code. Since a simple workaround exists, I am closing the issue as well.

brunoabinader commented 6 years ago

Thank you @rinigus for the insight - indeed to modify this behavior we'd need to change logic server-side as well.