Search SDK Integration

The Mapbox Search SDK provides the tools to add a search experience to your navigation application. Integrating the Search SDK with your application allows users to search for locations by place name, address, category, or coordinate. It also allows access to search history and save searches as Favorites.

Before starting to integrate your application with the Search SDK, you’ll need to add the Search SDK as a dependency. To install, follow the steps for adding the Search SDK as a dependency to your application. The secret access token with Downloads:Read scope that you use for your Navigation SDK application will work.

Running into problems installing?

Make sure that the versions of the Navigation SDK and Search SDK have compatible versions of Common SDK.

Integrating with the Search SDK

To integrate the Search SDK into your application, you can provide search programmatically. Use your own UI implementation with the search API from the Search SDK for higher customization and flexibility.

Send a search result to the Navigation SDK

A Search SDK selected query will return a SearchResult for the user's desired destination. A SearchResult is a search object with populated fields such as its result name, description, coordinates, and RoutablePoints that will allow you to display search results on the map as well as navigate to a desired result. After you retrieve a SearchResult, you will need to send it to the Navigation SDK in order to navigate to the desired result.

Here is an example of handling a search result selection:

fun handleSearchResultSelection(searchResult: SearchResult) {
    val destination = searchResult.routablePoints?.firstOrNull()?.point ?: searchResult.coordinate ?: return
    mapboxNavigation.requestRoutes(
        RouteOptions.builder()
            .applyDefaultNavigationOptions()
            .coordinatesList(listOf(origin, destination))
            .waypointNamesList(listOf(null, searchResult.name))
            .build(),
        object : NavigationRouterCallback {

            override fun onCanceled(routeOptions: RouteOptions, routerOrigin: RouterOrigin) {
            }

            override fun onFailure(reasons: List<RouterFailure>, routeOptions: RouteOptions) {
            }

            override fun onRoutesReady(routes: List<NavigationRoute>, routerOrigin: RouterOrigin) {
                // Handle routes
            }
        },
    )
}

searchResult.coordinate provides the center coordinates of a search result while searchResult.routablePoints provides coordinates that correspond to a building's entrance. Not all search results will include RoutablePoints, but when included in the result you should use them to navigate the user to their destination. The sample code above does this here:val destination = searchResult.routablePoints?.firstOrNull()?.point ?: searchResult.coordinateTo set this coordinate as a destination for your user, create a list of Points with the destination and pass it to RouteOptions.Builder. When requesting a route using MapboxNavigation#requestRoutes and using this Point as a destination, the returned route will snap to the road and originate from the optimal direction.

If you choose to display search results as annotations on the map, make sure to remove the results before displaying the route.

Send coordinates from the Navigation SDK to the Search SDK

You can use the Search SDK's SearchEngine class to perform reverse geocoding which allows users to search for place names and addresses by providing geographic coordinates. For example, the user can tap the map to find places nearby or see places near their destination.

If you want to tap on the map and display places nearby, you can add a new gesture like this:

fun handleMapClick(coordinate: Point) {
    searchEngine.search(
        ReverseGeoOptions(coordinate),
        object : SearchCallback {

            override fun onError(e: Exception) {
            }

            override fun onResults(results: List<SearchResult>, responseInfo: ResponseInfo) {
                // Display search results
                val annotations = results.mapNotNull { searchResult ->
                    val point = searchResult.coordinate ?: return@mapNotNull null
                    PointAnnotationOptions().withPoint(point).withTextField(searchResult.name)
                }
                pointAnnotationManager.create(annotations)
            }
        },
    )
}

PointAnnotationManager is used to manage PointAnnotations and is created using the following code:val pointAnnotationManager = mapView.annotations.createPointAnnotationManager()

Remember to set up the map click listener by adding it to the MapView.

Add autocomplete search view to the navigation view

Besides displaying a user's favorites and search history, you can also add autocomplete search view that suggests queries based on the input text using a custom search box. Incorporating autocomplete enhances the search experience by allowing the user to click on the desired result before finishing the query. As the user types in the query, results update in real time and your application receives updates as SearchSuggestions through the SearchSuggestionsCallback instance.

searchEngine.search(
    textView.text,
    searchOptions,
    object : SearchSuggestionsCallback {

        override fun onError(e: Exception) {
        }

        override fun onSuggestions(suggestions: List<SearchSuggestion>, responseInfo: ResponseInfo) {
            // Handle suggestions
        }
    },
)

A SearchSuggestion contains only enough information to display the suggestion in a list. To obtain a coordinate or detailed address information for navigation, pass the suggestion back to the SearchEngine#select method in response to a user selection.

Additional notes

Pricing for the Navigation SDK and Search SDK are calculated separately. For pricing information for the Search SDK, see the pricing guide.