Migrate to the latest version

VERSION 0.39.1
PUBLIC PREVIEW

This tutorial contrasts how to implement core functionality in the current and in the previous version of Maps SDK. The tutorial topics are:

Project setup

  1. Configure the project as described in the Project setup guide. Then add the following dependencies to the build.gradle.kts file of your application module and synchronize the project.
1implementation("com.tomtom.sdk.maps:map-display:0.39.1")
2implementation("com.tomtom.sdk.location:provider-android:0.39.1")
3implementation("com.tomtom.sdk.search:search-online:0.39.1")
4implementation("com.tomtom.sdk.routing:route-planner-online:0.39.1")
  1. Create build config fields with the API keys. These will be used later in the application.
    1android {
    2 defaultConfig {
    3 buildConfigField("String", "MAPS_API_KEY", ""YOUR_API_KEY"")
    4 buildConfigField("String", "SEARCH_API_KEY", ""YOUR_API_KEY"")
    5 buildConfigField("String", "ROUTING_API_KEY", ""YOUR_API_KEY"")
    6 }
    7}

Displaying a map

Legacy SDK

To display a map in the TomTom Maps SDK, you had to perform the following steps:

  1. Add a map container to the view.

    1<androidx.fragment.app.FragmentContainerView
    2 android:id="@+id/map_container"
    3 android:layout_width="match_parent"
    4 android:layout_height="match_parent" />
  2. Initialize the MapFragment in an Activity or a Fragment class, using MapProperties to provide a valid TomTom API key and other optional properties.

    1val apiKeys = mapOf(ApiKeyType.MAPS_API_KEY to BuildConfig.MAPS_API_KEY)
    2val mapProperties = MapProperties.Builder()
    3 .keys(apiKeys)
    4 .padding(MapPadding(32.0, 0.0, 0.0, 0.0))
    5 .build()
    6val mapFragment = MapFragment.newInstance(mapProperties)
  3. Use a FragmentManager to replace the map container with the created MapFragment.

    1childFragmentManager.beginTransaction()
    2 .replace(R.id.map_container, mapFragment)
    3 .commit()
  4. At this point the map will be displayed. However, to interact with its instance you have to get the TomtomMap object when the map is ready to use. Add the TomtomMap field to the class.

    private lateinit var tomtomMap: TomtomMap
  5. Implement the MapReadyCallback interface and provide it to the MapFragment. The 'OnMapReadyCallback.onMapReady(TomtomMap)' method will be called when the map is fully initialized.

    mapFragment.getAsyncMap(this)
    1override fun onMapReady(tomtomMap: TomtomMap) {
    2 this.tomtomMap = tomtomMap
    3 showUserLocation()
    4 enableSearchField()
    5}

TomTom SDKs

Map initialization in the TomTom SDKs is very similar to previous versions.

  1. Create a map container in your view.
    1<androidx.fragment.app.FragmentContainerView
    2 android:id="@+id/map_container"
    3 android:layout_width="match_parent"
    4 android:layout_height="match_parent" />
  2. Prepare a property to hold the TomTomMap instance.
    private lateinit var tomTomMap: TomTomMap
  3. Create MapFragment using the MapOptions class to specify the needed properties.
    1val mapOptions = MapOptions(
    2 mapKey = BuildConfig.MAPS_API_KEY,
    3 padding = Padding(top = 32, bottom = 0, left = 0, right = 0)
    4)
    5val mapFragment = MapFragment.newInstance(mapOptions)
  4. Finally, put the MapFragment in the container using the FragmentManager and set the MapReadyCallback to access the map instance when it is ready to be used.
    1childFragmentManager.beginTransaction()
    2 .replace(R.id.map_container, mapFragment)
    3 .commit()
    4mapFragment.getMapAsync(this)
  5. Once the map is ready, assign it to the previously created property.
    1override fun onMapReady(map: TomTomMap) {
    2 this.tomTomMap = map
    3 showUserLocation()
    4 enableSearchField()
    5}
Globe view

Showing user location

The next step is showing the user location on the map. To do this, Android requires the user to grant ACCESS_FINE_LOCATION and ACCESS_COARSE_LOCATION permissions. On devices running Android 6.0 or higher, you must request permissions at runtime.

Legacy SDK

In the TomTom Legacy SDK, location permissions are handled internally by the SDK. So to show the user location on the map, you only have to enable the user location layer.

tomtomMap.isMyLocationEnabled = true

TomTom SDKs

