Skip to content

Range Finder

In this guide you will learn how to render all possible paths on the map, to see the furthest you can travel in any direction, in a specific amount of time which you specify in seconds.

Setup

First, get an API key token, see the Getting Started guide.
Download the Maps & Navigation SDK for Android archive file

Download the RangeFinder project archive file or clone the project with Git

See the Configure Android Example guide.

Run the example

In Android Studio, from the File menu, select Sync Project with Gradle Files

Range finder example Android screenshot

Range finder example Android screenshot

Range finder example Android screenshot

The center screenshot shows the possible transport modes to select from: car, lorry(truck), pedestrian, bicycle.
The screenshot on the right shows the possible range types to select from: fastest or shortest.

Range finder example Android screenshot

Range finder example Android screenshot

Range finder example Android screenshot

The left screenshot shows the maximum range, in green, for driving a car for 180 seconds in any direction from a location in London.
The center screenshot shows the maximum range, in pink, for driving a car for 360 seconds in any direction from a location in London.
The right screenshot shows the maximum range, in blue, for driving a car for 720 seconds in any direction from a location in London.
An android device should be connected via USB cable.
Press SHIFT+F10 to compile, install and run the example on the android device.

How it works

Android example screenshot

You can open the MainActivity.kt file to see how the range is rendered on the map based on the transportation mode and time input by the user.

 1private fun calculateRange(transportMode: ERouteTransportMode,
 2    routeType: ERouteType,
 3    ranges: ArrayList<Int>)
 4{
 5     SdkCall.execute {
 6         routingService.preferences.transportMode = transportMode
 7         routingService.preferences.routeType = routeType
 8         routingService.preferences.setRouteRanges(ranges, 100)
 9         routingService.calculateRoute(arrayListOf(Landmark("London", 51.5073204, -0.1276475)))
10     }
11}

The calculateRange() function first sets the user-selected transportMode, routeType and ranges in the routingService, then calculates all possible routes from a specified (latitude, longitude) position using calculateRoute().

 1override fun onCreate(savedInstanceState: Bundle?)
 2{
 3     super.onCreate(savedInstanceState)
 4     setContentView(R.layout.activity_main)
 5     rootView = findViewById(R.id.root_view)
 6     progressBar = findViewById(R.id.progressBar)
 7     gemSurfaceView = findViewById(R.id.gem_surface)
 8     transportModeSpinner = findViewById(R.id.transport_mode_spinner)
 9     rangeTypeSpinner = findViewById(R.id.range_type_spinner)
10     rangeValueEditText = findViewById(R.id.range_value_edit_text)
11     addButton = findViewById(R.id.add_button)
12     currentRangesScrollContainer = findViewById(R.id.current_ranges_scroll_container)
13     currentRangesContainer = findViewById(R.id.current_ranges_buttons_container)
14     rangeViewsContainer = findViewById(R.id.range_container)
15     setConstraints(resources.configuration.orientation)
16     SdkSettings.onMapDataReady = { isReady ->
17         if (isReady)
18         {
19             // Defines an action that should be done when
20             // the world map is ready (Updated/ loaded).
21             progressBar.visibility = View.GONE
22             rangeViewsContainer.visibility = View.VISIBLE
23
24             prepareViews()
25         }
26     }
27     SdkSettings.onApiTokenRejected = {
28         showDialog("TOKEN REJECTED")
29     }
30     if (!Util.isInternetConnected(this))
31     {
32         showDialog("You must be connected to internet!")
33     }
34}
The MainActivity overrides the onCreate function, which checks that internet access is available, and calls the prepareViews function which defines a button to trigger the route calculation and the rendering of the highlighted area on the map, showing the maximum range that can be traveled in any direction in the amount of time and travel mode specified by the user.
 1private fun prepareViews()
 2{
 3     val transportTypesList = mutableListOf(getString(R.string.car),
 4       getString(R.string.lorry), getString(R.string.pedestrian), getString(R.string.bicycle))
 5     val adapter = ArrayAdapter(this, R.layout.spinner_item, R.id.spinner_text, transportTypesList)
 6     transportModeSpinner.adapter = adapter
 7     transportModeSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener
 8     {
 9         override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long)
10         {
11             onTransportModeSelected(position)
12         }
13
14         override fun onNothingSelected(parent: AdapterView<*>?) = Unit
15     }
16     transportModeSpinner.setSelection(0)
17     addButton.setOnClickListener {
18         if (rangeValueEditText.text.isNotEmpty())
19         {
20             currentSelectedRanges.add(rangeValueEditText.text.toString().toInt())
21             SdkCall.execute { calculateRanges() }
22             rangeValueEditText.setText("")
23             hideKeyboard()
24         }
25         else
26         {
27             showDialog("Range value is empty!")
28         }
29     }
30}

The prepareViews function sets a listener for the button to call calculateRanges(), which calls the calculateRange() function shown above, to compute the routes, if the user enters a valid range value, in seconds.

 1private val routingService = RoutingService(
 2     onStarted = {
 3         progressBar.visibility = View.VISIBLE
 4         addButton.visibility = View.GONE
 5     },
 6     onCompleted = { routes, errorCode, _ ->
 7         progressBar.visibility = View.GONE
 8         addButton.visibility = View.VISIBLE
 9         when (errorCode)
10         {
11             GemError.NoError ->
12             {
13                 SdkCall.execute {
14                     gemSurfaceView.mapView?.presentRoutes(routes, displayBubble = true)
15                 }
16             }
17             GemError.Cancel ->
18             { // The routing action was cancelled.
19             }
20             else ->
21             {
22                 currentSelectedRanges.removeAt(currentSelectedRanges.size - 1)
23                 showDialog("Routing service error: ${GemError.getMessage(errorCode)}")
24             }
25         }
26     }
27)

The routingService() computes the routes and calls presentRoutes() to highlight the ranges on the map.

Android Examples

Maps SDK for Android Examples can be downloaded or cloned with Git