mapbox / mapbox-maps-android

Interactive, thoroughly customizable maps in native Android powered by vector tiles and OpenGL.
https://www.mapbox.com/mobile-maps-sdk
Other
466 stars 131 forks source link

Satellite Styles don't work on an Offline map #1460

Closed ghost closed 1 year ago

ghost commented 2 years ago

Environment

Observed behavior and steps to reproduce

When using the offline map functionality with Satellite or Satellite Streets styles, the rasterised tiles appears as black squares. This results in the entire map being black in the case of the Satellite style, or the streets being overlayed on a black background for Satellite Streets.

To reproduce:

Screenshots:

Screenshot_20220627-130812 Screenshot_20220627-131115

Expected behavior

The Offline functionality should work with Satellite styles. The docs for Offline functionality don't give a reason why Satellite styles wouldn't work on an Offline map, and the restrictions it does give wouldn't exclude Satellite styles.

dudeuter commented 2 years ago

@ShigotoMitame Raster Sources aren't fully supported within TileStore at the moment. They can only use the same API surface as v4 vector tiles.

If you change your source to reflect this, you can get raster tiles to start rendering.

ghost commented 2 years ago

They can only use the same API surface as v4 vector tiles.

I'm not sure what you mean here. I was under the impression that the satellite tiles did use the V4 API? Or are the vector and raster APIs different?

If you change your source to reflect this, you can get raster tiles to start rendering.

Can you give an example on how to do that?

dudeuter commented 2 years ago

@ShigotoMitame Here's the documentation for Sources if you configure the tiles attribute to fetch tiles from the same source as the raster tiles stored in TileStore you should be able to get it working.

One thing to note for anyone reading this is that this is just a workaround for the time being. Normally your satellite source will reference mapbox://mapbox.satellite, which will fetch the TileJSON, which has all of the URL templates for satellite imagery. The renderer will then decide which is the most suited for the current device, overriding this will force the renderer to use the same tiles for each device. This may result in some extra API calls/memory being used. You should determine if this is the correct solution for your project.

maclne commented 2 years ago

@dudeuter caching of satellite imagery works fine on the MapBox for iOS, but not Android. Is the Android SDK just lagging behind a bit?

dudeuter commented 2 years ago

@dudeuter caching of satellite imagery works fine on the MapBox for iOS, but not Android. Is the Android SDK just lagging behind a bit?

Are you referring to caching? Or creating Offline Regions with Raster sources?

ErikOutside commented 2 years ago

@dudeuter I am also observing this issue while using "mapbox://styles/mapbox/satellite-v9" from the Style.SATELLITE constant as the styleURI in my TilesetDescriptor. The TileStore seems to download the tile regions successfully, however, it won't use the cache data when reloading Mapbox with the same Style.SATELLITE as the styleUri parameter in loadStyle.

Offline caching via TileStore is working as expected with Style.OUTDOORS. Also, Style.SATELLITE_STREETS will show street vectors and names, but no satellite imagery is loaded from the offline cache. The same approach work perfectly for all satellite on iOS.

Are you suggesting I should try to load the satellite imagery as a separate RasterSource and new layer pointed at "mapbox://styles/mapbox/satellite-v9"? Will that leverage the cached data in the TileStore? I don't quite understand the work-around you are describing, can you elaborate?

maclne commented 2 years ago

Are you referring to caching? Or creating Offline Regions with Raster sources?

I was using caching as a generalized term. I'm referring to creating an Offline Region with mapbox://styles/mapbox/satellite-v9 as the StyleURI, just like @ErikOutside mentioned above.

Thanks in advance - I appreciate the quick response!

wen-kai commented 2 years ago

we're also experiencing the same issue as folks above. @dudeuter thank you for the info, could you please elaborate regarding the workaround described above? Are you saying to include a "tiles": ["mapbox://styles/mapbox/satellite-v9"] property within the tile source definition along with "url": "mapbox://styles/mapbox/satellite-v9"? Is this done when using offlinemanager to download tiles for offline use?

sleushunou commented 2 years ago

I faced this problem too. Also I tried to download custom raster tileset through TilesetDescriptorOptionsForTilesets. It was downloaded successfully, but it doesn't show up on the map in offline mode, only online. I add it to map by using RasterLayer, and specify raster tile uri like "https://api.mapbox.com/v4/{_tileSetId}/{{z}}/{{x}}/{{y}}.png?access_token={accessToken}". Does MapBox works with raster tiles on Offline Mode? Can you provide documentation how to use TilesetDescriptorOptionsForTilesets API?

wen-kai commented 2 years ago

@dudeuter unfortunately your suggested workaround doesn't seem to work. Here are the steps:

  1. Successfully download a TileRegion for the styleURI mapbox://styles/mapbox/satellite-v9
  2. Go offline
  3. Render Map with a RasterLayer reading from a RasterSource where the url is pointed to the satellite tileset mapbox://mapbox.satellite. I also tried changing the tiles array to ['https://api.mapbox.com/v4/mapbox.satellite/{z}/{x}/{y}.png?access_token={token}']. These work online, but do not work when offline on a downloaded region.

