Skip to main content
Version: 1.x (beta)

MapSDK - Getting started

The WemapMapSDK is a library for embedding customized interactive maps within mobile applications.

Requirements​

Check common requirement.

Installation​

Check common installation.

Add a map​

At first add WemapMapView to your layout:

<com.getwemap.sdk.map.WemapMapView
android:id="@+id/mapView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>

Then create a MapSession and pass it to the WemapMapView via configure. The session and the (optional) rendering config are set once:

lifecycleScope.launch {
runCatching {
MapSession.create(requireContext(), 19158, "GUHTU6TYAWWQHUSR5Z5JZNMXX") // your mapId and token
}.onSuccess { session ->
mapView.configure(session) // pass a MapViewConfig() as the second argument to tune rendering
}.onFailure {
println("Failed to create session with error - $it")
}
}

Wait for the MapView to load​

Only once the view has finished loading is it safe to access WemapMapView properties. You can await loading with the suspending awaitLoaded():

lifecycleScope.launch {
runCatching {
mapView.awaitLoaded()
}.onSuccess {
// now it's safe to access MapView properties
}.onFailure { error ->
println("Failed to load MapView with error - $error")
}
}

Or observe loadPhases — a StateFlow<LoadPhase> that starts at LoadPhase.Loading and settles on LoadPhase.Ready or LoadPhase.Failed. The current phase is replayed to every new collector, so a late subscriber still sees the terminal state:

lifecycleScope.launch {
mapView.loadPhases.collect { phase ->
when (phase) {
LoadPhase.Loading -> showSpinner()
LoadPhase.Ready -> showMap()
is LoadPhase.Failed -> showError(phase.error)
}
}
}

A LoadPhase.Failed does not always mean the managers are missing. A style that failed to load leaves them unbuilt, and accessing one throws; a points-of-interest download that failed or timed out leaves every manager built and usable, with no POI content. That is deliberate — a network timeout must never bring down the host app.

MapView lifecycle​

WemapMapView manages Android's OpenGL lifecycle for you. It observes a Lifecycle and drives MapLibre's lifecycle automatically — when the view is placed in a normal Activity/Fragment layout it discovers the lifecycle owner from the view tree on attach, so you do not need to forward onStart/onResume/onDestroy and friends to it.

Assign mapView.lifecycle yourself only when the view tree can't provide a lifecycle owner (a plain Dialog/PopupWindow, a WindowManager overlay, Compose interop, or tests):

mapView.lifecycle = viewLifecycleOwner.lifecycle

When you're done with the screen, tear down the session that owns the shared services:

override fun onDestroy() {
super.onDestroy()
session.deinit()
}

Keep the session in a ViewModel (and call session.deinit() from onCleared()) if you want it to survive configuration changes such as rotation.

Jetpack Compose​

Compose support ships as a separate artifact, com.getwemap.sdk:map-compose, so that View-based apps are not made to depend on the Compose runtime:

implementation("com.getwemap.sdk:map-compose:<version>")

WemapMap takes the session and hands you the loaded WemapMapView — everything the SDK offers is reached through it, so there is no second API to learn:

@Composable
fun MapScreen(session: MapSession) {

var mapView by remember { mutableStateOf<WemapMapView?>(null) }

WemapMap(
session = session,
modifier = Modifier.fillMaxSize(),
onLoaded = { mapView = it },
onFailed = { error -> Log.e("Map", "Failed to load the map", error) }
)

// the SDK's own flows are collected directly — no wrapper parameters
val building by (mapView?.buildingManager?.focusedBuildings ?: emptyFlow())
.collectAsStateWithLifecycle(null)

building?.let { BuildingBanner(it) }
}

Three things to know:

  • Hoist the session into a ViewModel, not a remember — it is network-loaded and cannot go into a Bundle, so a remember would drop it on rotation. Call session.deinit() from onCleared().
  • The map view is torn down when it leaves composition, and rebuilt if you pass a different session (a view's session is set once). You do not forward any lifecycle callback.
  • onLoaded is not replayed. Supply it from the first composition; a handler first passed after loading finished is not invoked retroactively. Read loadPhase — or collect loadPhases — for the current state.

Full details, the parameter list and the pitfalls are in MapSDK with Jetpack Compose.

User Location​

Wemap provides various location sources to track the user's location on the map. For more info check positioning docs

By default, WemapMapSDK uses Android GPS and Network Providers. But you can easily take any WemapPositioningSDK location source — created with the same session — and connect it to the WemapMapView as shown below:

fun setupLocationSource(session: MapSession) {
val locationSource = AndroidFusedAdaptiveLocationSource(requireContext(), session) // any LocationSource from WemapPositioningSDK
mapView.locationManager.locationSource = locationSource
}

The full example is available in our GitHub repository.

Examples​

For additional examples and sample implementations of WemapSDKs, visit the official GitHub repository.

Clone the repository and follow the README instructions to run the sample application.