Display Offline Maps

This page talks about displaying installed offline map data with the standard MapView, set compatible styles, and use focusPreviewRegion() only as an optional camera helper.

Use the Standard MapView

The map display page does not require a dedicated Offline MapView. The optional focusPreviewRegion() camera helper is invoked through RegionalOffline; tile rendering itself does not depend on download-management initialization:

1
<ai.nextbillion.maps.core.MapView
2
android:id="@+id/mapView"
3
android:layout_width="match_parent"
4
android:layout_height="match_parent" />

Complete Activity example:

1
class OfflineMapActivity : AppCompatActivity() {
2
private lateinit var mapView: MapView
3
private var map: NextbillionMap? = null
4
5
override fun onCreate(savedInstanceState: Bundle?) {
6
super.onCreate(savedInstanceState)
7
setContentView(R.layout.activity_offline_map)
8
9
mapView = findViewById(R.id.mapView)
10
mapView.onCreate(savedInstanceState)
11
mapView.getMapAsync { nextbillionMap ->
12
map = nextbillionMap
13
14
val styleUri = Style.getPredefinedStyle("Bright")
15
nextbillionMap.setStyle(Style.Builder().fromUri(styleUri)) {
16
intent.getIntExtra("region_id", -1)
17
.takeIf { it >= 0 }
18
?.let { previewInstalledRegion(nextbillionMap, it) }
19
}
20
}
21
}
22
23
private fun previewInstalledRegion(map: NextbillionMap, regionId: Int) {
24
lifecycleScope.launch {
25
val installed = withContext(Dispatchers.IO) {
26
RegionalOffline.listInstalledRegions()
27
.any { it.regionId == regionId }
28
}
29
val focused = installed &&
30
RegionalOffline.focusPreviewRegion(map, regionId)
31
if (!focused) showRegionBoundsUnavailable()
32
}
33
}
34
35
override fun onStart() {
36
super.onStart()
37
mapView.onStart()
38
}
39
40
override fun onResume() {
41
super.onResume()
42
mapView.onResume()
43
}
44
45
override fun onPause() {
46
mapView.onPause()
47
super.onPause()
48
}
49
50
override fun onStop() {
51
mapView.onStop()
52
super.onStop()
53
}
54
55
override fun onLowMemory() {
56
super.onLowMemory()
57
mapView.onLowMemory()
58
}
59
60
override fun onSaveInstanceState(outState: Bundle) {
61
super.onSaveInstanceState(outState)
62
mapView.onSaveInstanceState(outState)
63
}
64
65
override fun onDestroy() {
66
map = null
67
mapView.onDestroy()
68
super.onDestroy()
69
}
70
}

focusPreviewRegion() is only an optional camera helper. A return value of false means that no indexable bounds are currently available for the region; it does not affect offline tile loading. The application may also save and restore its own camera position.

Map Page Integration Requirements

Handle the map page as follows:

  • Forward the full MapView lifecycle: onCreate(), onStart(), onResume(), onPause(), onStop(), onLowMemory(), onSaveInstanceState() and onDestroy().

  • After getMapAsync() returns, set the SDK's predefined Bright or Dark style.

  • When navigating from the download page to the map page, pass regionId. If the camera should move automatically, verify that the region is installed on an IO thread, then call focusPreviewRegion() on the main thread.

  • focusPreviewRegion() returns false: keep the current camera and prompt the user to locate the region manually. Do not treat this result as an indication that the region data is unavailable.

  • The map's current tile server must be NGLTomTom.

  • Do not wait for previewBundleReady on the map page, and do not use the download page resource-status API as a setStyle() condition.

  • After returning from the download page, call MapView.onResume() normally. Do not recreate MapView or reinitialize RegionalOffline.

When using a custom style, the application must ensure that the style, sprite, glyph, TileJSON, and region-tile URL templates are compatible with the current data source.