Route Calculation and Display
These examples show how to calculate routes between two points and display them on the map. Routes can be defined using raw coordinates or place IDs, and they support configurable visual styles for the upcoming and completed segments of a path.
Basic Route Between Two Coordinates
Use LzLocation objects to define the start and end of a route when you have raw latitude/longitude values. The response returns a list of possible routes; in most cases you will use the first result.
private fun calculateRoute(
startLat: Double, startLng: Double,
endLat: Double, endLng: Double
) {
viewLifecycleOwner.lifecycleScope.launch {
val start = LzLocation(
building = null,
floor = null,
latitude = startLat,
longitude = startLng
)
val end = LzLocation(
building = null,
floor = null,
latitude = endLat,
longitude = endLng
)
try {
val response = LzSdkManager.getRoute(
initialLocation = start,
finalLocation = end,
language = "en"
)
if (response.isSuccessful) {
response.body()?.firstOrNull()?.let { route ->
displayRoute(route)
}
} else {
showError("Route calculation failed: ${response.code()}")
}
} catch (e: Exception) {
showError("Error: ${e.message}")
}
}
}
private fun displayRoute(route: SdkRoute) {
LzSdkManager.setCurrentShowingRoute(route)
lzMap?.addRoute(
route = route,
nextStepsLineStyle = PlainRouteLine(colorHex = "#7000FF", lineWith = 4f),
prevStepsLineStyle = PlainRouteLine(colorHex = "#D2E0EB", lineWith = 4f)
) {
println("Route displayed")
// Show route steps
val steps = route.getSteps()
steps.forEach { step ->
println("Step: ${step.plainInstructions}")
}
}
}Route Between Place IDs
When your origin and destination are known places in the venue, use IdPlaceLocation instead of coordinates. This is the recommended approach for in-venue navigation because the SDK can resolve the exact geometry of each place, including its floor level.
val start = IdPlaceLocation(id = "entrance-main", level = 0)
val destination = IdPlaceLocation(id = "store-42", level = 2)
val response = LzSdkManager.getRoute(
initialLocation = start,
finalLocation = destination,
preferAccessibleRoute = true,
language = "es"
)Route from Current Location to a Place
Combine the position repository’s live location flow with a destination place ID to start navigation from wherever the user currently is.
// Get the user's current location from the position repository
positionRepo.locatorResultFlow
.filter { it?.location != null }
.mapNotNull { it?.location }
.first()
.let { currentLocation ->
val destination = IdPlaceLocation(id = "store-42", level = 1)
val response = LzSdkManager.getRoute(
initialLocation = currentLocation,
finalLocation = destination
)
if (response.isSuccessful) {
response.body()?.firstOrNull()?.let { route ->
displayRoute(route)
}
}
}Displaying Route Steps
After calculating a route, you can extract the step-by-step instructions and present them in your UI. Steps are indexed from zero and each carries a plain-text instruction suitable for display or text-to-speech.
private fun displayRoute(route: SdkRoute) {
LzSdkManager.setCurrentShowingRoute(route)
lzMap?.addRoute(
route = route,
nextStepsLineStyle = PlainRouteLine(colorHex = "#7000FF", lineWith = 4f),
prevStepsLineStyle = PlainRouteLine(colorHex = "#D2E0EB", lineWith = 4f)
) {
println("Route displayed")
// Show route steps
val steps = route.getSteps()
steps.forEach { step ->
println("Step: ${step.plainInstructions}")
}
}
}Move Route Progress Programmatically
You can drive step-by-step route progress from your own UI controls (cards, arrows, list selection):
// Move preview to an explicit step
lzMap?.goToRouteStep(stepIndex = 5)
// Relative navigation
lzMap?.goToNextRouteStep()
lzMap?.goToPreviousRouteStep()
// Keep external UI in sync
val activeStepIndex = lzMap?.getCurrentRouteStepIndex()If you already have a location projection for a specific step, you can keep using:
lzMap?.updateRouteStep(routingStepIndex = 5, userLocation = projectedLocation)Default Marker Fallback Icon
Marker APIs (addMarker, addAnnotationWith) now support configurable fallback icon ids:
val mapConfig = LazarilloMapConfig().apply {
defaultMarkerIcon = "outlined_pin"
}
// Runtime override (null restores SDK default icon: "pin")
lzMap?.setDefaultMarkerIcon("outlined_pin")Element Filtering
Filter which map elements are displayed by type (POIs, polygons, lines). This is useful for showing only relevant categories during navigation or search.
import org.json.JSONObject
// Show only restaurant POIs
val filterConfig = JSONObject().apply {
put("poi", JSONObject().apply {
put("only", JSONObject().apply {
put("category", "restaurant")
})
})
}
lzMap?.setElementFilter(filterConfig)
// Exclude parking polygons
val excludeConfig = JSONObject().apply {
put("polygon", JSONObject().apply {
put("exclude", JSONObject().apply {
put("type", "parking")
})
})
}
lzMap?.setElementFilter(excludeConfig)
// Remove all filters
lzMap?.clearElementFilter()Place Selection and Label Control
Listen for place taps and control label visibility for selected places:
// Register a callback for place taps
lzMap?.setTappedPlaceCallback { placeId ->
if (placeId != null) {
println("Place tapped: $placeId")
}
}
// Hide the label of the selected place to avoid overlap with custom UI
lzMap?.setHideSelectedPlaceLabel(true)
// Or configure it at map creation time
val mapConfig = LazarilloMapConfig().apply {
hideSelectedPlaceLabel = true
}
// Clear selection programmatically
lzMap?.clearSelectedPlace()
// Disable place tap handling
lzMap?.setTappedPlaceCallback(null)Route Animation Preview
Animate the full route on the map to let users preview their journey before starting navigation. The animation controller handles marker movement, floor transitions, and bearing rotation automatically.
lzMap?.animateRoute(
route = route,
aheadStyle = PlainRouteLine(colorHex = "#D2E0EB", lineWith = 4f),
behindStyle = PlainRouteLine(colorHex = "#7000FF", lineWith = 4f),
normalSpeed = 20.0,
changeFloorTime = 2.0,
rotatingIconTime = 0.5
) { currentStep ->
binding.tvInstruction.text = currentStep.plainInstructions
}
// Stop animation at any time
lzMap?.stopAnimatedRoute()See Route Style Customization for the full list of animation parameters and segment types.
Related Examples
- Indoor Navigation - Monitor navigation progress and handle off-route events
- Route Styling - Customize the visual appearance of routes and animation
- Error Handling - Handle route calculation failures gracefully
- Complete Navigation Flow - End-to-end navigation from venue selection to arrival