By contrast, the TomTom Maps and Navigation SDKs do not support handling permissions. Complete instructions on how to request location permissions are found here.

  1. If permissions were granted by the user, you can initialize the location provider.

    private lateinit var locationProvider: LocationProvider
    locationProvider = AndroidLocationProvider(requireContext())
  2. Set the engine to the TomTomMap object. Enable the marker that represents the user location so it can be displayed.

    tomTomMap.setLocationProvider(locationProvider)
    tomTomMap.enableLocationMarker(LocationMarkerOptions(LocationMarkerOptions.Type.Pointer))
  3. Enable the LocationProvider to receive location updates.

    locationProvider.enable()
Location pointer

This section of the tutorial describes a simple fuzzy search implementation. For more detailed information about searches see the Search module documentation. A good place to start is Search quickstart guide.

With both SDKs, you need to use an AppCompatAutoCompleteTextView to get the search term from the user. It also displays the results of the search request. Implementing AppCompatAutoCompleteTextView is outside the scope of this tutorial. This document only discusses functionality within the SDK.

Legacy SDK

  1. The entry point to the Search services is through the Search interface. Create the interface using the OnlineSearch class. It requires a context and a valid TomTom API key.

    private lateinit var searchApi: SearchApi
    searchApi = OnlineSearchApi.create(requireContext(), BuildConfig.SEARCH_API_KEY)
  2. The fuzzy search request is built using descriptors, which are then included in the FuzzySearchSpecification along with the query.

    1val searchEngineDescriptor = FuzzySearchEngineDescriptor.Builder()
    2 .typeAhead(true)
    3 .minFuzzyLevel(2)
    4 .maxFuzzyLevel(4)
    5 .build()
    6
    7val fuzzySearchSpecification = FuzzySearchSpecification.Builder(query)
    8 .searchEngineDescriptor(searchEngineDescriptor)
    9 .build()
  3. Use the prepared specification to perform the request. The results are returned using a FuzzyOutcomeCallback that was provided to the request method.

    1searchApi.search(
    2 fuzzySearchSpecification,
    3 object : FuzzyOutcomeCallback {
    4 override fun onError(error: SearchException) {
    5 Toast.makeText(requireContext(), error.localizedMessage, Toast.LENGTH_SHORT).show()
    6 }
    7
    8 override fun onSuccess(fuzzyOutcome: FuzzyOutcome) {
    9 addSearchResultsToSuggestionsAdapter(fuzzyOutcome.fuzzyDetailsList)
    10 }
    11 }
    12)

TomTom SDKs

  1. As in the legacy SDK, the Search services are accessed using the Search class. It also requires a context and a valid TomTom API key.

    private lateinit var search: Search
    search = OnlineSearch.create(requireContext(), BuildConfig.SEARCH_API_KEY)
  2. Use the FuzzySearchOptions class to build the fuzzy search request. You can specify all the parameters using this single class.

    1val options = SearchOptions(
    2 query = query
    3)
  3. Use the newly created FuzzySearchOptions to perform a search request. All the results are returned using the FuzzySearchCallback object.

    1search.search(
    2 options,
    3 object : SearchCallback {
    4 override fun onFailure(failure: SearchFailure) {
    5 Toast.makeText(requireContext(), failure.message, Toast.LENGTH_SHORT).show()
    6 }
    7
    8 override fun onSuccess(result: SearchResponse) {
    9 addSearchResultsToSuggestionsAdapter(result.results)
    10 }
    11 }
    12)

Adding a marker

This section explains how to add a marker at a selected location using each of the SDKs.

Legacy SDK

To add a marker to the map, first create a MarkerBuilder to specify its properties. Then add the MarkerBuilder to the TomTomMap.

1private fun displayMarkerAt(latLng: LatLng) {
2 val markerBuilder = MarkerBuilder(latLng)
3 tomtomMap.addMarker(markerBuilder)
4}

TomTom SDKs

Adding a marker works the same way with the TomTom SDKs as in the legacy SDK. The only difference is that you use the MarkerOptions class instead of MarkerBuilder.

1private fun displayMarkerAt(coordinate: GeoPoint) {
2 val markerOptions =
3 MarkerOptions(
4 coordinate,
5 ImageFactory.fromResource(R.drawable.center_balloon_bg)
6 ) // No default marker
7 tomTomMap.addMarker(markerOptions)
8}
center

Drawing a route

The last part of this tutorial explains how to plan a route between two locations and draw it on the map.

