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`.
Getting started
The basic steps for adding a map are:
- Follow the steps described in the Getting started section.
- Add MapFragment to your Activity:
MapFragment
created from the code:
val mapFragment = MapFragment.newInstance()
MapFragment
declared in the XML:
1<fragment2 android:id="@+id/map_fragment"3 android:name="com.tomtom.online.sdk.map.MapFragment"4 android:layout_width="match_parent"5 android:layout_height="match_parent" />
To obtain the fragment reference call:
3. Implement the OnMapReadyCallback and use the onMapReady method to get the TomtomMap object:
1/**2 * Callback interface executed when the map is ready to be used.3 * The instance of this interface is set to {@link MapFragment},4 * and the {@link OnMapReadyCallback#onMapReady(TomtomMap)} is triggered5 * when the map is fully initialized and not-null.6 */7public interface OnMapReadyCallback {8 /**9 * Called when the map is ready to be used.10 */11 void onMapReady(@NonNull TomtomMap tomtomMap);12}
Sample implementation of the OnMapReadyCallback:
Attach OnMapReadyCallback to the MapFragment:
4. Forward the permissions callbacks from 'Activity' to 'TomtomMap':
1@Override2public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {3super.onRequestPermissionsResult(requestCode, permissions, grantResults);4tomtomMap.onRequestPermissionsResult(requestCode, permissions, grantResults);5}
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:
1@Override2public void onStart() {3 super.onStart();4 mapView.onStart();5}67@Override8public void onResume() {9 super.onResume();10 mapView.onResume();11}1213@Override14public void onPause() {15 mapView.onPause();16 super.onPause();17}1819@Override20public void onStop() {21 mapView.onStop();22 super.onStop();23}2425@Override26public void onDestroy() {27 mapView.onDestroy();28 super.onDestroy();29}3031@Override32public void onSaveInstanceState(@NonNull Bundle outState) {33 super.onSaveInstanceState(outState);34 mapView.onHostSaveInstanceState();35}
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:
1MapProperties.Builder()2 .backgroundColor(Color.BLUE)3 .build()
- Map style url:
1MapProperties.Builder()2 .customStyleUri("asset://styles/style.json")3 .build()
- Map initial camera position:
1val cameraPosition = CameraPosition.builder()2 .focusPosition(LatLng(12.34, 23.45))3 .zoom(10.0)4 .bearing(24.0)5 .pitch(45.2)6 .build()7MapProperties.Builder()8 .cameraPosition(cameraPosition)9 .build()
- Map initial camera focus area:
1val cameraFocusArea = CameraFocusArea.Builder(2 BoundingBox(LatLng(52.407943, 4.808601), LatLng(52.323363, 4.969053))3)4 .bearing(24.0)5 .pitch(45.2)6 .build()7MapProperties.Builder()8 .cameraFocusArea(cameraFocusArea)9 .build()
- Map initial padding:
1MapProperties.Builder()2 .padding(MapPadding(50.0, 40.0, 100.0, 80.0))3 .build()
- TomTom services API Keys:
1val keysMap = mapOf(2 ApiKeyType.MAPS_API_KEY to "maps-key",3 ApiKeyType.TRAFFIC_API_KEY to "traffic-key"4)5MapProperties.Builder()6 .keys(keysMap)7 .build()
MapStyleSource
is used to determine if the default and loaded style should support Style Merger. Setting it toSTYLE_MERGER
results in the default style only supporting vector tiles:
1MapProperties.Builder()2 .mapStyleSource(MapStyleSource.STYLE_MERGER)3 .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 theMapStyleSource
set toSTYLE_MERGER
.
1val layerSetConfiguration = LayerSetConfiguration.Builder()2 .mapTilesConfiguration(MAP_TILES_SOURCE_ID)3 .trafficIncidentsTilesConfiguration(TRAFFIC_INCIDENTS_SOURCE_ID)4 .trafficFlowTilesConfiguration(TRAFFIC_FLOW_SOURCE_ID)5 .build()6MapProperties.Builder()7 .mapStyleSource(MapStyleSource.STYLE_MERGER)8 .layerSetConfiguration(layerSetConfiguration)9 .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:
1<fragment xmlns:tomtom="http://schemas.android.com/apk/res-auto"2 android:id="@+id/map_fragment"3 android:name="com.tomtom.online.sdk.map.MapFragment"4 android:layout_width="match_parent"5 android:layout_height="match_parent"67 tomtom:mapStyleSource="STYLE_MERGER"8 tomtom:styleUrl="http://your-server:port/style/example-merged.json"910 tomtom:cameraFocusAreaBearing="84.5"11 tomtom:cameraFocusAreaBottomRightLatitude="12.5"12 tomtom:cameraFocusAreaBottomRightLongitude="84.5"13 tomtom:cameraFocusAreaPitch="84.5"14 tomtom:cameraFocusAreaTopLeftLatitude="84.5"15 tomtom:cameraFocusAreaTopLeftLongitude="13.5"1617 tomtom:cameraPositionBearing="84.5"18 tomtom:cameraPositionLatitude="84.5"19 tomtom:cameraPositionLongitude="84.5"20 tomtom:cameraPositionPitch="84.5"21 tomtom:cameraPositionZoom="11"2223 tomtom:mapBackgroundColor="@color/solid_black"2425 tomtom:mapPaddingBottom="200"26 tomtom:mapPaddingLeft="12"27 tomtom:mapPaddingRight="50"28 tomtom:mapPaddingTop="100"2930 tomtom:mapsApiKey="maps.api.key"31 tomtom:trafficApiKey="traffic.api.key" />
TomTom logo
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:
1<style name="LogoView" parent="BaseLogoView" >2 <item name="android:layout_gravity">bottom|left</item>3 <item name="android:layout_margin">@dimen/common_layout_zero_dp</item>4</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:
1@Override2public void onCreate() {3 super.onCreate();4 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:
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.