Building highlights
The Mapbox Navigation SDK provides logic to highlight a particular building footprint or extrude a footprint as a 3D building shape. You can use this functionality to enhance the navigation experience for your users by visually highlighting your user's stop or final destination. For example, a package delivery driver might want to see the exact building that's associated with a delivery address.
Use the default building UI component
The buildings UI component consists of two main classes:
-
The
MapboxBuildingsApi
has methods for retrieving the building you'd like to highlight in the form of aQueriedRenderedFeature
. -
The
MapboxBuildingView
handles consuming the data produced by theMapboxBuildingsApi
and rendering the results on the map.
Point types
It's important to understand the difference between location
point and routable
point to make use of the buildings API:
location
point: A point where the actual building is.routable
point: A point on a road snapped from the address.
Create an instance of MapboxBuildingsApi
Instantiate MapboxBuildingsApi
in your Activity
or Fragment
.
private val buildingsApi: MapboxBuildingsApi by lazy {
MapboxBuildingsApi(mapboxMap)
}
Then you can get the building you'd like to highlight. MapboxBuildingsApi
exposes three different methods that returns you one or more building(s):
queryBuildingToHighlight
: This API takesPoint
as an argument and returns a list of building(s) asQueriedFeature
. If the point passed is not a location point, the list returned will be empty.queryBuildingOnWaypoint
: This API takesRouteProgress
as an argument and returns a list of building(s) asQueriedFeature
. IfRouteProgress
doesn't contain a location point, the list returned will be empty.queryBuildingOnFinalDestination
: This API takesRouteProgress
as an argument and returns a list of building(s) asQueriedFeature
. IfRouteProgress
doesn't contain a location point, the list returned will be empty.
Use location point in route request
When requesting a single- or multi-stop route, the simplest way is to invoke request route with your already-instantiated MapboxNavigation
object. But, if you want to highlight buildings, you should use RouteOptions#waypointTargetsList
.
In the snippet below, coordinatesList
holds a list of three routable
points that the Navigation SDK uses to navigate to your destination, and the waypointTargetsList
holds a list of three location
points that the SDK uses to return a list of buildings in the form of QueriedRenderedFeature
.
val routeOptions = RouteOptions.builder()
.applyDefaultNavigationOptions()
.applyLanguageAndVoiceUnitOptions(this)
.coordinatesList(
listOf(
Point.fromLngLat(-122.4192, 37.7627), // origin
Point.fromLngLat(-122.4182, 37.7651), // waypoint destination
Point.fromLngLat(-122.4145, 37.7653) // final destination
)
)
.waypointTargetsList(
listOf(
Point.fromLngLat(-122.4192, 37.7627), // origin
Point.fromLngLat(-122.4183, 37.7653), // waypoint destination
Point.fromLngLat(-122.4146, 37.7655) // final destination
)
)
.build()
waypointTargetsList
, but you must use location
points instead of routable
points in coordinateList
. If you use routable
points, the SDK will query the snapped location on the road and will not return any building(s).Query buildings on arrival
Now that you have passed in location points and have your instance of MapboxBuildingsApi
ready, you can use one or more of the query-related methods to query buildings.
To use building highlighting to visually emphasize the location of stops along a route or a final destination, you'll need to know when the user has arrived at a waypoint or destination. You can listen for arrival events using ArrivalObserver
. Read more about how ArrivalObserver
works in the Arrival detection guide.
To query the building upon reaching a waypoint, use ArrivalObserver
's onWaypointArrival
and MapboxBuildingsApi
's queryBuildingOnWaypoint
.
val arrivalObserver = object : ArrivalObserver {
override fun onWaypointArrival(routeProgress: RouteProgress) {
buildingsApi.queryBuildingOnWaypoint(routeProgress, callback)
}
...
}
To query the building upon reaching the final destination, add onFinalDestinationArrival
to ArrivalObserver
and then use MapboxBuildingsApi
's queryBuildingOnFinalDestination
.
override fun onFinalDestinationArrival(routeProgress: RouteProgress) {
buildingsApi.queryBuildingOnFinalDestination(routeProgress, callback)
}
The callback
for both query methods can either be BuildingError
containing an error message or BuildingValue
containing a list of buildings in the form of QueriedRenderedFeature
.
private val callback =
MapboxNavigationConsumer<Expected<BuildingError, BuildingValue>> { expected ->
expected.fold(
{
// handle errors
},
{ value ->
// highlight the building using `MapboxBuildingView`
}
)
}
Don't forget to cancel any potential in-flight MapboxBuildingsApi
requests in onStop
or onDestroy
:
override fun onDestroy() {
super.onDestroy()
buildingsApi.cancel()
}
Highlight buildings
Now that you have queried your buildings, you can highlight them by creating an instance of MapboxBuildingView
.
private val buildingView = MapboxBuildingView()
Inside the callback you have defined above get the map style and highlight buildings.
{ value ->
mapboxMap.getStyle { style ->
buildingView.highlightBuilding(style, value.buildings)
}
}
After you have reached the waypoint and highlighted the building, you can clear the building highlight before starting the next leg.
override fun onNextRouteLegStart(routeLegProgress: RouteLegProgress) {
mapboxMap.getStyle { style ->
buildingView.removeBuildingHighlight(style)
}
}