Sorry, you need to enable JavaScript to visit this website.

Map initialization

Map initialization

The main class that represents a map is a MapView. MapView is wrapped by MapFragment. To display a map, it is recommended to use`MapFragment`.

The basic steps for adding a map are:

  1. Follow the steps described in the Getting started section.

  2. Add MapFragment to your Activity:

  • MapFragment created from the code:

val mapFragment = MapFragment.newInstance()
  • MapFragment declared in the XML:

<fragment
    android:id="@+id/map_fragment"
    android:name="com.tomtom.online.sdk.map.MapFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

To obtain the fragment reference call:

_

MapFragment mapFragment = (MapFragment) getSupportFragmentManager().findFragmentById(mapFragmentId);
mapFragment = supportFragmentManager.findFragmentById(R.id.map_fragment) as MapFragment

  3. Implement the OnMapReadyCallback and use the onMapReady method to get the TomtomMap object:

/**
 * Callback interface executed when the map is ready to be used.
 * The instance of this interface is set to {@link MapFragment},
 * and the {@link OnMapReadyCallback#onMapReady(TomtomMap)} is triggered
 * when the map is fully initialized and not-null.
 */
public interface OnMapReadyCallback {
    /**
     * Called when the map is ready to be used.
     */
    void onMapReady(@NonNull TomtomMap tomtomMap);
}

 

Sample implementation of the OnMapReadyCallback:

_

private final OnMapReadyCallback onMapReadyCallback =
        new OnMapReadyCallback() {
            @Override
            public void onMapReady(TomtomMap map) {
                //Map is ready here
                tomtomMap = map;
                tomtomMap.setMyLocationEnabled(true);
                tomtomMap.collectLogsToFile(SampleApp.LOG_FILE_PATH);
            }
        };
private val onMapReadyCallback = OnMapReadyCallback { tomtomMap ->
    val mapPaddingVertical = resources.getDimension(R.dimen.map_padding_vertical).toDouble()
    val mapPaddingHorizontal = resources.getDimension(R.dimen.map_padding_horizontal).toDouble()

    tomtomMap.uiSettings.currentLocationView.hide()
    tomtomMap.setPadding(
        mapPaddingVertical, mapPaddingHorizontal,
        mapPaddingVertical, mapPaddingHorizontal
    )
    tomtomMap.collectLogsToFile(SampleApp.LOG_FILE_PATH)
}

Attach OnMapReadyCallback to the MapFragment:

_

mapFragment.getAsyncMap(onMapReadyCallback);
mapFragment.getAsyncMap(onMapReadyCallback)

  4. Forward the permissions callbacks from 'Activity' to 'TomtomMap':

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
tomtomMap.onRequestPermissionsResult(requestCode, permissions, grantResults);
}

MapView initialization

In some cases, it may be required to directly use "MapView". To do this create a new instance by calling:

val mapView = MapView(context)

When working with MapView you need to pass lifecycle events as shown in the following example:

@Override
/** @inheritDoc */
public void onStart() {
    super.onStart();
    mapView.onStart();
}

@Override
/** @inheritDoc */
public void onResume() {
    super.onResume();
    mapView.onResume();
}

@Override
/** @inheritDoc */
public void onPause() {
    mapView.onPause();
    callbackContainer.removeAllCallbacks();
    super.onPause();
}

@Override
public void onStop() {
    mapView.onStop();
    super.onStop();
}

@Override
public void onDestroy() {
    mapView.onDestroy();
    super.onDestroy();
}

 

Map properties

IMPORTANT: In May 2020 the methods used to switch between vector and raster tiles were deprecated and will be removed after one year. From that point, to display raster tiles it will be required to reload the style to one which contains raster layers. Before the deprecation period is over, a map is still going to be initialized with the style that contains raster and vector tiles. However, if your style is obtained from the Style Merger you need to set MapStyleSource to STYLE_MERGER in MapProperties described here.

You can create an instance of the MapProperties class via its Builder to pass initial properties of the map to either MapFragment or MapView. MapProperties is a single point of initialization of different map parameters. It is possible to set the following properties:

Map properties can be specified depending on the implementation of Map:

  • Map background color:

MapProperties.Builder()
    .backgroundColor(Color.BLUE)
    .build()
  • Map style url:

MapProperties.Builder()
    .customStyleUri("asset://styles/style.json")
    .build()
  • Map initial camera position:

val cameraPosition = CameraPosition.builder()
    .focusPosition(LatLng(12.34, 23.45))
    .zoom(10.0)
    .bearing(24.0)
    .pitch(45.2)
    .build()
MapProperties.Builder()
    .cameraPosition(cameraPosition)
    .build()
  • Map initial camera focus area:

val cameraFocusArea = CameraFocusArea.Builder(
    BoundingBox(LatLng(52.407943, 4.808601), LatLng(52.323363, 4.969053))
)
    .bearing(24.0)
    .pitch(45.2)
    .build()
MapProperties.Builder()
    .cameraFocusArea(cameraFocusArea)
    .build()
  • Map initial padding:

MapProperties.Builder()
    .padding(MapPadding(50.0, 40.0, 100.0, 80.0))
    .build()
  • TomTom services API Keys:

val keysMap = mapOf(
    ApiKeyType.MAPS_API_KEY to "maps-key",
    ApiKeyType.TRAFFIC_API_KEY to "traffic-key"
)
MapProperties.Builder()
    .keys(keysMap)
    .build()
  • MapStyleSource is used to determine if the default and loaded style should support Style Merger. Setting it to STYLE_MERGER results in the default style only supporting vector tiles:

MapProperties.Builder()
    .mapStyleSource(MapStyleSource.STYLE_MERGER)
    .build()
  • LayerSetConfiguration is used to provide custom IDs for layer sources in the style. This is useful when the user has a custom style not compliant with the TomTom source names convention. An underlying builder allows the configuration of Map Tiles, Traffic Flow Tiles, and Traffic Incidents Tiles. LayerSetConfiguration should only be used with the MapStyleSource set to STYLE_MERGER.

val layerSetConfiguration = LayerSetConfiguration.Builder()
    .mapTilesConfiguration(MAP_TILES_SOURCE_ID)
    .trafficIncidentsTilesConfiguration(TRAFFIC_INCIDENTS_SOURCE_ID)
    .trafficFlowTilesConfiguration(TRAFFIC_FLOW_SOURCE_ID)
    .build()
MapProperties.Builder()
    .mapStyleSource(MapStyleSource.STYLE_MERGER)
    .layerSetConfiguration(layerSetConfiguration)
    .build()

The MapProperties instance can be passed to either MapFragment or MapView in the following way:

val fragment = MapFragment.newInstance(mapProperties)
val view = MapView(context, mapProperties)

MapProperties can be also declared in the XML:

<fragment
    android:id="@+id/map_fragment"
    android:name="com.tomtom.online.sdk.map.MapFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tomtom:mapBackgroundColor="@color/solid_black"
    tomtom:styleUrl="http://your-server:port/style/example-merged.json"
    tomtom:mapStyleSource="STYLE_MERGER"
    tomtom:cameraFocusAreaPitch="84.5"
    tomtom:cameraFocusAreaBearing="84.5"
    tomtom:cameraFocusAreaTopLeftLatitude="84.5"
    tomtom:cameraFocusAreaTopLeftLongitude="13.5"
    tomtom:cameraFocusAreaBottomRightLatitude="12.5"
    tomtom:cameraFocusAreaBottomRightLongitude="84.5"

    tomtom:mapPaddingTop="100"
    tomtom:mapPaddingLeft="12"
    tomtom:mapPaddingBottom="200"
    tomtom:mapPaddingRight="50"

    tomtom:cameraPositionZoom="11"
    tomtom:cameraPositionPitch="84.5"
    tomtom:cameraPositionBearing="84.5"
    tomtom:cameraPositionLatitude="84.5"
    tomtom:cameraPositionLongitude="84.5"

    tomtom:mapsApiKey="maps.api.key"
    tomtom:trafficApiKey="traffic.api.key" />

When using the Maps SDK for Android, it is required that the TomTom logo is always visible. By default, the TomTom logo is located at the bottom-left corner of the map. However, you can easily customise its position to meet your app design by defining the LogoView style in the style.xml file in your app.

Sample use case 1: Your app has a bottom panel which covers the TomTom logo and you need to place the logo in the top-right corner. To change the TomTom logo position:

<style name="LogoView" parent="BaseLogoView" >
    <item name="android:layout_gravity">bottom|left</item>
    <item name="android:layout_margin">@dimen/common_layout_zero_dp</item>
</style>

 

Logging

TomTom SDK Log level

In TomTom we are constantly working on the quality of our products. That is why it is very important to have logs as detailed as possible for our support team to provide accurate help or bugfixes. The Maps SDK for Android has an advanced mechanism to gather and send logs to our support team. To enable logging and specify a log level please add the following code to your app:

Example:

@Override
public void onCreate() {
    super.onCreate();
    LogUtils.enableLogs(Log.VERBOSE);
  • android.util.Log.VERBOSE will print all logs from TomTom SDK.

  • android.util.Log.DEBUG will print debug logs from TomTom SDK.

Note: Logs from the SDK libraries are disabled by default.

Collecting logs

TomTom log

Logs from an application can be collected into a file on the SD card.

LogUtils.collectLogsToFile(logsFilePath);

A special permission should be added into your AndroidManifest.xml file to save logs on the SD card. For example:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

When the sdk-maps module is used, the problem with supporting runtime permissions is handled by the SDK with the following method:

_

@Override
public void onMapReady(@NonNull TomtomMap tomtomMap) {
    tomtomMap.collectLogsToFile(SampleApp.LOG_FILE_PATH);
}
override fun onMapReady(tomtomMap: TomtomMap) {
    tomtomMap.collectLogsToFile(SampleApp.LOG_FILE_PATH)
}

Important: Since Android API level 23, it is required to ask the user for runtime permission to write into the SD card.

Register crash observer

Using the crash observer makes it possible to automate the process of preparing an email message with attached logs which were already collected and stored on the SD card. To do so, please register a crash handler with the following code. Crash observer doesn’t break your already-used handlers (like Crashlitics).

LogUtils.registerCrashObserver(getApplicationContext(), Uri.parse("file://" + LOGCAT_PATH), CRASH_OBSERVER_EMAIL);

Bug report

To enable an advanced logging mechanism which collects detailed data from logcat like: threads, services, and phone states, please use the following code:

adb bugreport issue01

This produces an issue01.zip file.