Am I doing something wrong? I'd imagine the mapbox satellite style uses the mapbox satellite tileset, in which case the above should work according to your workaround.

Unfortunately this is a major blocker for anyone building maps with satellite imagery. It'd be amazing to have some additional guidance or an example of the workaround. Thank you!

dudeuter commented 2 years ago

I've pushed a working example to the branch sd-offline-raster.

https://github.com/mapbox/mapbox-maps-android/blob/1fee4a831a295f2560ef9f89e464e8df1a048e19/app/src/main/java/com/mapbox/maps/testapp/examples/OfflineActivity.kt#L110-L123

This workaround is forcing the renderer to use exclusively 256px tiles, so you'll have no control over the resolution of the satellite imagery. For devices where the renderer might choose to use 512px tiles, you'll be pulling in 4x as many tiles which might cause performance issues depending on the device. Also before downloading any regions you should be aware that raster imagery can take up significantly more storage depending on the location, zoom extents, and region size.

As you're working around the renderer trying to pick the most optimized tile from the API, you should do your due diligence and profile your application to make sure the increased memory usage is within an acceptable range. Similar to any third-party tiles. ...Or wait for official support. 🙂

wen-kai commented 2 years ago

Thanks so much @dudeuter We're using rnmapbox which uses this package under the hood. I implemented your example with a RasterLayer reading from a RasterSource with the v4 api tile template; however, it does not work offline. When attempting to render the tiles we get the error: Unable to resolve host "api.mapbox.com": No address associated with hostname. Is there anything specific in addition that needs to be configured in the download process to ensure the raster tiles are downloaded without opening the map prior? https://github.com/mapbox/mapbox-maps-android/blob/1fee4a831a295f2560ef9f89e464e8df1a048e19/app/src/main/java/com/mapbox/maps/testapp/examples/OfflineActivity.kt#L230-255

ErikOutside commented 2 years ago

@dudeuter Thanks for providing more details. I tried implementing the same approach, but saw the same result as @wen-kai.

Given that official support is on-the-way, do you have any ETA on when we can expect this to be resolved?

eugeneroz commented 2 years ago

Same issue

dudeuter commented 2 years ago

Thanks so much @dudeuter We're using rnmapbox which uses this package under the hood. I implemented your example with a RasterLayer reading from a RasterSource with the v4 api tile template; however, it does not work offline. When attempting to render the tiles we get the error: Unable to resolve host "api.mapbox.com": No address associated with hostname. Is there anything specific in addition that needs to be configured in the download process to ensure the raster tiles are downloaded without opening the map prior? https://github.com/mapbox/mapbox-maps-android/blob/1fee4a831a295f2560ef9f89e464e8df1a048e19/app/src/main/java/com/mapbox/maps/testapp/examples/OfflineActivity.kt#L230-255

Sorry for being a little in and out on this thread.

Hmm, I want to avoid the dreaded: "works in my environment". It looks like the region isn't loaded. I just want to make sure you've verified that you've downloaded the tile packs.

Potentially there are other formats that the renderer might request (and this might change per device) as tile packs that are different from the source being set. You can try authoring a blank style and manually add that source to the style with a single tiles URL (same as what you're setting on the client side) and then use that to create a tile descriptor. It's really just a matter of forcing the wires to match up internally, normally the renderer would do this so it's abstracted away from the developer.

Given that official support is on-the-way, do you have any ETA on when we can expect this to be resolved?

@ErikOutside Unfortunately I can't give you a definitive answer to that question. It's not my place to say as I don't work directly on the team(s) that are responsible for delivering this feature. Although I'll advocate for everyone here's use-case internally. 😉

andre99 commented 1 year ago

Hello @dudeuter when do you expect this to have official support?

ZiZasaurus commented 1 year ago

@andre99, @wen-kai, @eugeneroz, @maclne, @sleushunou - If you set the pixel Ratio within createTilesetDescriptor to .pixelRatio(2f) the satellite styles should behave as expected. Please try this fix in v10.9.

ErikOutside commented 1 year ago

@ZiZasaurus Thank you!

Updating to Mapbox 10.9 and setting pixel ratio worked for our implementation.

ZiZasaurus commented 1 year ago

Fantastic news. Closing this ticket but please feel free to reopen if you continue to experience issues.

dthib commented 1 year ago

Hi @wen-kai , I am facing the same issue using rnmapbox as a wrapper. i can't find the pixelRatio mentioned. Have you found a solution on your side ? Thanks a lot

wen-kai commented 1 year ago

@dthib I haven't attempted the fix yet, it'll need to be added to the rnmapbox native code here: https://github.com/rnmapbox/maps/blob/main/android/rctmgl/src/main/java-v10/com/mapbox/rctmgl/modules/RCTMGLOfflineModule.kt#L78

dthib commented 1 year ago

Ok thanks for the answer, Best