Legacy SDK

  1. To perform any routing request in the TomTom SDKs, start by initializing a RoutingApi. This is the access point to the routing service.

    private lateinit var routingApi: RoutingApi
    routingApi = OnlineRoutingApi.create(requireContext(), BuildConfig.ROUTING_API_KEY)
  2. Build and perform the request. Specify the route parameters by applying route descriptors to the RouteSpecification class. Then provide the configured specification to the routing call. Possible routes are returned inside the RouteCallback provided to the request method.

    1private fun planRoute(departureLatLng: LatLng, destinationLatLng: LatLng) {
    2 val routeDescriptor = RouteDescriptor.Builder()
    3 .routeType(RouteType.FASTEST)
    4 .considerTraffic(true)
    5 .build()
    6
    7 val routeCalculationDescriptor = RouteCalculationDescriptor.Builder()
    8 .routeDescription(routeDescriptor)
    9 .build()
    10
    11 val routeSpecification = RouteSpecification.Builder(departureLatLng, destinationLatLng)
    12 .routeCalculationDescriptor(routeCalculationDescriptor)
    13 .build()
    14
    15 routingApi.planRoute(
    16 routeSpecification,
    17 object : RouteCallback {
    18 override fun onError(error: RoutingException) {
    19 Toast.makeText(requireContext(), error.localizedMessage, Toast.LENGTH_SHORT).show()
    20 }
    21
    22 override fun onSuccess(routePlan: RoutePlan) {
    23 val route = routePlan.routes.firstOrNull() ?: return
    24 drawRoute(route)
    25 }
    26 }
    27 )
    28}
  3. Draw the calculated route on the map. You can define the appearance of the route using the RouteStyleBuilder class. The RouteBuilder is a representation of the path to add to the map. You must provide it with a list of coordinates. Optional: You can also specify the design. All the routes are then shown in the route overview.

    1val coordinates = route.getCoordinates()
    2val routeStyle = RouteStyleBuilder.create().withFillColor(Color.RED).build()
    3val routeBuilder = RouteBuilder(coordinates)
    4 .style(routeStyle)
    5 .startIcon(
    6 Icon.Factory.fromResources(
    7 requireContext(),
    8 R.drawable.ic_map_route_departure
    9 )
    10 )
    11 .endIcon(
    12 Icon.Factory.fromResources(
    13 requireContext(),
    14 R.drawable.ic_map_route_destination
    15 )
    16 )
    17tomtomMap.addRoute(routeBuilder)
    18tomtomMap.displayRoutesOverview()

TomTom SDKs

  1. As with the legacy SDK, the entry point to the routing services for TomTom SDKs is through the RoutingApi interface. It must be initialized before any routing calls.

    private lateinit var routePlanner: RoutePlanner
    routePlanner = OnlineRoutePlanner.create(requireContext(), BuildConfig.ROUTING_API_KEY)
  2. Build and perform the route request.

The request requires origin and destination coordinates. You can also provide additional parameters. Add them all using the RoutingOptions class, which you can then use to perform the routing request. As with the legacy SDK, routing results are returned in the provided callback - RoutingCallback.

+

1private fun planRoute(
2 departureCoordinate: GeoPoint,
3 destinationCoordinate: GeoPoint
4) {
5 val routePlanningOptions = RoutePlanningOptions(
6 itinerary = Itinerary(
7 origin = departureCoordinate,
8 destination = destinationCoordinate
9 ),
10 costModel = CostModel(routeType = RouteType.Fast, considerTraffic = ConsiderTraffic.Yes)
11 )
12
13 routePlanner.planRoute(
14 routePlanningOptions,
15 object : RoutePlanningCallback {
16 override fun onFailure(failure: RoutingFailure) {
17 Toast.makeText(requireContext(), failure.message, Toast.LENGTH_SHORT).show()
18 }
19
20 override fun onSuccess(result: RoutePlanningResponse) {
21 val route = result.routes.firstOrNull() ?: return
22 drawRoute(route)
23 }
24
25 override fun onRoutePlanned(route: Route) = Unit
26 }
27 )
28}
  1. Use the result of the call to draw a route on the map. To do this, get the list of coordinates of the route that you want to draw. Use the list to build a RouteOptions object. This is also where you can specify the visual properties for the route. Then add the RouteOptions to the TomTomMap. When you display all of the routes, you can also specify the padding from the edges of the map.
    1val routeOptions = RouteOptions(
    2 geometry = route.geometry,
    3 color = Color.RED,
    4 destinationMarkerVisible = true,
    5 departureMarkerVisible = true
    6)
    7tomTomMap.addRoute(routeOptions)
    8tomTomMap.zoomToRoutes(40)
Adding a route

Summary

This tutorial instructed you on how to move a basic app from Mapbox’s SDKs to TomTom’s SDKs. Now you can enrich your app with TomTom’s features and functions.

If you want to learn more, take a look at our other tutorials: