Calculating a reachable range
Introduction
The Reachable Range API calculates how far a vehicle can travel from a given location, based on constraints such as distance, time, fuel, or battery charge. It is commonly used in applications that support electric or combustion vehicles, delivery logistics, and travel-time-based decisions.
The result of a successful Reachable Range calculation is a Range
object that contains a polygon representing the reachable area under the selected constraints. You can render this polygon as an overlay on the map.
To learn how to display the range polygon on a map, see the Map overlays guide.
Project setup
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.routing:model:1.26.0")2implementation("com.tomtom.sdk.routing:range-calculator-online:1.26.0")3implementation("com.tomtom.sdk.location:model:1.26.0")4implementation("com.tomtom.sdk.vehicle:model:1.26.0")5implementation("com.tomtom.quantity:quantity:1.26.0")
The OnlineRangeCalculatorFactory
can be used to create a RangeCalculator
, which is the entry point for performing reachable range requests.
val rangeCalculator = OnlineRangeCalculatorFactory.create(applicationContext, "YOUR_TOMTOM_API_KEY")
Setting up range options
A range calculation generates a polygon representing the area a vehicle can reach, given a specific budget. It uses criteria similar to those in route planning, defined through the RangeCalculationOptions
class. You can use named parameters in Kotlin to set only the properties you need. The required parameters are the origin point and a budget
.
The origin point is passed as an ItineraryPoint
, which can include both coordinates and a heading.
Although the API is designed to support multiple budgets of the same type in a single request, currently only one budget is allowed. It can be one of the following types:
Distance
— calculates the range based on a specified travel distance.Time
— calculates the range based on a specified travel time (isochrone).Fuel
— calculates the range for a combustion vehicle based on the specified fuel volume. To use this option, specify avehicle
that has acombustion engine
in the range calculation options.Energy
— calculates the range for an electric vehicle based on the specified battery charge. To use this option, specify avehicle
that has anelectric engine
in the range calculation options.
There are several optional parameters you can use to tailor the range calculation criteria to your use case. For a detailed description of the available parameters, see the Range API documentation.
You can specify a cost model
that determines the range achievable using routes of that type. In particular, fast
routes tend to incur greater energy consumption, resulting in a shorter range compared to short
or efficient
routes.
1val amsterdam = ItineraryPoint(Place(GeoPoint(52.377956, 4.897070)))23val vehicle = Vehicle.Car(4 electricEngine = ElectricEngine(5 consumption = ElectricVehicleConsumption(6 speedConsumption = mapOf(7 Speed.kilometersPerHour(50) to ElectricConsumption.kilowattHoursPer100Kilometers(6.5),8 Speed.kilometersPerHour(100) to ElectricConsumption.kilowattHoursPer100Kilometers(7),9 ),10 ),11 ),12)1314val rangeCalculationOptions = RangeCalculationOptions(15 origin = amsterdam,16 budgets = setOf(Budget.Energy(Energy.kilowattHours(5.0))),17 vehicle = vehicle,18)
Requesting ranges
When you have a RangeCalculationOptions
object, pass it to the calculateRange
method. You can perform the range calculation either synchronously or asynchronously using a callback
.
Synchronous calls
A synchronous call is blocking, meaning the calculateRange method blocks the program flow until it returns either a result or an error. The response is wrapped in a Result<Range, RoutingFailure>
object. Use the Result.isSuccess()
method to check if the call succeeded. If it returns true, you can retrieve the resulting Range
object using Result.value()
. If an error occurred, Result.isFailure()
returns true instead. More details about the error can be found using Result.failure()
.
1val amsterdam = ItineraryPoint(Place(GeoPoint(52.377956, 4.897070)))23val vehicle = Vehicle.Car(4 electricEngine = ElectricEngine(5 consumption = ElectricVehicleConsumption(6 speedConsumption = mapOf(7 Speed.kilometersPerHour(50) to ElectricConsumption.kilowattHoursPer100Kilometers(6.5),8 Speed.kilometersPerHour(100) to ElectricConsumption.kilowattHoursPer100Kilometers(7),9 ),10 ),11 ),12)1314val rangeCalculationOptions = RangeCalculationOptions(15 origin = amsterdam,16 budgets = setOf(Budget.Energy(Energy.kilowattHours(0.1))),17 vehicle = vehicle,18)1920when (val calculateRangeResult = rangeCalculator.calculateRange(rangeCalculationOptions)) {21 is Result.Success -> calculateRangeResult.value()22 is Result.Failure -> calculateRangeResult.failure()23}
Asynchronous calls
The asynchronous version of the call requires passing a Callback<Range, RoutingError>
as a parameter. If the call is successful, the callback’s onSuccess(result: Range)
method is triggered with the routing result. If a failure occurs, it is handled by the callback’s onFailure(error: RoutingFailure)
method.
1val amsterdam = ItineraryPoint(Place(GeoPoint(52.377956, 4.897070)))23val rangeCalculationOptions = RangeCalculationOptions(4 origin = amsterdam,5 budgets = setOf(Budget.Distance(Distance.meters(1000))),6)78rangeCalculator.calculateRange(9 rangeCalculationOptions,10 object : Callback<Range, RoutingFailure> {11 override fun onSuccess(result: Range) {12 // YOUR CODE GOES HERE13 }1415 override fun onFailure(failure: RoutingFailure) {16 // YOUR CODE GOES HERE17 }18 },19)
Setting the cost model and vehicle
Refer to the Route planning guide to learn more about configuring the cost model, including route type, avoid options, and vehicle settings.
Calculation failures
A RoutingFailure
is returned if an error occurs during the range calculation. For more information, refer to the Route planning failures documentation.
Next steps
Since you have learned how to calculate a range, here are recommendations for the next steps: