Android Kotlin实现Mapbox全量离线瓦片后部分层级无法显示的问题
Mapbox离线地图部分层级无法渲染的排查与修复
核心原因
你创建了自定义TileStore并下载了瓦片,但MapView初始化时未关联该自定义TileStore对应的ResourceOptions,导致地图渲染时使用默认缓存而非你下载的离线瓦片,因此部分层级需要联网补充加载。
修复步骤
1. 初始化MapView时关联自定义ResourceOptions
修改MapView的创建代码,传入你定义的resourceOptions,确保地图读取你下载到自定义TileStore的瓦片:
mapView = MapView( this@Carban, MapViewOptions.create(this).resourceOptions(resourceOptions) ).also { mapview -> val mapboxMap = mapview.getMapboxMap() mapboxMap.setCamera(CameraOptions.Builder().zoom(ZOOM).center(TOKYO).build()) mapboxMap.loadStyleUri(Style.MAPBOX_STREETS){ mapview.annotations.createCircleAnnotationManager().create( CircleAnnotationOptions().withPoint(TOKYO).withCircleColor(Color.RED) ) } } binding.container.addView(mapView)
2. 确认瓦片下载完成且无错误
为loadTileRegion添加回调,验证瓦片是否成功下载到TileStore:
tilePackCancelable1 = tileStore.loadTileRegion( TILE_REGION_ID1, TileRegionLoadOptions.Builder() .geometry(TOKYO) .descriptors(listOf(tilesetDescriptor)) .metadata(Value(TILE_REGION_METADATA1)) .acceptExpired(true) .networkRestriction(NetworkRestriction.NONE) .build() ).addListener(object : CancelableCallback { override fun onCancel() {} override fun onSuccess(tileRegion: TileRegion) { Log.d("OfflineTile", "瓦片下载完成,数量:${tileRegion.tileCount}") } override fun onError(error: TileRegionError) { Log.e("OfflineTile", "瓦片下载失败:${error.message}") } }, Looper.getMainLooper())
如果下载失败,根据错误信息排查网络、权限或几何范围问题。
3. 离线加载样式(替代直接loadStyleUri)
直接调用loadStyleUri会尝试联网拉取最新样式,建议通过OfflineManager加载已下载的StylePack:
offlineManager.getStylePack(Style.MAPBOX_STREETS) .addOnSuccessListener { stylePack -> mapboxMap.loadStyle(stylePack.style) { mapview.annotations.createCircleAnnotationManager().create( CircleAnnotationOptions().withPoint(TOKYO).withCircleColor(Color.RED) ) } } .addOnFailureListener { // 离线样式加载失败时, fallback 到在线加载 mapboxMap.loadStyleUri(Style.MAPBOX_STREETS) { mapview.annotations.createCircleAnnotationManager().create( CircleAnnotationOptions().withPoint(TOKYO).withCircleColor(Color.RED) ) } }
4. 验证下载区域的几何范围
如果TOKYO是单个Point,Mapbox会自动扩展为小范围,但高缩放层级的瓦片可能需要更大的覆盖区域。建议用LatLngBounds定义明确的边界:
// 定义东京核心区域的边界 val tokyoBounds = LatLngBounds.Builder() .include(LatLng(35.60, 139.69)) .include(LatLng(35.73, 139.90)) .build() // 在TileRegionLoadOptions中使用该边界 TileRegionLoadOptions.Builder() .geometry(tokyoBounds) // 其他配置不变 .build()
额外检查
- 确认App拥有读写存储权限,确保TileStore能正常写入离线瓦片;
- 检查
TileStore的配置,确认MAPBOX_ACCESS_TOKEN已正确设置,且与Style/Tile下载时使用的Token一致。
内容的提问来源于stack exchange,提问作者Mamad 989331727735
相关产品推荐
相关产品推荐

