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

Map Examples

Map Examples

Have a look at our functional examples to see how easy it is to implement map features with the Maps Android SDK. Speed up development by using our sample code snippets in your app. Try all of this out with the Maps Android SDK Examples app!

Map Display

TomtomMap contains a variety of options consisting of a number of map layers: map tiles and traffic tiles.

Map tiles

Allow your users to display a map in either raster or vector format:

  • Raster tiles are served as images. They require less processing power and memory to render, but have a larger file size than vector tiles.

  • Vector tiles take the form of data that describes map entries such as geographic points, forests, lakes, built-up areas (as polygons), and roads (as lines). They are styled by means of a style sheet. Vector tiles can be scaled to different sizes without losing quality. The file size of vector tiles is smaller than that of raster tiles.

Sample use case 1: Your app is designed to use raster tiles for map display. You want to update the app with TomTom Map Display API raster tiles.

Sample use case 2: You want to take advantage of vector tiles features such as map 2.5 D perspective, custom map styles, etc.

Sample use case 3: Your app runs on devices with different capabilities. You want to use vector tiles for map display on powerful devices and raster tiles on devices with less processing power.

Use the following code snippets in your app to display the map with raster or vector tiles.

To select vector tiles:

_

tomtomMap.getUiSettings().setMapTilesType(MapTilesType.VECTOR);
tomtomMap.uiSettings.mapTilesType = MapTilesType.VECTOR

 

To select raster tiles:

_

tomtomMap.getUiSettings().setMapTilesType(MapTilesType.RASTER);
tomtomMap.uiSettings.mapTilesType = MapTilesType.RASTER

 

To turn off all tiles:

_

tomtomMap.getUiSettings().setMapTilesType(MapTilesType.NONE);
tomtomMap.uiSettings.mapTilesType = MapTilesType.NONE

 

In this example you will see buttons that allow switching between raster and vector tiles at runtime:

image

Raster tiles

image

Vector tiles

Traffic layers

Give your users the ability to see real time traffic in your mobile apps.

With Traffic Flow tiles your users will have information about congestion, the speed of traffic on different road segments, and the difference between that speed and the free-flow speed on the same road segments. You can find more information and details about Traffic Flow tile parameters on Vector Traffic Flow tiles or Raster Traffic Flow tiles.

Traffic Flow tiles

Traffic Flow tiles are available in two formats: vector (.pbf) and raster (.png). Vector tiles provide a possibility for visual customization and a better visual experience by means of a style sheet. Also, the vector tiles contain certain traffic information (e.g., road type, traffic level, etc.). Check Traffic Flow tags in the Vector Flow Tiles documentation for details.

Vector Traffic Flow tiles are used by default for traffic flow in the Maps SDK. You can switch to raster Traffic Flow tiles by using the following method:

_

tomtomMap.getTrafficSettings().turnOnRasterTrafficFlowTiles();
tomtomMap.trafficSettings.turnOnRasterTrafficFlowTiles()

 

You can change back to vector traffic tiles by using the following method:

_

tomtomMap.getTrafficSettings().turnOnVectorTrafficFlowTiles();
tomtomMap.trafficSettings.turnOnVectorTrafficFlowTiles()

 

Vector Traffic Flow tiles listener

Additionally, you can get details about the specific traffic flow of the road fragment (e.g., current speed, travel times, etc.) from the Flow Segment Data service which is integrated in the Maps SDK. This service is designed to work alongside the Traffic Flow tiles to support clickable flow data visualizations. This is handled for you in the Maps SDK. Set the following listener:

_

tomtomMap.getTrafficSettings().setOnTrafficFlowClickListener(new DefaultOnTrafficFlowClickListener(tomtomMap));
tomtomMap.trafficSettings.setOnTrafficFlowClickListener(DefaultOnTrafficFlowClickListener(this))

 

Then you need to implement the following interface which informs you if any Traffic Flow segment was clicked:

/**
 * A callback executed when traffic flow on the map is clicked.
 */
public interface OnTrafficFlowClickListener {
    /**
     * A callback executed when traffic flow on the map is clicked.
     *
     * @param mapPoint A point on the screen resolved as a location.
     * @param trafficFlows  A list of traffic points displayed under the clicked place on the map.
     */
    boolean onTrafficFlowClick(MapPoint mapPoint, List<TrafficFlow> trafficFlows);
}

which informs the user what place on the map is clicked and what traffic flows are clicked.

By the default implementation, when you click on the specific Traffic Flow segment, a balloon with details is shown:

tomtomMap.getTrafficSettings().showTrafficFlowBalloon(pointOnScreen, new TrafficFlowMapBalloon(flows));

 

The default listener dismisses a traffic balloon when information about traffic is not available:

tomtomMap.getTrafficSettings().dismissTrafficBalloon();

 

To set a custom view for the traffic balloon, the TrafficFlowBalloonViewAdapter should be implemented and set by the TrafficSettings#setTrafficFlowBalloonViewAdapter method. A default implementation is set as follows:

_

tomtomMap.getTrafficSettings().setTrafficFlowBalloonViewAdapter(new TrafficFlowBalloonViewAdapter.Default());
tomtomMap.trafficSettings.setTrafficFlowBalloonViewAdapter(TrafficFlowBalloonViewAdapter.Default())

 

Vector Traffic Incidents Tiles listener

You can get details about the specific traffic incidents flow and traffic incidents POIs (e.g., current speed, travel times, etc.) from the Vector Flow Tiles service which is integrated in the Maps SDK. This service is designed to work alongside the traffic tiles to support clickable incident data visualizations. This is handled for you in the Maps SDK. Set the following listener:

_

tomtomMap.getTrafficSettings().setOnTrafficIncidentsClickListener(new DefaultOnTrafficIncidentClickListener(tomtomMap));
tomtomMap.trafficSettings.setOnTrafficIncidentsClickListener(DefaultOnTrafficIncidentClickListener(this))

 

Next you need to implement the following interface which informs you if any traffic incident (POI, cluster, flow) was clicked:

/**
 * A callback executed when traffic flow on the map is clicked.
 */
public interface OnTrafficFlowClickListener {
    /**
     * A callback executed when traffic flow on the map is clicked.
     *
     * @param mapPoint A point on the screen resolved as a location.
     * @param trafficFlows  A list of traffic points displayed under the clicked place on the map.
     */
    boolean onTrafficFlowClick(MapPoint mapPoint, List<TrafficFlow> trafficFlows);
}

and informs the user what place on the map is clicked and what traffic flows are clicked.

By the default implementation, when you click on the specific traffic incident, a balloon with details is shown for incident flows:

tomtomMap.getTrafficSettings().showTrafficIncidentBalloon(mapPoint, TrafficIncidentsMapBalloon.ofFlows(incidentsFlows));

and for incident POIs

tomtomMap.getTrafficSettings().showTrafficIncidentBalloon(mapPoint, TrafficIncidentsMapBalloon.ofPois(incidentsPois));

 

For the default implementation of incident, click listener and zoom the map when a traffic cluster is clicked:

tomtomMap.getUiSettings().setCameraPosition(
        CameraPosition
                .builder(mapPoint.getPosition())
                .zoom(countNewZoom(incidentsCluster))
                .build()
);

 

To set a custom view for the traffic incident balloon, the TrafficIncidentsBalloonViewAdapter should be implemented and set by the TrafficSettings#setTrafficIncidentsBalloonViewAdapter method. A default implementation is set as follows:

_

tomtomMap.getTrafficSettings().setTrafficIncidentsBalloonViewAdapter(new TrafficIncidentsBalloonViewAdapter.Default());
tomtomMap.trafficSettings.setTrafficIncidentsBalloonViewAdapter(TrafficIncidentsBalloonViewAdapter.Default())

 

Traffic type and styles

Traffic tile styles are represented in the SDK as Java data classes. Traffic flow tile style types are represented in the SDK as data classes.

The available vector traffic flow styles listed below can be set by the following method:

_

tomtomMap.getTrafficSettings().turnOnVectorTrafficFlowTiles(new TrafficFlowType.RelativeTrafficFlowStyle()); //default
tomtomMap.getTrafficSettings().turnOnVectorTrafficFlowTiles(new TrafficFlowType.AbsoluteTrafficFlowStyle());
tomtomMap.getTrafficSettings().turnOnVectorTrafficFlowTiles(new TrafficFlowType.RelativeDelayTrafficFlowStyle());
tomtomMap.trafficSettings.turnOnVectorTrafficFlowTiles(TrafficFlowType.RelativeTrafficFlowStyle()) //default
tomtomMap.trafficSettings.turnOnVectorTrafficFlowTiles(TrafficFlowType.AbsoluteTrafficFlowStyle())
tomtomMap.trafficSettings.turnOnVectorTrafficFlowTiles(TrafficFlowType.RelativeDelayTrafficFlowStyle())

 

The available raster traffic flow styles listed below can be set by the following method:

_

tomtomMap.getTrafficSettings().turnOnRasterTrafficFlowTiles(new TrafficFlowType.RelativeTrafficFlowStyle()); //default
tomtomMap.getTrafficSettings().turnOnRasterTrafficFlowTiles(new TrafficFlowType.AbsoluteTrafficFlowStyle());
tomtomMap.getTrafficSettings().turnOnRasterTrafficFlowTiles(new TrafficFlowType.RelativeDelayTrafficFlowStyle());
//default
tomtomMap.trafficSettings.turnOnRasterTrafficFlowTiles(TrafficFlowType.RelativeTrafficFlowStyle())
tomtomMap.trafficSettings.turnOnRasterTrafficFlowTiles(TrafficFlowType.AbsoluteTrafficFlowStyle())
tomtomMap.trafficSettings.turnOnRasterTrafficFlowTiles(TrafficFlowType.RelativeDelayTrafficFlowStyle())
tomtomMap.trafficSettings.turnOnRasterTrafficFlowTiles(TrafficFlowType.ReducedSensitivityTrafficFlowStyle())

 

Sample use case: You want to visualize traffic information in your app so your users can adjust their commute based on traffic information.

Use the following code snippets in your app to enable and visualize the vector traffic flow layer on the map:

_

tomtomMap.getTrafficSettings().turnOnVectorTrafficFlowTiles();
tomtomMap.trafficSettings.turnOnVectorTrafficFlowTiles()

 

You can turn off traffic flow by using the following method:

_

tomtomMap.getTrafficSettings().turnOffTraffic();
tomtomMap.getTrafficSettings().turnOffTrafficFlowTiles();
tomtomMap.trafficSettings.turnOffTraffic()

 

Information about set style:

_

VectorTrafficFlowType style = tomtomMap.getTrafficSettings().getTrafficVectorFlowStyle();
val style = tomtomMap.trafficSettings.trafficVectorFlowStyle

 

Traffic incidents

Traffic incident style types are represented in the SDK as a data class. The available traffic incident options are shown in the following code examples:

  • Vector incident tiles and POIs:

_

tomtomMap.getTrafficSettings().turnOnVectorTrafficIncidents();
tomtomMap.trafficSettings.turnOnVectorTrafficIncidents()

 

  • Raster incident tiles:

_

tomtomMap.getTrafficSettings().turnOnRasterTrafficIncidents();
tomtomMap.trafficSettings.turnOnRasterTrafficIncidents()

 

You can turn off traffic incidents by using the following method:

_

tomtomMap.getTrafficSettings().turnOffTrafficIncidents();
tomtomMap.trafficSettings.turnOffTrafficIncidents()

 

image

Traffic vector flow layer shown on a vector map.

image

Traffic raster flow shown on a raster map.

image

Traffic vector incidents layer with the S1 file style.

image

Traffic raster incidents layer in the sample app.

image

Traffic vector incidents and raster flow layer on a raster map.

image

Traffic raster incidents and raster flow layer on a raster map.

image

No vector traffic in the sample app.

image

No raster traffic in the sample app.

My location layer

Allow your users to display and track their current location; by default it is disabled. Permissions to use GPS are automatically handled by the map.

Sample use case: You want to display the user’s current location and use it to plan a route.

To enable location tracking:

_

tomtomMap.setMyLocationEnabled(true);
tomtomMap.isMyLocationEnabled = true

To get user’s current location:

_

Location location = tomtomMap.getUserLocation();
val location = tomtomMap.userLocation

Map language

Allow your users to see a map in different languages to make your app international. The language parameter determines the language of labels on the map. It does not affect any proper nouns like the names of streets, plazas, etc. The list of the supported languages can be found at: Default View Mapping.

Sample use case: You want to have all labels only in British English

To change the language for a map:

_

//BRITISH_ENGLISH_CODE = "en-GB"
tomtomMap.setLanguage(BRITISH_ENGLISH_CODE);
//language can be equal e.g. to "en-GB"
tomtomMap.setLanguage(language)
image

Map labels in English

image

Map labels in Russian

image

Map labels in Dutch

Geopolitical view

Allow your users to see map boundaries based on unified or local country views. The local view is available for a particular area of the world that is considered disputed by two or more countries. You can change the geopolitical view of your map. If you don’t specify a geopolitical view the "Unified" view will be used. The Israel geopolitical view is currently available only for vector maps.

A list of the supported views can be found at Default View Mapping.

Note: Inside India’s territory only the "IN" geopolitical view is available without the possibility of being overridden.

Sample use case: You want to display a local map view for Israel.

To change the geopolitical view for the map:

_

//ISRAEL_LOCAL_VIEW = "IL"
tomtomMap.setGeopoliticalView(ISRAEL_LOCAL_VIEW);
tomtomMap.setGeopoliticalView("IL")
image

Israel international view

image

Israel local view

Multiple maps

Use this to display more than one map at the same time in your app. Developers are not limited to only attaching a single map. You can put as many map objects as you want on the same Activity without any issues.

Sample use case: You want to show a mini map with the night style and a different zoom level than the main map.

image

Map with building heights

Allow your users to see a map either in 2.5D with building heights enabled, or in 2D with building footprints.

Sample use case: Your application provides the possibility to display sophisticated visualization of the map with building heights (2.5D map), as well as displaying the map with building footprints (2D map).

The building heights data are available in Vector Map Tiles. The default TomTom map styles enable the display of building heights by default, but this can be disabled by switching off layers in the style.

Have a look at the detailed documentation for more related information at Vector Map Tiles and Map Style

In order to disable the display of the building heights you need to switch off corresponding layers in the style. That means that the following layers would need to be switched off in the default TomTom style: "Subway Station 3D", "Place of worship 3D", "Railway Station 3D", "Government Administration Office 3D", "Other building 3D", "School building 3D", "Other town block 3D", "Factory building 3D", "Hospital building 3D", "Hotel building 3D", and "Cultural Facility 3D. This will work in runtime.

val LAYERS_IN_3D_REGEX = listOf(
    "Subway Station 3D",
    "Place of worship 3D",
    "Railway Station 3D",
    "Government Administration Office 3D",
    "Other building 3D",
    "School building 3D",
    "Other town block 3D",
    "Factory building 3D",
    "Hospital building 3D",
    "Hotel building 3D",
    "Cultural Facility 3D")
    .joinToString(separator = "|")

Use the following code snippets in your app to display building footprints (i.e., switch building heights off):

val layers = tomtomMap.styleSettings.findLayersById(LAYERS_IN_3D_REGEX)
layers.forEach { layer ->
    layer.visibility = Visibility.NONE
}

Use the following code snippets in your app to display building heights (i.e., switch building heights back on):

val layers = tomtomMap.styleSettings.findLayersById(LAYERS_IN_3D_REGEX)
layers.forEach {
    it.visibility = Visibility.VISIBLE
}
image

Switching the heights on

image

Switching the heights off

Map manipulation

When you use the TomtomMap in your application, users will like to play with it in a variety of ways. In this section you will learn how to implement these actions and how to register for their callbacks.

Map centering

Center the map in your mobile app either at the current coordinates or any other location at the zoom level of your choice.

Sample use case: You want to display the maps for selected cities in specific zoom levels. Your users should be able to easily switch between different locations.

Use the following code snippets in your app to display maps of different locations (in this case, the current location and the TomTom offices in Amsterdam and Berlin).

The example shows how to center the map on Amsterdam with the zoom level set to 10:

_

tomtomMap.centerOn(
        Locations.AMSTERDAM_LOCATION.getLatitude(),
        Locations.AMSTERDAM_LOCATION.getLongitude(),
        DEFAULT_ZOOM_LEVEL,
        MapConstants.ORIENTATION_NORTH);
tomtomMap.centerOn(location.latitude,
    location.longitude,
    zoomLevel,
    bearing)

 

image

Map centered on Amsterdam with 10 zoom level

image

Map centered on London with 10 zoom level

image

Map centered on Berlin with 10 zoom level

Map perspective

Set either the 2D map perspective for the typical map view mode, or the 2.5D map perspective for custom scenarios such as moving the map.

Sample use case: You want to switch from 2D to 2.5D modes to support following the moving location in your app.

Use the following code snippets in your app to switch between perspectives.

Note that switching between 2D and 3D modes only changes the perspective. The zoom level and map orientation are set with the methods described in the "Map centering" example.

In order to change the map mode to 2-dimensional, you need to call the following method:

_

tomtomMap.set2DMode();
tomtomMap.set2DMode()

 

To change it back to 3D simply apply the other option setting:

_

tomtomMap.set3DMode();
tomtomMap.set3DMode()

 

image

3D map perspective

image

2D map perspective

Map events

Implement any action you need to be triggered on one of the following map events:

  • Panning

  • Single press

  • Double press

  • Long press

Sample use case: In your app, users invoke one behavior with a single press and another with a long press.

Use the following code snippets in your app to catch map events. In this example, the action is simply to display a toast with latitude and longitude on each map event. Of course, you can implement other cool features instead.

If you want to receive callbacks after a map is clicked, long-clicked, or panned, then you need to define your own TomtomMapCallback listeners:

_

private TomtomMapCallback.OnMapClickListener onMapClickListener =
        latLng -> displayMessage(
                R.string.menu_events_on_map_click,
                latLng.getLatitude(),
                latLng.getLongitude()
        );
private TomtomMapCallback.OnMapLongClickListener onMapLongClickListener =
        latLng -> displayMessage(
                R.string.menu_events_on_map_long_click,
                latLng.getLatitude(),
                latLng.getLongitude()
        );
private TomtomMapCallback.OnMapViewPortChanged onMapViewPortChangedListener =
        (focalLatitude, focalLongitude, zoomLevel, perspectiveRatio, yawDegrees) -> displayMessage(
                R.string.menu_events_on_map_panning,
                focalLatitude,
                focalLongitude
        );
private val showMessageWhenOnMapClick: TomtomMapCallback.OnMapClickListener = object : TomtomMapCallback.OnMapClickListener {
    override fun onMapClick(latLng: LatLng) {
        displayMessage(SINGLE_PRESS_TITLE, latLng)
    }
}

private val showMessageWhenOnMapLongClick: TomtomMapCallback.OnMapLongClickListener = object : TomtomMapCallback.OnMapLongClickListener {
    override fun onMapLongClick(latLng: LatLng) {
        displayMessage(LONG_CLICK_TITLE, latLng)
    }
}

private val showMessageWhenOnMapViewPortChanges: TomtomMapCallback.OnMapViewPortChanged = object : TomtomMapCallback.OnMapViewPortChanged {
    override fun onMapViewPortChanged(lat: Float, lon: Float, zoom: Double, perspectie: Float, yaw: Float) {
        displayMessage(VIEW_PORT_CHANGE_TITLE, LatLng(lat.toDouble(), lon.toDouble()))
    }
}

 

Then set them to your TomtomMap instance:

_

tomtomMap.addOnMapClickListener(onMapClickListener);
tomtomMap.addOnMapLongClickListener(onMapLongClickListener);
tomtomMap.addOnMapViewPortChangedListener(onMapViewPortChangedListener);
tomtomMap.addOnMapClickListener(showMessageWhenOnMapClick)
tomtomMap.addOnMapLongClickListener(showMessageWhenOnMapLongClick)
tomtomMap.addOnMapViewPortChangedListener(showMessageWhenOnMapViewPortChanges)

 

In this example you will see a Toast with the latitude and longitude of a point that was clicked on the map, but you can utilize this information in your own manner.

image

Receive callbacks after the map is clicked.

image

Receive callbacks after the map is long clicked.

image

Receive callbacks after the map panning.

Enable and disable gestures

You can disable gestures such as zooming, panning, and rotating in your application by passing the gestures settings object to tomtomMap: By default all gestures are enabled.

Disable zooming gesture

_

tomtomMap.updateGesturesDetectionSettings(
        GesturesDetectionSettingsBuilder.create()
                .zoomEnabled(false)
                .build()
);
tomtomMap.updateGesturesDetectionSettings(
        GesturesDetectionSettingsBuilder.create()
                .zoomEnabled(false)
                .build())

 

Disable the rotating gesture

_

tomtomMap.updateGesturesDetectionSettings(
        GesturesDetectionSettingsBuilder.create()
                .rotationEnabled(false)
                .build()
);
tomtomMap.updateGesturesDetectionSettings(
        GesturesDetectionSettingsBuilder.create()
                .rotationEnabled(false)
                .build()
)

 

Disable the tilting gesture

_

tomtomMap.updateGesturesDetectionSettings(
        GesturesDetectionSettingsBuilder.create()
                .tiltEnabled(false)
                .build()
);
tomtomMap.updateGesturesDetectionSettings(
        GesturesDetectionSettingsBuilder.create()
                .tiltEnabled(false)
                .build()
)

 

Disable the panning gesture

_

tomtomMap.updateGesturesDetectionSettings(
        GesturesDetectionSettingsBuilder.create()
                .panningEnabled(false)
                .build()
);
tomtomMap.updateGesturesDetectionSettings(
        GesturesDetectionSettingsBuilder.create()
                .panningEnabled(false)
                .build()
)

 

You can turn off more than one gesture by setting up the mask on properties as shown in the following code snippets:

_

tomtomMap.updateGesturesDetectionSettings(
        GesturesDetectionSettingsBuilder.create()
                .rotationEnabled(false)
                .panningEnabled(false)
                .build()
);
tomtomMap.updateGesturesDetectionSettings(
        GesturesDetectionSettingsBuilder.create()
                .rotationEnabled(false)
                .panningEnabled(false)
                .build()
)

 

If you want to enable gestures, pass the GesturesDetectionSettings object to the tomtomMap object as shown in the following code snippets:

_

tomtomMap.updateGesturesDetectionSettings(
        GesturesDetectionSettingsBuilder.create()
                .rotationEnabled(true)
                .panningEnabled(true)
                .zoomEnabled(true)
                .tiltEnabled(true)
                .build()
);
tomtomMap.updateGesturesDetectionSettings(
        GesturesDetectionSettingsBuilder.create()
                .rotationEnabled(true)
                .panningEnabled(true)
                .zoomEnabled(true)
                .tiltEnabled(true)
                .build()
)

 

or even in a simpler way:

_

tomtomMap.updateGesturesDetectionSettings(
        GesturesDetectionSettings.createDefault()
);
tomtomMap.updateGesturesDetectionSettings(
        GesturesDetectionSettings.createDefault()
)

 

Map UI Extensions

Use default compass, current location buttons, zooming, and panning controls built into the Maps SDK. You can read more on the Map UI extensions page.

Sample use case 1: You want to provide your users with the compass, current location, and panning and zooming controls so they can quickly center the map on their current location, set it to display north at the top of the screen after rotating the map, and pan or zoom the map. You can use the default controls provided with the Maps SDK.

Sample use case 2: You want to provide your users with the compass, current location, panning and zooming controls and you want to use custom icons that are designed for your app style.

Sample use case 3: In some of the screens in your app, you want to remove the compass, current location, and panning and zooming controls.

Since all ui elements are fully customizable because the Android view’s properties are exposed, changing the default icons for them is straight forward:

_

ArrowButtonsGroup arrowButtons = tomtomMap.getUiSettings().getPanningControlsView().getView();
arrowButtons.getArrowDownButton().setImageResource(R.drawable.btn_down_custom);
arrowButtons.getArrowUpButton().setImageResource(R.drawable.btn_up_custom);
arrowButtons.getArrowLeftButton().setImageResource(R.drawable.btn_left_custom);
arrowButtons.getArrowRightButton().setImageResource(R.drawable.btn_right_custom);
val arrowButtonGroup: ArrowButtonsGroup = tomtomMap.uiSettings.panningControlsView.getView()
arrowButtonGroup.arrowDownButton.setImageResource(R.drawable.arrow_button_down_custom)
arrowButtonGroup.arrowUpButton.setImageResource(R.drawable.arrow_button_up_custom)
arrowButtonGroup.arrowLeftButton.setImageResource(R.drawable.arrow_button_left_custom)
arrowButtonGroup.arrowRightButton.setImageResource(R.drawable.arrow_button_right_custom)

 

_

ZoomButtonsGroup zoomButtons = tomtomMap.getUiSettings().getZoomingControlsView().getView();
zoomButtons.getZoomInButton().setImageResource(R.drawable.btn_zoom_in_custom);
zoomButtons.getZoomOutButton().setImageResource(R.drawable.btn_zoom_out_custom);
val zoomButtonsGroup: ZoomButtonsGroup = tomtomMap.uiSettings.zoomingControlsView.getView()
zoomButtonsGroup.zoomInButton.setImageResource(R.drawable.zoom_in_button_custom)
zoomButtonsGroup.zoomOutButton.setImageResource(R.drawable.zoom_out_button_custom)

 

image

Default ui extensions controls

image

Default ui extensions controls - Hidden

image

Custom ui extensions controls

Map layers visibility

Allow your users to dynamically toggle the visibility of map entities. You can hide map layers to get the level of detail you need and highlight the layers that are important for your use case.

Sample use case: You want to provide a clear map view for driving that focuses on the road network in your app. You can achieve that by switching off some map layers e.g., woodland, build-up areas, etc. You can turn these layers back on at run time to bring back the details for a better map viewing experience.

The following articles provide more information on map layer visibility and map layers available in the default style: Map layers, Default style.

You can retrieve all layers available in the style or only those that match the provided regex. To filter, you can use layer ID or source layer ID properties, as shown in the following code snippets:

_

//ROADS_NETWORK_LAYER_REGEX = "[mM]otorway.*|.*[rR]oad.*"
List<Layer> layers = tomtomMap.getStyleSettings().findLayersBySourceLayerId(ROADS_NETWORK_LAYER_REGEX);
//regex = e.g. "[mM]otorway.*|.*[rR]oad.*" or "[wW]oodland" or "Built-up area"
val layers = tomtomMap.styleSettings.findLayersBySourceLayerId(String.format(regex))

Once you have a list of layers, you can modify their visibility:

_

for (Layer layer : layers) {
    layer.setVisibility(visibility);
}
layers.forEach { layer -> layer.visibility = visibility }
image

Road network hidden

image

Woodland and build-up shown

Dynamic map sources

Add layers and sources (e.g., GeoJSON, images) to the map in real time. This will allow you to dynamically change a map’s style in response to user interaction and context.

Sample use case 1: You want to add extra layers with building plans from your custom source.

Sample use case 2: You want to dynamically modify source parameters (e.g., a URL).

To create a layer and dynamically add it to the style:

_

Layer layer = LayerFactory.createLayer(layerJson);
tomtomMap.getStyleSettings().addLayer(layer);
val layer = LayerFactory.createLayer(layerJson)
tomtomMap.styleSettings.addLayer(layer)

To create a GeoJSON source and dynamically add it to the style:

_

//GEOJSON_SOURCE_ID = unique_source_id
//GeoJsonData = JSON representing source data
GeoJsonSource source = SourceFactory.createGeoJsonSource(GEOJSON_SOURCE_ID);
source.setGeoJson(geoJsonData);
tomtomMap.getStyleSettings().addSource(source);
//GEOJSON_SOURCE_ID = unique_source_id
//GeoJsonData = JSON representing source data
val source = SourceFactory.createGeoJsonSource(GEOJSON_SOURCE_ID)
source.setGeoJson(geoJsonData)
tomtomMap.styleSettings.addSource(source)

To create an Image source:

_

//IMAGE_SOURCE_ID = unique_source_id
//IMAGE_CORNERS = Four corners of the image (top left, top right, bottom right, bottom left)
ImageSource source = SourceFactory.createImageSource(IMAGE_SOURCE_ID, IMAGE_CORNERS);
source.setImage(getContext().getResources().getDrawable(R.drawable.buckingham_palace_plan));
tomtomMap.getStyleSettings().addSource(source);
//IMAGE_SOURCE_ID = unique_source_id
//IMAGE_CORNERS = Four corners of the image (top left, top right, bottom right, bottom left)
val source = SourceFactory.createImageSource(IMAGE_SOURCE_ID, IMAGE_CORNERS)
source.setImage(context.resources.getDrawable(R.drawable.buckingham_palace_plan))
tomtomMap.styleSettings.addSource(source)

To remove a source or a layer from the style:

_

tomtomMap.getStyleSettings().removeLayer(GEOJSON_LAYER_ID);
tomtomMap.getStyleSettings().removeSource(GEOJSON_SOURCE_ID);
tomtomMap.styleSettings.removeLayer(layerId)
tomtomMap.styleSettings.removeSource(sourceId)
image

Custom GeoJSON source

image

Custom image source

Dynamic Layer Ordering

You can dynamically change the z-order of the layers on the map to make the layers important to your use case visible on top of other layers.

Sample use case : You placed images on the map in your app but your users can bring the route and the road network on top of the images to see what the route looks like in detail.

image

Images layer moved to the front

_

// layersImages = tomtomMap.getStyleSettings().findLayersById(IMAGE_LAYER_ID + "[0-9]");
// Layer imgLayer = layersImages.get(...)
// tomtomMap.getStyleSettings().moveLayerBehind(layer.getId(), "");
layersHelper.moveLayerToFront(imgLayer);
//REFERENCE_LAYER = ""
tomtomMap.styleSettings.moveLayerBehind(layer.id, REFERENCE_LAYER)
image

GeoJson layer with line moved to the front

_

// layerGeoJson = tomtomMap.getStyleSettings().findLayerById("layer-line-id").orNull();
// tomtomMap.getStyleSettings().moveLayerBehind(layerGeoJson.getId(), "");
layersHelper.moveLayerToFront(layerGeoJson);
//REFERENCE_LAYER = ""
tomtomMap.styleSettings.moveLayerBehind(layer.id, REFERENCE_LAYER)
image

Roads layer moved to the front

_

// layersRoads = tomtomMap.getStyleSettings().findLayersById(".*[rR]oad.*|.*[mM]otorway.*");
// Layer roadLayer = layersRoads.get(...)
tomtomMap.getStyleSettings().moveLayerBehind(roadLayer.getId(), "");
//REFERENCE_LAYER = ""
tomtomMap.styleSettings.moveLayerBehind(layer.id, REFERENCE_LAYER)

Interactive map layers

Retrieve data of a feature (e.g., ID, geometry) from layers in the style by querying for rendered features at a point, coordinates, or a bounding box within a specified layer in the style.

Sample use case 1: You want to display information if the user clicks the layer that you added.

Sample use case 2: You want to return all visible features in a viewport.

To create a layer and dynamically add it to the style:

_

Layer layer = LayerFactory.createLayer(layerJson);
tomtomMap.getStyleSettings().addLayer(layer);
val layer = LayerFactory.createLayer(layerJson)
tomtomMap.styleSettings.addLayer(layer)

 

To query the style for specific layer features at a given screen point, call:

_

List<String> layerIds = ImmutableList.of(GEOJSON_LAYER_ID);
FeatureCollection featureCollection = tomtomMap.getDisplaySettings().featuresAtPoint(point, layerIds);
val layerIds = listOf(GEOJSON_LAYER_ID)
val featureCollection = tomtomMap.displaySettings.featuresAtPoint(point, layerIds)

 

To query the style for specific layer features in a given screen box, call:

_

FeatureCollection featureCollection = tomtomMap.getDisplaySettings().featuresInScreenRect(mapViewPort, layerIds);
val featureCollection = tomtomMap.displaySettings.featuresInScreenRect(mapViewPort, LAYER_LIST)

 

To obtain and process features:

_

List<Feature> featureList = featureCollection.getFeatures();
FuncUtils.forEach(featureList, feature -> FuncUtils.apply(feature.getId(), this::displayToast));
val featureList = featureCollection.features
FuncUtils.forEach(featureList) { feature -> FuncUtils.apply(feature.id) { id -> displayToast(id) } }
image

GeoJSON polygon clicked

image

Features in viewport

Map layer filtering

Allow your users to apply a filter based on feature properties to only show selected layers.

Sample use case: You are using Traffic Module in your application, and you only want to show the traffic flow on Motorways.

You can achieve that by applying a filter that takes the value of the "road_type" property defined in the Traffic Vector Flow Tiles and compares it with the "Motorway" value. In this case the filter needs to be applied on layers that have a layer with an id of "Traffic flow" as their source layer.

To retrieve all those layers you can use the findLayersBySourceLayerId method as shown in the following code snippet:

//LAYERS_REGEX = "Traffic flow"
val layers = tomtomMap.styleSettings.findLayersBySourceLayerId(LAYERS_REGEX)

Once you have a list of layers, you can create the expression defining the filter (it is required to create a new instance of the expression for every layer):

//ROAD_TYPE = "road_type"
//ROAD_TYPE_MOTORWAY = "Motorway"
val filteringExpression = ComparisonExpression.eq(
    GetExpression.get(ROAD_TYPE),
    LiteralExpression.string(ROAD_TYPE_MOTORWAY)
)

To apply the filer you have to provide it to the setFiler method of the Layer object:

layer.setFilter(filteringExpression)

Removing the filter is done by calling the resetFilter method of the Layer object.

layer.resetFilter()
image

Show traffic only on motorways

image

Show traffic only on major roads

image

Show traffic on all roads

Image clustering

Allow your users to cluster image annotations for better visualization. By default clustering is disabled.

Sample use case 1: You want to cluster images in the FeatureCollection type provided in GeoJSON.

To enable clustering you need to set:

"cluster": true,

and set the desired cluster radius:

"clusterRadius": 70,

Here you can see what the GeoJSON Source style file with enabled clustering looks like:

"IC-app-test-source": {
    "type": "geojson",
    "cluster": true,
    "clusterRadius": 70,
    "data": {
      "type": "FeatureCollection",
      "features": [
        {
          "type": "Feature",
          "geometry": {
            "type": "Point",
            "coordinates": [
              4.710759,
              52.340415
            ]
          },
          "properties": {
            "icon": "jet_airplane_landing"
          }
        }
      ]
    }
  }

You also need to add a new Layer to the current style that defines behaviour when your features do not fulfill clustering constraints.

{
  "id": "IC-layer-cluster-image",
  "filter": ["!has", "point_count"],
  "type": "symbol",
  "layout": {
    "icon-image":  "{icon}",
    "icon-allow-overlap": true
  },
  "source": "IC-clustering-source"
}

Please also remember if the feature "properties": {"icon": "jet_airplane_landing"} is set you need to add an image to Style as follows:

val image = ImageFactory.createImage(imageId, context.resources.getDrawable(imageResId))
tomtomMap.styleSettings.addImage(image)

 

Sample use case: You want to add a background overlay under the cluster size.

You need to create Layer with given content:

{
  "id": "IC-layer-clustered",
  "filter": ["has", "point_count"],
  "type": "symbol",
  "layout": {
    "icon-image":  "ic_cluster",
    "icon-allow-overlap": true,
    "icon-ignore-placement": true
  },
  "source": "IC-clustering-source"
}

and add it to current map style.

Sample use case: You want to customize the cluster symbol text color, text size, and offset.

You need to define Layer with given JSON content:

{
  "filter": ["has", "point_count"],
  "id": "IC-layer-symbol-count",
  "source": "IC-clustering-source",
  "type": "symbol",
  "layout": {
    "text-field": "{point_count}",
    "text-font": [
      "Noto-Bold"
    ],
    "text-size": 14,
    "text-offset": [0.0, 0.0]
  },
  "paint": {
    "text-color": "#FFFFFF"
  }
}

and add it to current map style.

Code Example

Here you can check what an example implementation may look like:

  • adding map source

val imageSourceJson = AssetUtils.getAssetFile(context, SOURCE_PATH)
val source = SourceFactory.createSource(imageSourceJson)
tomtomMap.styleSettings.addSource(source)
  • adding map layer with a given file name

val imageLayerJson = AssetUtils.getAssetFile(context, LAYER_CLUSTER_IMAGE_PATH)
val imageLayer = LayerFactory.createLayer(imageLayerJson)
tomtomMap.styleSettings.addLayer(imageLayer)
image

Clusters and images

Map annotations

Markers

Utilize different Maps SDK marker features to provide engaging functionality in your mobile app.

The main marker features are:

  • Customizable marker icons: Use the default TomTom marker, or favorite icons, or use your own.

  • Simple and decal marker mode: Choose how the marker is rendered on the map.

  • Draggable markers: Allow your users to drag and drop a marker around the map.

  • Animated markers: Use GIFs as marker icons.

You can find details of each of the marker features following the examples on this page.

Sample use case: In your app, you want to display a number of markers to mark places on the map. Use the code snippet below to display a single marker at specific coordinates on the map.

_

MarkerBuilder markerBuilder = new MarkerBuilder(position)
        .icon(Icon.Factory.fromResources(context, R.drawable.ic_favourites))
        .markerBalloon(new SimpleMarkerBalloon(positionToText(position)))
        .tag("more information in tag").iconAnchor(MarkerAnchor.Bottom)
        .decal(true); //By default is false
tomtomMap.addMarker(markerBuilder);
val markerBuilder = MarkerBuilder(position)
        .icon(icon)
        .markerBalloon(SimpleMarkerBalloon(positionToText(position)))
        .tag(SERIALIZABLE_MARKER_TAG)
        .iconAnchor(MarkerAnchor.Bottom)
        .decal(true) //By default is false
tomtomMap.addMarker(markerBuilder)

Examples are shown in the following code snippet:

image

Icon Marker

image

Decal Marker

Create a simple marker with a default icon and add it to the map; only the location needs to be specified:

_

MarkerBuilder markerBuilder = new MarkerBuilder(position)
        .markerBalloon(new SimpleMarkerBalloon(positionToText(position)));
tomtomMap.addMarker(markerBuilder);
val markerBuilder = MarkerBuilder(position)
        .markerBalloon(SimpleMarkerBalloon(positionToText(position)))
tomtomMap.addMarker(markerBuilder)

Marker selected

You can implement an observable marker selected event. You can do that with the global listener OnMarkerClickedListener for all markers that have to be registered on MarkerSettings as shown in the following code snippets:

_

tomtomMap.addOnMarkerClickListener(this);
tomtomMap.addOnMarkerClickListener(markerListener)

 

For that purpose, the passed object has to implement the following interface:

interface OnMarkerClickListener {
    /**
     * Called when the user clicks on the marker.
     *
     * @param marker Selected marker.
     */
    void onMarkerClick(@NonNull Marker marker);
}

 

You can remove all markers from the map in this way:

_

tomtomMap.removeMarkers();
tomtomMap.removeMarkers()

You can remove all the markers one-by-one in this way:

  • Remove all markers with the tag "tag".

_

tomtomMap.removeMarkerByTag("tag");
tomtomMap.removeMarkerByTag("tag")
  • Remove marker by id.

_

tomtomMap.removeMarkerByID(1);
tomtomMap.removeMarkerByID(1)

 

Simple and decal marker modes

  • Focal (default): Where the icon always stands vertically even when the map is rotated. All nine callout anchor points are supported with this annotation type.

  • Decal: Where the icon sticks to the map even when the map is rotated. Only one callout anchor point is supported for decal MarkerAnchor - Bottom.

Mixing icons of different modes is generally unsupported and advised against, as there are unresolvable depth-sorting issues and the results will not always look correct. It is safe to mix some modes, however, such as either of the decal modes with any of the standing modes.

Non-decal icons may optionally cast a shadow on the map. You will need to leave additional empty space between icons in your drawable if you specify a non-zero blur amount.

Draggable markers

Thanks to this feature your users are able move existing markers around the map. They long-click on a marker that is on the map to start dragging it, then they drop the marker on a selected position by releasing the finger from the screen.

In order to do that you need to set 'draggable' to true:

_

MarkerBuilder markerBuilder = new MarkerBuilder(position)
        .markerBalloon(new SimpleMarkerBalloon(positionToText(position)))
        .draggable(true);
tomtomMap.addMarker(markerBuilder);
val markerBuilder = MarkerBuilder(position)
        .markerBalloon(SimpleMarkerBalloon(positionToText(position)))
        .draggable(true)
tomtomMap.addMarker(markerBuilder)

It is also possible to register to receive the Marker’s dragging callbacks.

As an example you can create a listener like this one:

_

TomtomMapCallback.OnMarkerDragListener onMarkerDragListener = new TomtomMapCallback.OnMarkerDragListener() {
    @Override
    public void onStartDragging(@NonNull Marker marker) {
        Timber.d("onMarkerDragStart(): " + marker.toString());
        displayMessage(R.string.marker_dragging_start_message, marker.getPosition().getLatitude(), marker.getPosition().getLongitude());
    }

    @Override
    public void onStopDragging(@NonNull Marker marker) {
        Timber.d("onMarkerDragEnd(): " + marker.toString());
        displayMessage(R.string.marker_dragging_end_message, marker.getPosition().getLatitude(), marker.getPosition().getLongitude());
    }

    @Override
    public void onDragging(@NonNull Marker marker) {
        Timber.d("onMarkerDragging(): " + marker.toString());
    }
};
private var onMarkerDragListener: TomtomMapCallback.OnMarkerDragListener = object : TomtomMapCallback.OnMarkerDragListener {
    override fun onStartDragging(marker: Marker) {
        displayMessage(R.string.marker_dragging_start_message, marker.position.latitude, marker.position.longitude)
    }

    override fun onStopDragging(marker: Marker) {
        displayMessage(R.string.marker_dragging_end_message, marker.position.latitude, marker.position.longitude)
    }

    override fun onDragging(marker: Marker) {
    }
}

Then register it to receive events related to dragging the marker over the map:

_

tomtomMap.getMarkerSettings().addOnMarkerDragListener(onMarkerDragListener);
tomtomMap.markerSettings.addOnMarkerDragListener(onMarkerDragListener)

Animated markers

Thanks to this feature you can use GIFs as marker icons. For this purpose, you need to place your images in the assets folder and then use them in the following way:

_

MarkerBuilder markerBuilder = new MarkerBuilder(position)
        .icon(createAnimatedIcon());
tomtomMap.addMarker(markerBuilder);
val markerBuilder = MarkerBuilder(position)
        .icon(icon)
tomtomMap.addMarker(markerBuilder)

Marker anchoring

You can change the anchoring point for your icon. The anchor specifies which point of an annotation image is attached to the map. The annotation will rotate around this anchoring point when rotating the map. You can use the default image representation of an annotation which is attached to the bottom height center width as presented in the following figure. You can change this behavior by MarkerAnchor enumeration on the builder. E.g., if you want to use a crosshair annotation image, you should set the anchor to MarkerAnchor.Center

_

MarkerBuilder markerBuilder = new MarkerBuilder(position)
        .icon(Icon.Factory.fromResources(context, R.drawable.ic_favourites))
        .markerBalloon(new SimpleMarkerBalloon(positionToText(position)))
        .tag("more information in tag").iconAnchor(MarkerAnchor.Bottom)
        .decal(true); //By default is false
tomtomMap.addMarker(markerBuilder);
val markerBuilder = MarkerBuilder(position)
        .icon(icon)
        .markerBalloon(SimpleMarkerBalloon(positionToText(position)))
        .tag(SERIALIZABLE_MARKER_TAG)
        .iconAnchor(MarkerAnchor.Bottom)
        .decal(true) //By default is false
tomtomMap.addMarker(markerBuilder)

All possible anchors are defined in the enum:

/**
 * Copyright (c) 2015-2020 TomTom N.V. All rights reserved.
 *
 * This software is the proprietary copyright of TomTom N.V. and its subsidiaries and may be used
 * for internal evaluation purposes or commercial use strictly subject to separate licensee
 * agreement between you and TomTom. If you are the licensee, you are only permitted to use
 * this Software in accordance with the terms of your license agreement. If you are not the
 * licensee then you are not authorised to use this software in any manner and should
 * immediately return it to TomTom N.V.
 */
package com.tomtom.online.sdk.map;

import java.io.Serializable;

/**
 * The anchor property of the marker.
 */
public enum MarkerAnchor implements Serializable {

    /**
     * Value of(0,-0.5).
     */
    Center(0f, -0.5f),
    /**
     * Value of(-0.5,-0.5).
     */
    Left(-0.5f, -0.5f),

    /**
     * Value of(0.5,-0.5).
     */
    Right(0.5f, -0.5f),
    /**
     * Value of(0, 0).
     */
    Top(0, 0),

    /**
     * Value of(0,-1).
     */
    Bottom(0, -1f),

    /**
     * Value of(-0.5, 0).
     */
    TopLeft(-0.5f, 0),
    /**
     * Value of(0.5,0).
     */
    TopRight(0.5f, 0),

    /**
     * Value of(-0.5,-1).
     */
    BottomLeft(-0.5f, -1f),

    /**
     * Value of(0.5,-1).
     */
    BottomRight(0.5f, -1f);

    /**
     * Defines the icon offset in the x axis.
     */
    public float xIconOffset;

    /**
     * Defines the icon offset in the y axis.
     */
    public float yIconOffset;

    MarkerAnchor(float xIconOffset, float yIconOffset) {
        this.xIconOffset = xIconOffset;
        this.yIconOffset = yIconOffset;
    }
}

Marker performance

For performance purposes, it is recommended to combine multiple icons into a single drawable, and specify the sub-region of the icon you are interested in. If you use this approach, be sure to leave at least one empty pixel between the icons in your image to keep the edges from blending together as the icons are scaled.

Markers clustering

Allow your users to cluster markers for better visualization. By default, marker clustering is disabled. You can decide for each marker if it should be included in the clustering process or not (e.g., you want to have a few markers that are never clustered). To manipulate marker clustering, use MarkerSettings obtained from TomtomMap.

Sample use case: You want to display the distribution of parking spots across the city. Individual parking spots are shown only at higher zoom levels, otherwise data is clustered for better visualization.

To enable markers clustering:

_

tomtomMap.getMarkerSettings().setMarkersClustering(true);
tomtomMap.markerSettings.setMarkersClustering(true)

To flag a marker that it should be clustered:

_

MarkerBuilder markerBuilder = new MarkerBuilder(position)
        .shouldCluster(true)
        .markerBalloon(new SimpleMarkerBalloon(positionToText(position)));
val markerBuilder = MarkerBuilder(position)
        .shouldCluster(true)
        .markerBalloon(SimpleMarkerBalloon(positionToText(position)))

Examples are shown below:

image

Lower zoom level

image

Higher zoom level

Balloons

Allow your users to display and customize balloons in a few lines of code.

Sample use case: You would like to learn more about a place on the map. Depending on the selected location, the app displays a balloon containing either text or additional information such as icons or pictures.

Every Marker can be linked with a corresponding balloon to display detailed information. Balloons can be triggered in two ways:

  • Automatically, if the annotation is tapped on the map.

  • Calling the Marker#select() method.

A balloon can be closed in the following ways:

  • Automatically, if a user taps on the map.

  • Automatically, if a user taps on another Marker.

You can use one of the built-in balloon views that provide an easy way to display it, like SimpleMarkerBalloon that is used to display a default balloon. A balloon object is an instance of MarkerBalloon that has to implement the ViewAdapter interface.

Default Balloons

By default every marker when selected will display a default balloon which is an instance of BaseMarkerBalloon filled with the coordinates of the marker. BaseMarkerBalloon is a view model of the marker balloon view. To add a property to the model, you need to use this function:

_

BaseMarkerBalloon markerBalloon = new BaseMarkerBalloon();
markerBalloon.addProperty("key", "value");
val markerBalloon = BaseMarkerBalloon()
markerBalloon.addProperty("key", "value")

Model can be used to inflate balloon view.

Property Marker#canShowBalloon by default is set to true. By changing it to false the marker can still be selected but no balloon will appear. Property Marker#selected determines if the marker is selected at all. By default is false.

There is only one defined common model property key, which can be used in BaseBalloonViewAdapter to inflate the balloon, however more property keys can be added.

/**
 * text property key, one of the most used properties for balloon.
 */
public static final String KEY_TEXT = "text";

To display a balloon model we need to create and set a balloon view adapter:

/**
 * The adapter of balloon view. An implement interface to inflate a balloon adapter.
 */
public interface BalloonViewAdapter<T extends MarkerBalloon, E extends MapPoint> {

    /**
     * A callback which is called when inflating model.
     *
     * @param container - A container where a marker or balloon item will be inflated.
     * @param marker - A marker which has a balloon.
     * @param markerBalloon - A view model of a marker balloon.
     */
    <M extends T> View onCreateView(ViewGroup container, E marker, M markerBalloon);

    /**
     * @param view  The root view of inflating a layout.
     * @param marker The value which is used to fill a layout.
     * @param markerBalloon The view model of the marker balloon.
     */
    <M extends T> void onBindView(View view, E marker, M markerBalloon);

    /**
     * A view of the marker balloon.
     * @return It can be null when the balloon is not inflated.
     */
    @Nonnull
    View getBalloonView();

    /**
     * Gets the balloon offset from the marker.
     */
    @NonNull
    Point getBalloonOffset(E marker);
}

There are a few implementations provided of the balloon view adapter. These implementations cover the commons cases for balloons.

Simple balloons

 

image
Figure 1. Simple balloon

 

To create a simple balloon (a simple balloon is a balloon with one text line):

  1. Create a model for the marker balloon with the text properties: new SimpleMarkerBalloon("Welcome to TomTom").

  2. Create a balloon view adapter: TextBalloonViewAdapter that supports a one text line balloon view model.

  3. Set an adapter.

  4. Use all of the following steps:

_

tomtomMap.getMarkerSettings().setMarkerBalloonViewAdapter(new TextBalloonViewAdapter());
SimpleMarkerBalloon balloon = new SimpleMarkerBalloon("Welcome to TomTom");
MarkerBuilder markerBuilder = new MarkerBuilder(position)
        .markerBalloon(balloon);

Marker m = tomtomMap.addMarker(markerBuilder);
tomtomMap.markerSettings.markerBalloonViewAdapter = TextBalloonViewAdapter()
val balloon = SimpleMarkerBalloon(SIMPLE_BALLOON_TEXT)
val markerBuilder = MarkerBuilder(position)
        .markerBalloon(balloon)

val marker = tomtomMap.addMarker(markerBuilder)

 

If any adapter is not set by the user, TextBalloonViewAdapter is set by default. Because of that, points 2-4 are optional.

Custom balloons

Despite that you can use the default balloon, as the SDK allows you to create fully customizable ones. Balloon is nothing more than an Android layout implementation. A custom layout can be built in the way that you like either from the Android Studio Builder or programmatically.

image

To create a custom layout balloon:

  • Create a model for the marker balloon. BaseMarkerBalloon doesn’t have properties by default. Properties can be added by the addProperties(key, value) method.

  • Use SingleLayoutBalloonViewAdapter and provide the layout in the constructor.

  • Set an adapter.

  • Use all of the following steps:

_

tomtomMap.getMarkerSettings().setMarkerBalloonViewAdapter(new SingleLayoutBalloonViewAdapter(R.layout.custom_balloon_layout));
MarkerBuilder markerBuilder = new MarkerBuilder(position)
        .markerBalloon(new BaseMarkerBalloon());
Marker m = tomtomMap.addMarker(markerBuilder);
tomtomMap.markerSettings.markerBalloonViewAdapter = SingleLayoutBalloonViewAdapter(layoutRes)
val markerBuilder = MarkerBuilder(position)
        .markerBalloon(BaseMarkerBalloon())

val marker = tomtomMap.addMarker(markerBuilder)

 

To manage the custom ballon view model override method of SingleLayoutBalloonViewAdapter:

/**
 * @param view  The root view of inflating a layout.
 * @param marker The value which is used to fill a layout.
 * @param markerBalloon The view model of the marker balloon.
 */
<M extends T> void onBindView(View view, E marker, M markerBalloon);

or create your own class which extends BalloonViewAdapter and overrides all abstract methods.

Shapes

Allow your users to draw shapes like circles, polygons, and polylines on your map to mark different areas on the map.

Sample use case: You are developing an app for a delivery company and need to illustrate ranges of the transportation area around different cities. What you need to do is render circles around cities with radiuses indicating zones of deliveries. The details on the example implementation of shapes rendering follows.

The TomtomMap supports several shape overlays which can be easily created by using corresponding overlay builders. These are:

  • PolygonBuilder

  • PolylineBuilder

  • CircleBuilder

Shape overlays are immutable. That is, once they have been created their shape cannot be changed. Visibility and color can be changed. If you want to change a shape, you must remove the existing shape and replace it with a new one. It is the responsibility of the framework user to take care of performance and the number of shapes in use. You should use as few shapes as possible, and hide or dispose of the ones that are not being displayed.

To create shape overlays:

_

Polygon polygon = PolygonBuilder.create()
        .coordinates(coordinates)
        .color(color)
        .build();

tomtomMap.getOverlaySettings().addOverlay(polygon);
val polygon = PolygonBuilder.create()
        .coordinates(coordinates)
        .color(color)
        .build()

tomtomMap.overlaySettings.addOverlay(polygon)

 

_

Polyline polyline = PolylineBuilder.create()
        .coordinates(coordinates)
        .color(color)
        .build();

tomtomMap.getOverlaySettings().addOverlay(polyline);
val polyline = PolylineBuilder.create()
        .coordinates(coordinates)
        .color(color)
        .build()

tomtomMap.overlaySettings.addOverlay(polyline)

 

_

Circle circle = CircleBuilder.create()
        .fill(true)
        .radius(radiusM)
        .position(position)
        .color(color)
        .build();

tomtomMap.getOverlaySettings().addOverlay(circle);
val circle = CircleBuilder.create()
        .fill(true)
        .radius(CIRCLE_RADIUS_IN_METERS)
        .position(position)
        .color(color)
        .build()

tomtomMap.overlaySettings.addOverlay(circle)

 

To register click events:

_

tomtomMap.addOnCircleClickListener(onCircleClickListener);
tomtomMap.addOnPolygonClickListener(onPolygonClickListener);
tomtomMap.addOnPolylineClickListener(onPolylineClickListener);
tomtomMap.addOnCircleClickListener { infoTextView.displayAsToast(getString(R.string.toast_circle_clicked)) }
tomtomMap.addOnPolygonClickListener { infoTextView.displayAsToast(getString(R.string.toast_polygon_clicked)) }
tomtomMap.addOnPolylineClickListener { infoTextView.displayAsToast(getString(R.string.toast_polyline_clicked)) }

 

To unregister click events:

_

tomtomMap.removeOnCircleClickListeners();
tomtomMap.removeOnPolygonClickListeners();
tomtomMap.removeOnPolylineClickListeners();
tomtomMap.removeOnCircleClickListeners()
tomtomMap.removeOnPolygonClickListeners()
tomtomMap.removeOnPolylineClickListeners()

 

image

Polygon overlay

image

Polyline overlay

image

Circle overlay

Route display

You can display a route on the map and customize its origin and destination icons. It is also possible to specify the fill color, outline color, and width of the route.

Sample use case: When you add the route, you would like to highlight the starting and the destination points. Also, you would like to plan several routes simultaneously with different origin and destination points and use different icons.

Prerequisites:

The TomtomMap tomtomMap object was created and configured. Route coordinates are prepared.

Origin and destination icons customization

If you need to customize start and destination icons, you should create icons through the Icon class.

The icon can be created in following ways:

  • with a constructor:

    Icon startIcon = new Icon(name, drawable);
  • with the Icon.Factory.fromDrawable method:

    Icon startIcon = Icon.Factory.fromDrawable(name, drawable);

    where name is a String object and drawable is a Drawable object.

  • with the Icon.Factory.fromResources method:

    Icon endIcon = Icon.Factory.fromResources(context, iconId);

    where context is your Context object and iconId is an icon resource identifier.

When icons are created, you can add them to the route using the startIcon and endIcon methods of the RouteBuilder class,

Route customization

You can create a route with custom style properties like fill color, outline color, and width. First, you need to create the RouteStyle object:

_

RouteStyleBuilder.create()
        .withWidth(2.0)
        .withFillColor(Color.BLACK)
        .withOutlineColor(Color.RED)
        .build();
RouteStyleBuilder.create()
        .withWidth(ROUTE_WIDTH)
        .withFillColor(Color.BLACK)
        .withOutlineColor(Color.RED)
        .build()

 

Next, you need to pass routeBuilder to the addRoute method of tomtomMap:

_

RouteBuilder routeBuilder = new RouteBuilder(route.getCoordinates())
        .endIcon(endIcon)
        .startIcon(startIcon)
        .style(routeStyle);
final Route mapRoute = tomtomMap.addRoute(routeBuilder);
val routeBuilder = RouteBuilder(route.coordinates)
        .style(RouteStyle.DEFAULT_ROUTE_STYLE)
        .startIcon(createIcon(R.drawable.ic_map_route_origin))
        .endIcon(createIcon(R.drawable.ic_map_route_destination))
        .tag(routeIdx.toString())
tomtomMap.addRoute(routeBuilder)

 

If you don’t call startIcon and endIcon there will be no icons on route. You can specify only a start icon by calling only startIcon or only an end icon by calling only endIcon.

If you don’t call style then the default style will be applied.

You can use different images and styles for different routes.

Clear map

To clear a map, delete all polylines, polygons, markers, and routes and use the clear method.

/**
 * Clear from map all annotation, like markers, polyline, polygon's, routes or chevrons.
 */
void clear();