Plan efficient routes for EV fleets

Electric vehicles (EVs) present unique logistical challenges when planning delivery routes and service tours. Compared to traditional combustion-engine vehicles, EVs have limited range and require more frequent recharging stops, which can significantly impact tour efficiency and operational costs. Without proper planning, these constraints can lead to incomplete routes, missed deliveries, or excessive downtime due to unnecessary charging stops.

The HERE Tour Planning API addresses these challenges by automatically calculating optimal recharge stops as part of the tour optimization process. The API supports two distinct methods for planning EV routes: a distance-based approach that uses simple range calculations, and a consumption-based approach that leverages detailed vehicle power consumption profiles sourced from the HERE EV Profiles API that provide more accurate and efficient planning.

By integrating EV-specific constraints into your tour planning, you can maximize vehicle range utilization, minimize charging downtime, and ensure reliable operations for your electric fleet while maintaining cost efficiency.

📘

Note

recharges is an ALPHA feature, which means it is new or experimental and under active development. Alpha features are provided for testing and feedback purposes. They may change significantly or might not become generally available.

For more information, see Explore experimental features.

⚠️

Important

Consider the following limitations for creating EV tours with the recharges feature:

  • Long-distance tours: Insufficient charging infrastructure along extended routes might prevent optimal solutions.
  • Speed factor: Battery consumption is independent of speedFactor adjustments. Avoid using speedFactor with the recharges feature.

Understand the EV charging methods

The HERE Tour Planning API provides two approaches for managing EV charging during tour planning:

The following sections explain the differences between each method and provide practical examples helping you choose the method that is most suited to your specific business needs.

📘

Note

Include premiumFeatures=ev in the query string for both synchronous and asynchronous requests when using the consumption-based EV tour planning (based on evProfileId) or when you want to enable EV charging stations from HERE data in the distance-based approach. The following snippets show how to use the premiumFeatures parameter:

https://tourplanning.hereapi.com/v3/problems?premiumFeatures=ev
https://tourplanning.hereapi.com/v3/problems?apiKey=${api_key}&premiumFeatures=ev

Consumption-based charging

The consumption-based method uses detailed vehicle energy consumption profiles to calculate precise energy usage throughout the tour. This approach requires an evProfileId obtained from the HERE EV Profiles API, which contains vehicle-specific efficiency data including battery capacity, consumption rates, and charging characteristics.

This method provides significant advantages: the API can access HERE's database of public charging stations in addition to any private stations you define, enabling more flexible, and efficient tour planning. You can also specify initial charge levels for individual vehicles and control minimum and maximum charge thresholds.

For a practical example, see Example: Consumption-based EV tour planning.

📘

Note

The evProfileId-based EV tour planning feature requires additional licensing. Contact your HERE sales representative for access and more information.

Understand consumption-based EV charging configuration

To configure consumption-based charging, use the evProfileId parameter together with the accompanying minCharge, maxCharge, and initialCharges parameters. You must also enable the recharges experimental feature in the problem configuration.

For more information, see API Reference.

The evProfileId parameter references a vehicle energy profile obtained through the HERE EV Profiles API. This profile contains detailed consumption characteristics specific to your electric vehicle model and enables access to public charging stations available in HERE data for the corresponding vehicle.

📘

Note

The evProfileId value corresponds directly to the profileId returned by the HERE EV Profiles API when querying vehicle variants. For more information, see Obtain variants by make and model.

The following example shows the basic structure for consumption-based EV configuration:

{
  "configuration": {
    "experimentalFeatures": ["recharges"] // Mandatory experimentalFeatures flag
  },
  "fleet": {
    "types": [
      {
        "id": "EV_van",
        "profile": "EV_delivery_car",
        "charging": {
          "evProfileId": "84",
          "minCharge": 20,
          "maxCharge": 80,
          "initialCharges": [
            {
              "vehicleId": "EV_van_1",
              "charge": 80 // Initial battery charge
            }
          ]
        }
      }
    ]
  },
  "plan": {
    "shared": {
      "chargingStations": [ // Defining custom charging stations is optional with evProfileId
        {
          "id": "recharge-1",
          "location": {
            "lat": 52.63330707177772,
            "lng": 13.466836363077164
          },
          "vehicleTypeToDuration": {
            "EV_van": 1800
          }
        }
      ]
    }
  }
}

In this configuration:

  • The evProfileId value "84" references a specific EV model profile from the HERE EV Profiles API.
    ⚠️

    Important

    The evProfileId must reference a valid profile from the HERE EV Profiles API. Do not use arbitrary or random IDs. If your vehicle model is not available in the EV Profiles API, use the distance-based method with maxDistance instead.

  • The minCharge value of 20 (percent) sets the minimum battery level threshold before the vehicle must recharge.
  • The maxCharge value of 80 (percent) sets the target charge level to preserve battery health.
  • The optional setupDuration value specifies charging setup time in seconds, such as the time needed to park the vehicle, connect the charging cable, and start the charging session. For example, 300 represents five minutes.
  • The initialCharges array specifies the starting battery level for individual vehicles in the fleet.
  • The optional chargingStations array defines custom/private charging locations with their geographic coordinates and the charging duration required for each vehicle type you want to charge at each station. You can specify up to 20 custom charging stations.
📘

Note

  • When using evProfileId, defining custom charging stations is optional. In the consumption-based mode, the API automatically provides information on public charging stations available for vehicles matching the selected profile from the HERE database, improving tour efficiency.

  • You can disable the use of public charging stations from HERE content through the optional usePublicStations: false option. The usePublicStations option is set to true by default. See the following snippet for an example:

    "charging": {
      "evProfileId": "84",
      "minCharge": 10,
      "maxCharge": 80,
      "setupDuration": 300,
      "usePublicStations": false, // The use of public stations is disabled
        "initialCharges": [
          {
            "vehicleId": "EV_van",
            "charge": 15
          }
        ]
    }    

    For more information, see the API Reference.

Distance-based charging

Distance-based charging provides an alternative to consumption-based planning and is best suited for scenarios where detailed consumption data is unavailable. In this method, you specify the maximum distance a vehicle can travel on a full charge through the maxDistance parameter in the charging object.

When using the distance-based approach, you must explicitly define all available charging stations in your problem specification.

For a practical example, see Example: Distance-based EV tour planning.

📘

Note

If you specify a valid evProfileId, the HERE charging stations become available in the distance-based mode. However, the consumption-based method is recommended in that case as it is more efficient.

Tip: Determine vehicle range limits for distance-based charging

Electric vehicles have a limited range on a single charge before requiring recharge. This limit is critical, especially in logistics and delivery scenarios. You might already have insights into your vehicles' range capabilities. If not, consider using the HERE Routing API v8 to calculate battery consumption based on variables such as vehicle speed, route length, and terrain elevation. For more information, see EV routing in HERE Routing API v8.

When querying the HERE Routing API v8 for EV battery consumption data, the response includes a summary object. This object contains values that you can use to establish range limits for your EV fleet.

Consider the following sample summary object:

"summary" : {
  "consumption" : 43.343000000000004,
  "length" : 145350,
  "baseDuration" : 6337,
  "duration" : 6337
}

The length value represents the distance traveled on a route. You can use this value to set the maxDistance limit for your EV fleet. For example, if a route covers 145.35 km, you can set maxDistance to approximately 80% of this value (about 145 km) to account for real-world conditions and battery degradation.

Configure the distance-based EV charging

To configure distance-based charging, add the charging object to your vehicle type specification with the maxDistance parameter. You must also enable the recharges experimental feature in the problem configuration. Additionally, you must explicitly define all available charging stations in the chargingStations array, as the API does not have access to public charging infrastructure in distance-based mode.

The following example shows the basic structure for distance-based EV configuration:

{
  "configuration": {
    "experimentalFeatures": ["recharges"] // Mandatory experimentalFeatures flag
  },
  "fleet": {
    "types": [
      {
        "id": "EV_van",
        "profile": "EV_delivery_car",
        "charging": {
          "maxDistance": 145000
        }
      }
    ]
  },
  "plan": {
    "shared": {
      "chargingStations": [
        {
          "id": "recharge-1",
          "location": {
            "lat": 52.63330707177772,
            "lng": 13.466836363077164
          },
          "vehicleTypeToDuration": {
            "EV_van": 1800
          }
        }
      ]
    }
  }
}

In this configuration:

  • The maxDistance value of 145000 meters (145 km) represents approximately 80% of a vehicle's full range, providing a safety margin.
    📘

    Tip

    Set maxDistance to approximately 80% of your vehicle's rated range to account for real-world conditions such as traffic, weather, and battery degradation.

  • Each charging station must be explicitly defined in the chargingStations array with its location and charging duration per vehicle type.
  • The vehicleTypeToDuration object specifies how long each vehicle type needs to fully recharge at that station (in seconds).

Comparing distance-based and consumption-based EV tour planning

The following examples demonstrate both distance-based and consumption-based EV tour planning approaches using the same delivery scenario. Both examples feature the same 10 delivery jobs and private charging station locations around Berlin, Germany. The only difference between the two approaches lies in the charging mode configuration: the distance-based example uses maxDistance for simple range calculations, while the consumption-based example uses evProfileId for precise energy consumption modeling.

The following figure shows the job and charging station locations as used in the sample scenario:

Job and private charging station locations in the sample EV scenario

Example: Distance-based EV tour planning

This example demonstrates distance-based EV tour planning for a delivery route covering 10 locations around Berlin, Germany. A single electric van must complete all deliveries while managing its limited range through strategic charging stops.

Problem configuration

The problem consists of a single EV van with a maximum range of 145 km between charges, 10 delivery jobs, and 8 available charging stations. The van must depart from and return to the same depot location.

{ "configuration": {
    "experimentalFeatures": [
      "recharges"
    ]
  },
  "fleet": {
    "types": [
      {
        "profile": "EV_delivery_car",
        "amount": 1,
        "capacity": [
          50
        ],
        "costs": {
          "time": 0.002,
          "distance": 0.001,
          "fixed": 10
        },
        "id": "EV_van",
        "charging": {
          "maxDistance": 145000
        },
        "shifts": [
          {
            "start": {
              "location": {
                "lat": 52.531,
                "lng": 13.38461
              },
              "time": "2024-06-24T08:00:00+02:00"
            },
            "end": {
              "location": {
                "lat": 52.531,
                "lng": 13.38461
              },
              "time": "2024-06-24T20:00:00+02:00"
            }
          }
        ]
      }
    ],
    "profiles": [
      {
        "name": "EV_delivery_car",
        "type": "car"
      }
    ]
  },
  "plan": {
    "jobs": [
      {
        "id": "Job_1_Tegel",
        "tasks": {
          "deliveries": [
            {
              "places": [
                {
                  "location": {
                    "lat": 52.58827738438644,
                    "lng": 13.296353816986086
                  },
                  "duration": 300
                }
              ],
              "demand": [
                1
              ]
            }
          ]
        }
      },
      {
        "id": "Job_2_Bernau_bei_Berlin",
        "tasks": {
          "deliveries": [
            {
              "places": [
                {
                  "location": {
                    "lat": 52.67281,
                    "lng": 13.57398
                  },
                  "duration": 300
                }
              ],
              "demand": [
                1
              ]
            }
          ]
        }
      },
      {
        "id": "Job_3_Oranienburg",
        "tasks": {
          "deliveries": [
            {
              "places": [
                {
                  "location": {
                    "lat": 52.74401,
                    "lng": 13.22915
                  },
                  "duration": 300
                }
              ],
              "demand": [
                1
              ]
            }
          ]
        }
      },
      {
        "id": "Job_4_Nauen",
        "tasks": {
          "deliveries": [
            {
              "places": [
                {
                  "location": {
                    "lat": 52.6163222431449,
                    "lng": 12.880417630076408
                  },
                  "duration": 300
                }
              ],
              "demand": [
                1
              ]
            }
          ]
        }
      },
      {
        "id": "Job_5_Brandenburg_an_der_Havel",
        "tasks": {
          "deliveries": [
            {
              "places": [
                {
                  "location": {
                    "lat": 52.403784877078074,
                    "lng": 12.551846355199816
                  },
                  "duration": 300
                }
              ],
              "demand": [
                1
              ]
            }
          ]
        }
      },
      {
        "id": "Job_6_Potsdam",
        "tasks": {
          "deliveries": [
            {
              "places": [
                {
                  "location": {
                    "lat": 52.397707342242505,
                    "lng": 13.04578176699579
                  },
                  "duration": 300
                }
              ],
              "demand": [
                1
              ]
            }
          ]
        }
      },
      {
        "id": "Job_7_Zossen",
        "tasks": {
          "deliveries": [
            {
              "places": [
                {
                  "location": {
                    "lat": 52.21758094651013,
                    "lng": 13.466836363077164
                  },
                  "duration": 300
                }
              ],
              "demand": [
                1
              ]
            }
          ]
        }
      },
      {
        "id": "Job_8_Storkow",
        "tasks": {
          "deliveries": [
            {
              "places": [
                {
                  "location": {
                    "lat": 52.25225447270385,
                    "lng": 13.926220647990707
                  },
                  "duration": 300
                }
              ],
              "demand": [
                1
              ]
            }
          ]
        }
      },
      {
        "id": "Job_9_Kopenick",
        "tasks": {
          "deliveries": [
            {
              "places": [
                {
                  "location": {
                    "lat": 52.441362207320445,
                    "lng": 13.581075668334963
                  },
                  "duration": 300
                }
              ],
              "demand": [
                1
              ]
            }
          ]
        }
      },
      {
        "id": "Job_10_Muncheberg",
        "tasks": {
          "deliveries": [
            {
              "places": [
                {
                  "location": {
                    "lat": 52.50679458191002,
                    "lng": 14.122798070311548
                  },
                  "duration": 300
                }
              ],
              "demand": [
                1
              ]
            }
          ]
        }
      }              
    ],
    "shared": {
      "chargingStations": [
        {
          "id": "recharge-1",
          "location": {
            "lat": 52.63330707177772,
            "lng": 13.466836363077164
          },
           "vehicleTypeToDuration": {
            "EV_van": 1800
          }
        },
        {
          "id": "recharge-2",
          "location": {
            "lat": 52.54295506642127,
            "lng": 13.349863886833193
          },
           "vehicleTypeToDuration": {
            "EV_van": 1800
          }
        },
        {
          "id": "recharge-3",
          "location": {
            "lat": 52.289267605204834,
            "lng": 13.435935974121096
          },
           "vehicleTypeToDuration": {
            "EV_van": 1800
          }
        },
        {
          "id": "recharge-4",
          "location": {
            "lat": 52.353550434388495,
            "lng": 13.131365776062013
          },
           "vehicleTypeToDuration": {
            "EV_van": 1800
          }
        },
        {
          "id": "recharge-5",
          "location": {
            "lat": 52.56205587025991,
            "lng": 13.062915802001955
          },
           "vehicleTypeToDuration": {
            "EV_van": 1800
          }
        },
        {
          "id": "recharge-6",
          "location": {
            "lat": 52.356653188253595,
            "lng": 13.57588291168213
          },
           "vehicleTypeToDuration": {
            "EV_van": 1800
          }
        },
        {
          "id": "recharge-7",
          "location": {
            "lat": 52.55682385745202,
            "lng": 13.633003612048924
          },
           "vehicleTypeToDuration": {
            "EV_van": 1800
          }
        },
        {
          "id": "recharge-8",
          "location": {
            "lat": 52.56901193099222,
            "lng": 13.881736546754839
          },
           "vehicleTypeToDuration": {
            "EV_van": 1800
          }
        }
      ]
    }
  }
}

Key aspects of this problem configuration:

  • The vehicle has a maxDistance of 145000 meters (145 km), representing 80% of its full range for safety.
  • Eight charging stations are strategically distributed across the service area.
  • Each charging station requires 30 minutes (1800 seconds) for a full recharge.
  • The 12-hour shift window (08:00 to 20:00) provides ample time for charging stops.

Solution analysis

The API generates an optimized route that includes three charging stops, enabling the vehicle to complete all 10 deliveries within the shift constraints while respecting the range limitation.

The following figure shows the tour visualization, highlighting the charging stops:

Sample distance-based EV tour

See the following JSON snippet for the full solution:

{
    "statistic": {
        "cost": 526.539,
        "distance": 448071,
        "duration": 34234,
        "times": {
            "driving": 25834,
            "serving": 3000,
            "waiting": 0,
            "stopping": 0,
            "break": 0,
            "intraStop": 0,
            "charging": 5400
        },
        "intraStopDistance": 0
    },
    "tours": [
        {
            "vehicleId": "EV_van_1",
            "typeId": "EV_van",
            "stops": [
                {
                    "time": {
                        "arrival": "2024-06-24T06:00:00Z",
                        "departure": "2024-06-24T06:00:00Z"
                    },
                    "load": [
                        10
                    ],
                    "activities": [
                        {
                            "jobId": "departure",
                            "type": "departure",
                            "location": {
                                "lat": 52.531,
                                "lng": 13.38461
                            },
                            "time": {
                                "start": "2024-06-24T06:00:00Z",
                                "end": "2024-06-24T06:00:00Z",
                                "arrival": "2024-06-24T06:00:00Z"
                            }
                        }
                    ],
                    "location": {
                        "lat": 52.531,
                        "lng": 13.38461
                    },
                    "distance": 0
                },
                {
                    "time": {
                        "arrival": "2024-06-24T06:31:16Z",
                        "departure": "2024-06-24T06:36:16Z"
                    },
                    "load": [
                        9
                    ],
                    "activities": [
                        {
                            "jobId": "Job_2_Bernau_bei_Berlin",
                            "type": "delivery",
                            "location": {
                                "lat": 52.67281,
                                "lng": 13.57398
                            },
                            "time": {
                                "start": "2024-06-24T06:31:16Z",
                                "end": "2024-06-24T06:36:16Z",
                                "arrival": "2024-06-24T06:31:16Z"
                            }
                        }
                    ],
                    "location": {
                        "lat": 52.67281,
                        "lng": 13.57398
                    },
                    "distance": 32833
                },
                {
                    "time": {
                        "arrival": "2024-06-24T07:02:39Z",
                        "departure": "2024-06-24T07:07:39Z"
                    },
                    "load": [
                        8
                    ],
                    "activities": [
                        {
                            "jobId": "Job_3_Oranienburg",
                            "type": "delivery",
                            "location": {
                                "lat": 52.74401,
                                "lng": 13.22915
                            },
                            "time": {
                                "start": "2024-06-24T07:02:39Z",
                                "end": "2024-06-24T07:07:39Z",
                                "arrival": "2024-06-24T07:02:39Z"
                            }
                        }
                    ],
                    "location": {
                        "lat": 52.74401,
                        "lng": 13.22915
                    },
                    "distance": 74362
                },
                {
                    "time": {
                        "arrival": "2024-06-24T07:26:09Z",
                        "departure": "2024-06-24T07:31:09Z"
                    },
                    "load": [
                        7
                    ],
                    "activities": [
                        {
                            "jobId": "Job_1_Tegel",
                            "type": "delivery",
                            "location": {
                                "lat": 52.58827738438644,
                                "lng": 13.296353816986086
                            },
                            "time": {
                                "start": "2024-06-24T07:26:09Z",
                                "end": "2024-06-24T07:31:09Z",
                                "arrival": "2024-06-24T07:26:09Z"
                            }
                        }
                    ],
                    "location": {
                        "lat": 52.58827738438644,
                        "lng": 13.296353816986086
                    },
                    "distance": 97215
                },
                {
                    "time": {
                        "arrival": "2024-06-24T08:07:08Z",
                        "departure": "2024-06-24T08:37:08Z"
                    },
                    "load": [
                        7
                    ],
                    "activities": [
                        {
                            "jobId": "recharge-5",
                            "type": "recharge",
                            "location": {
                                "lat": 52.56205587025991,
                                "lng": 13.062915802001957
                            },
                            "time": {
                                "start": "2024-06-24T08:07:08Z",
                                "end": "2024-06-24T08:37:08Z",
                                "arrival": "2024-06-24T08:07:08Z"
                            }
                        }
                    ],
                    "location": {
                        "lat": 52.56205587025991,
                        "lng": 13.062915802001957
                    },
                    "distance": 120320
                },
                {
                    "time": {
                        "arrival": "2024-06-24T09:01:50Z",
                        "departure": "2024-06-24T09:06:50Z"
                    },
                    "load": [
                        6
                    ],
                    "activities": [
                        {
                            "jobId": "Job_4_Nauen",
                            "type": "delivery",
                            "location": {
                                "lat": 52.6163222431449,
                                "lng": 12.880417630076408
                            },
                            "time": {
                                "start": "2024-06-24T09:01:50Z",
                                "end": "2024-06-24T09:06:50Z",
                                "arrival": "2024-06-24T09:01:50Z"
                            }
                        }
                    ],
                    "location": {
                        "lat": 52.6163222431449,
                        "lng": 12.880417630076408
                    },
                    "distance": 141390
                },
                {
                    "time": {
                        "arrival": "2024-06-24T09:48:15Z",
                        "departure": "2024-06-24T09:53:15Z"
                    },
                    "load": [
                        5
                    ],
                    "activities": [
                        {
                            "jobId": "Job_5_Brandenburg_an_der_Havel",
                            "type": "delivery",
                            "location": {
                                "lat": 52.403784877078074,
                                "lng": 12.551846355199816
                            },
                            "time": {
                                "start": "2024-06-24T09:48:15Z",
                                "end": "2024-06-24T09:53:15Z",
                                "arrival": "2024-06-24T09:48:15Z"
                            }
                        }
                    ],
                    "location": {
                        "lat": 52.403784877078074,
                        "lng": 12.551846355199816
                    },
                    "distance": 180762
                },
                {
                    "time": {
                        "arrival": "2024-06-24T10:36:11Z",
                        "departure": "2024-06-24T10:41:11Z"
                    },
                    "load": [
                        4
                    ],
                    "activities": [
                        {
                            "jobId": "Job_6_Potsdam",
                            "type": "delivery",
                            "location": {
                                "lat": 52.397707342242505,
                                "lng": 13.04578176699579
                            },
                            "time": {
                                "start": "2024-06-24T10:36:11Z",
                                "end": "2024-06-24T10:41:11Z",
                                "arrival": "2024-06-24T10:36:11Z"
                            }
                        }
                    ],
                    "location": {
                        "lat": 52.397707342242505,
                        "lng": 13.04578176699579
                    },
                    "distance": 236672
                },
                {
                    "time": {
                        "arrival": "2024-06-24T10:53:42Z",
                        "departure": "2024-06-24T11:23:42Z"
                    },
                    "load": [
                        4
                    ],
                    "activities": [
                        {
                            "jobId": "recharge-4",
                            "type": "recharge",
                            "location": {
                                "lat": 52.353550434388495,
                                "lng": 13.131365776062012
                            },
                            "time": {
                                "start": "2024-06-24T10:53:42Z",
                                "end": "2024-06-24T11:23:42Z",
                                "arrival": "2024-06-24T10:53:42Z"
                            }
                        }
                    ],
                    "location": {
                        "lat": 52.353550434388495,
                        "lng": 13.131365776062012
                    },
                    "distance": 247993
                },
                {
                    "time": {
                        "arrival": "2024-06-24T11:54:52Z",
                        "departure": "2024-06-24T11:59:52Z"
                    },
                    "load": [
                        3
                    ],
                    "activities": [
                        {
                            "jobId": "Job_7_Zossen",
                            "type": "delivery",
                            "location": {
                                "lat": 52.21758094651013,
                                "lng": 13.466836363077164
                            },
                            "time": {
                                "start": "2024-06-24T11:54:52Z",
                                "end": "2024-06-24T11:59:52Z",
                                "arrival": "2024-06-24T11:54:52Z"
                            }
                        }
                    ],
                    "location": {
                        "lat": 52.21758094651013,
                        "lng": 13.466836363077164
                    },
                    "distance": 287963
                },
                {
                    "time": {
                        "arrival": "2024-06-24T12:21:27Z",
                        "departure": "2024-06-24T12:51:27Z"
                    },
                    "load": [
                        3
                    ],
                    "activities": [
                        {
                            "jobId": "recharge-6",
                            "type": "recharge",
                            "location": {
                                "lat": 52.356653188253595,
                                "lng": 13.57588291168213
                            },
                            "time": {
                                "start": "2024-06-24T12:21:27Z",
                                "end": "2024-06-24T12:51:27Z",
                                "arrival": "2024-06-24T12:21:27Z"
                            }
                        }
                    ],
                    "location": {
                        "lat": 52.356653188253595,
                        "lng": 13.57588291168213
                    },
                    "distance": 312512
                },
                {
                    "time": {
                        "arrival": "2024-06-24T13:22:26Z",
                        "departure": "2024-06-24T13:27:26Z"
                    },
                    "load": [
                        2
                    ],
                    "activities": [
                        {
                            "jobId": "Job_8_Storkow",
                            "type": "delivery",
                            "location": {
                                "lat": 52.25225447270385,
                                "lng": 13.926220647990707
                            },
                            "time": {
                                "start": "2024-06-24T13:22:26Z",
                                "end": "2024-06-24T13:27:26Z",
                                "arrival": "2024-06-24T13:22:26Z"
                            }
                        }
                    ],
                    "location": {
                        "lat": 52.25225447270385,
                        "lng": 13.926220647990707
                    },
                    "distance": 348124
                },
                {
                    "time": {
                        "arrival": "2024-06-24T14:03:30Z",
                        "departure": "2024-06-24T14:08:30Z"
                    },
                    "load": [
                        1
                    ],
                    "activities": [
                        {
                            "jobId": "Job_10_Muncheberg",
                            "type": "delivery",
                            "location": {
                                "lat": 52.50679458191002,
                                "lng": 14.122798070311548
                            },
                            "time": {
                                "start": "2024-06-24T14:03:30Z",
                                "end": "2024-06-24T14:08:30Z",
                                "arrival": "2024-06-24T14:03:30Z"
                            }
                        }
                    ],
                    "location": {
                        "lat": 52.50679458191002,
                        "lng": 14.122798070311548
                    },
                    "distance": 385231
                },
                {
                    "time": {
                        "arrival": "2024-06-24T14:51:55Z",
                        "departure": "2024-06-24T14:56:55Z"
                    },
                    "load": [
                        0
                    ],
                    "activities": [
                        {
                            "jobId": "Job_9_Kopenick",
                            "type": "delivery",
                            "location": {
                                "lat": 52.441362207320445,
                                "lng": 13.581075668334964
                            },
                            "time": {
                                "start": "2024-06-24T14:51:55Z",
                                "end": "2024-06-24T14:56:55Z",
                                "arrival": "2024-06-24T14:51:55Z"
                            }
                        }
                    ],
                    "location": {
                        "lat": 52.441362207320445,
                        "lng": 13.581075668334964
                    },
                    "distance": 428033
                },
                {
                    "time": {
                        "arrival": "2024-06-24T15:30:34Z",
                        "departure": "2024-06-24T15:30:34Z"
                    },
                    "load": [
                        0
                    ],
                    "activities": [
                        {
                            "jobId": "arrival",
                            "type": "arrival",
                            "location": {
                                "lat": 52.531,
                                "lng": 13.38461
                            },
                            "time": {
                                "start": "2024-06-24T15:30:34Z",
                                "end": "2024-06-24T15:30:34Z",
                                "arrival": "2024-06-24T15:30:34Z"
                            }
                        }
                    ],
                    "location": {
                        "lat": 52.531,
                        "lng": 13.38461
                    },
                    "distance": 448071
                }
            ],
            "statistic": {
                "cost": 526.539,
                "distance": 448071,
                "duration": 34234,
                "times": {
                    "driving": 25834,
                    "serving": 3000,
                    "waiting": 0,
                    "stopping": 0,
                    "break": 0,
                    "intraStop": 0,
                    "charging": 5400
                },
                "intraStopDistance": 0
            },
            "shiftIndex": 0
        }
    ]
}

The solution demonstrates effective range management:

  • Total distance: 448 km across all deliveries and charging stops
  • Charging time: 90 minutes total (three 30-minute charging sessions)
  • Driving time: Approximately 7.2 hours
  • First recharge occurs at recharge-5 after 120 km, before reaching the 145 km limit
  • Second recharge occurs at recharge-4 after an additional 127 km
  • Third recharge occurs at recharge-6 after an additional 64 km, ensuring sufficient range to complete remaining deliveries and return to the depot

The optimization algorithm places recharge stops to prevent range violations while minimizing total charging time. Each recharge activity includes a 30-minute duration, as specified in the vehicleTypeToDuration configuration.

Example: Consumption-based EV tour planning

This example demonstrates consumption-based EV tour planning using the same 10 delivery locations, but with a detailed energy consumption profile. This approach enables more efficient route planning through precise energy calculations and access to public charging infrastructure.

Prerequisites

To use consumption-based EV charging, you must first obtain the evProfileId from the HERE EV Profiles API. The profileId parameter in the EV Profiles API returns a unique identifier that represents the specific make, model, and model variant of your vehicle. This profileId value is then used as the evProfileId in the Tour Planning API to ensure accurate energy consumption calculations tailored to your exact vehicle specifications.

For more information, see Get EV metadata with the HERE EV Profiles API

Problem configuration

The problem uses the same delivery locations as the distance-based example, but replaces maxDistance with evProfileId, adds charge threshold parameters, and an initial charge value for the vehicle ID to complete the resulting tour.

{ "configuration": {
    "experimentalFeatures": [
      "recharges"
    ]
  },
  "fleet": {
    "types": [
      {
        "profile": "EV_delivery_car",
        "amount": 1,
        "capacity": [
          50
        ],
        "costs": {
          "time": 0.002,
          "distance": 0.001,
          "fixed": 10
        },
        "id": "EV_van",
        "charging": {
          "evProfileId": "84",
          "minCharge": 20,
          "maxCharge": 80,
          "initialCharges": [
            {
              "vehicleId": "EV_van_1",
              "charge": 80
            }
          ]
        },
        "shifts": [
          {
            "start": {
              "location": {
                "lat": 52.531,
                "lng": 13.38461
              },
              "time": "2024-06-24T08:00:00+02:00"
            },
            "end": {
              "location": {
                "lat": 52.531,
                "lng": 13.38461
              },
              "time": "2024-06-24T20:00:00+02:00"
            }
          }
        ]
      }
    ],
    "profiles": [
      {
        "name": "EV_delivery_car",
        "type": "car"
      }
    ]
  },
  "plan": {
    "jobs": [
      {
        "id": "Job_1_Tegel",
        "tasks": {
          "deliveries": [
            {
              "places": [
                {
                  "location": {
                    "lat": 52.58827738438644,
                    "lng": 13.296353816986086
                  },
                  "duration": 300
                }
              ],
              "demand": [
                1
              ]
            }
          ]
        }
      },
      {
        "id": "Job_2_Bernau_bei_Berlin",
        "tasks": {
          "deliveries": [
            {
              "places": [
                {
                  "location": {
                    "lat": 52.67281,
                    "lng": 13.57398
                  },
                  "duration": 300
                }
              ],
              "demand": [
                1
              ]
            }
          ]
        }
      },
      {
        "id": "Job_3_Oranienburg",
        "tasks": {
          "deliveries": [
            {
              "places": [
                {
                  "location": {
                    "lat": 52.74401,
                    "lng": 13.22915
                  },
                  "duration": 300
                }
              ],
              "demand": [
                1
              ]
            }
          ]
        }
      },
      {
        "id": "Job_4_Nauen",
        "tasks": {
          "deliveries": [
            {
              "places": [
                {
                  "location": {
                    "lat": 52.6163222431449,
                    "lng": 12.880417630076408
                  },
                  "duration": 300
                }
              ],
              "demand": [
                1
              ]
            }
          ]
        }
      },
      {
        "id": "Job_5_Brandenburg_an_der_Havel",
        "tasks": {
          "deliveries": [
            {
              "places": [
                {
                  "location": {
                    "lat": 52.403784877078074,
                    "lng": 12.551846355199816
                  },
                  "duration": 300
                }
              ],
              "demand": [
                1
              ]
            }
          ]
        }
      },
      {
        "id": "Job_6_Potsdam",
        "tasks": {
          "deliveries": [
            {
              "places": [
                {
                  "location": {
                    "lat": 52.397707342242505,
                    "lng": 13.04578176699579
                  },
                  "duration": 300
                }
              ],
              "demand": [
                1
              ]
            }
          ]
        }
      },
      {
        "id": "Job_7_Zossen",
        "tasks": {
          "deliveries": [
            {
              "places": [
                {
                  "location": {
                    "lat": 52.21758094651013,
                    "lng": 13.466836363077164
                  },
                  "duration": 300
                }
              ],
              "demand": [
                1
              ]
            }
          ]
        }
      },
      {
        "id": "Job_8_Storkow",
        "tasks": {
          "deliveries": [
            {
              "places": [
                {
                  "location": {
                    "lat": 52.25225447270385,
                    "lng": 13.926220647990707
                  },
                  "duration": 300
                }
              ],
              "demand": [
                1
              ]
            }
          ]
        }
      },
      {
        "id": "Job_9_Kopenick",
        "tasks": {
          "deliveries": [
            {
              "places": [
                {
                  "location": {
                    "lat": 52.441362207320445,
                    "lng": 13.581075668334963
                  },
                  "duration": 300
                }
              ],
              "demand": [
                1
              ]
            }
          ]
        }
      },
      {
        "id": "Job_10_Muncheberg",
        "tasks": {
          "deliveries": [
            {
              "places": [
                {
                  "location": {
                    "lat": 52.50679458191002,
                    "lng": 14.122798070311548
                  },
                  "duration": 300
                }
              ],
              "demand": [
                1
              ]
            }
          ]
        }
      }              
    ],
    "shared": {
      "chargingStations": [
        {
          "id": "recharge-1",
          "location": {
            "lat": 52.63330707177772,
            "lng": 13.466836363077164
          },
           "vehicleTypeToDuration": {
            "EV_van": 1800
          }
        },
        {
          "id": "recharge-2",
          "location": {
            "lat": 52.54295506642127,
            "lng": 13.349863886833193
          },
           "vehicleTypeToDuration": {
            "EV_van": 1800
          }
        },
        {
          "id": "recharge-3",
          "location": {
            "lat": 52.289267605204834,
            "lng": 13.435935974121096
          },
           "vehicleTypeToDuration": {
            "EV_van": 1800
          }
        },
        {
          "id": "recharge-4",
          "location": {
            "lat": 52.353550434388495,
            "lng": 13.131365776062013
          },
           "vehicleTypeToDuration": {
            "EV_van": 1800
          }
        },
        {
          "id": "recharge-5",
          "location": {
            "lat": 52.56205587025991,
            "lng": 13.062915802001955
          },
           "vehicleTypeToDuration": {
            "EV_van": 1800
          }
        },
        {
          "id": "recharge-6",
          "location": {
            "lat": 52.356653188253595,
            "lng": 13.57588291168213
          },
           "vehicleTypeToDuration": {
            "EV_van": 1800
          }
        },
        {
          "id": "recharge-7",
          "location": {
            "lat": 52.55682385745202,
            "lng": 13.633003612048924
          },
           "vehicleTypeToDuration": {
            "EV_van": 1800
          }
        },
        {
          "id": "recharge-8",
          "location": {
            "lat": 52.56901193099222,
            "lng": 13.881736546754839
          },
           "vehicleTypeToDuration": {
            "EV_van": 1800
          }
        }
      ]
    }
  }
}

Key differences from the distance-based configuration include the following:

  • The use of evProfileId: "84" instead of maxDistance provides precise energy calculations and gives access to public charging stations in addition to the eight defined private stations
  • The addition of minCharge: 20 and maxCharge: 80 optimize battery health and charging time
  • The initialCharges value specifies that the vehicle starts at 80% battery capacity

Solution analysis

The consumption-based approach produces a more efficient solution with reduced total distance, fewer charging stops, and optimized charging durations.

Sample solution with a consumption-based EV tour

See the following JSON snippet for the full solution:

{
  "statistic": {
    "cost": 476.34000000000003,
    "distance": 400630,
    "duration": 32855,
    "times": {
      "driving": 23325,
      "serving": 3000,
      "waiting": 0,
      "stopping": 0,
      "break": 0,
      "intraStop": 0,
      "charging": 6530
    },
    "intraStopDistance": 0,
    "consumption": 71.1756
  },
  "tours": [
    {
      "vehicleId": "EV_van_1",
      "typeId": "EV_van",
      "stops": [
        {
          "time": {
            "arrival": "2024-06-24T06:00:00Z",
            "departure": "2024-06-24T06:00:00Z"
          },
          "load": [
            10
          ],
          "activities": [
            {
              "jobId": "departure",
              "type": "departure",
              "location": {
                "lat": 52.531,
                "lng": 13.38461
              },
              "time": {
                "start": "2024-06-24T06:00:00Z",
                "end": "2024-06-24T06:00:00Z",
                "arrival": "2024-06-24T06:00:00Z"
              }
            }
          ],
          "location": {
            "lat": 52.531,
            "lng": 13.38461
          },
          "distance": 0
        },
        {
          "time": {
            "arrival": "2024-06-24T06:19:05Z",
            "departure": "2024-06-24T06:24:05Z"
          },
          "load": [
            9
          ],
          "activities": [
            {
              "jobId": "Job_1_Tegel",
              "type": "delivery",
              "location": {
                "lat": 52.58827738438644,
                "lng": 13.296353816986086
              },
              "time": {
                "start": "2024-06-24T06:19:05Z",
                "end": "2024-06-24T06:24:05Z",
                "arrival": "2024-06-24T06:19:05Z"
              }
            }
          ],
          "location": {
            "lat": 52.58827738438644,
            "lng": 13.296353816986086
          },
          "distance": 10669,
          "consumption": 1.0802
        },
        {
          "time": {
            "arrival": "2024-06-24T06:49:40Z",
            "departure": "2024-06-24T07:19:40Z"
          },
          "load": [
            9
          ],
          "activities": [
            {
              "jobId": "recharge-1",
              "type": "recharge",
              "location": {
                "lat": 52.63330707177772,
                "lng": 13.466836363077164
              },
              "time": {
                "start": "2024-06-24T06:49:40Z",
                "end": "2024-06-24T07:19:40Z",
                "arrival": "2024-06-24T06:49:40Z"
              }
            }
          ],
          "location": {
            "lat": 52.63330707177772,
            "lng": 13.466836363077164
          },
          "distance": 26769,
          "consumption": 2.7183
        },
        {
          "time": {
            "arrival": "2024-06-24T07:34:05Z",
            "departure": "2024-06-24T07:39:05Z"
          },
          "load": [
            8
          ],
          "activities": [
            {
              "jobId": "Job_2_Bernau_bei_Berlin",
              "type": "delivery",
              "location": {
                "lat": 52.67281,
                "lng": 13.57398
              },
              "time": {
                "start": "2024-06-24T07:34:05Z",
                "end": "2024-06-24T07:39:05Z",
                "arrival": "2024-06-24T07:34:05Z"
              }
            }
          ],
          "location": {
            "lat": 52.67281,
            "lng": 13.57398
          },
          "distance": 37342,
          "consumption": 3.8078
        },
        {
          "time": {
            "arrival": "2024-06-24T08:05:28Z",
            "departure": "2024-06-24T08:10:28Z"
          },
          "load": [
            7
          ],
          "activities": [
            {
              "jobId": "Job_3_Oranienburg",
              "type": "delivery",
              "location": {
                "lat": 52.74401,
                "lng": 13.22915
              },
              "time": {
                "start": "2024-06-24T08:05:28Z",
                "end": "2024-06-24T08:10:28Z",
                "arrival": "2024-06-24T08:05:28Z"
              }
            }
          ],
          "location": {
            "lat": 52.74401,
            "lng": 13.22915
          },
          "distance": 78871,
          "consumption": 14.5212
        },
        {
          "time": {
            "arrival": "2024-06-24T08:37:02Z",
            "departure": "2024-06-24T08:42:02Z"
          },
          "load": [
            6
          ],
          "activities": [
            {
              "jobId": "Job_4_Nauen",
              "type": "delivery",
              "location": {
                "lat": 52.6163222431449,
                "lng": 12.880417630076408
              },
              "time": {
                "start": "2024-06-24T08:37:02Z",
                "end": "2024-06-24T08:42:02Z",
                "arrival": "2024-06-24T08:37:02Z"
              }
            }
          ],
          "location": {
            "lat": 52.6163222431449,
            "lng": 12.880417630076408
          },
          "distance": 117169,
          "consumption": 23.5261
        },
        {
          "time": {
            "arrival": "2024-06-24T08:47:44Z",
            "departure": "2024-06-24T09:27:09Z"
          },
          "load": [
            6
          ],
          "activities": [
            {
              "jobId": "here:pds:place:evcp0-MTdmMmIzYTAtMDQzZi0xMWVlLWFhZDUtNDIwMTBhYTQwZmMw",
              "type": "recharge",
              "jobTag": "charging-station-here:pds:place:evcp0-MTdmMmIzYTAtMDQzZi0xMWVlLWFhZDUtNDIwMTBhYTQwZmMw",
              "location": {
                "lat": 52.60758,
                "lng": 12.86844
              },
              "time": {
                "start": "2024-06-24T08:47:44Z",
                "end": "2024-06-24T09:27:09Z",
                "arrival": "2024-06-24T08:47:44Z"
              }
            }
          ],
          "location": {
            "lat": 52.60758,
            "lng": 12.86844
          },
          "distance": 119821,
          "consumption": 23.861
        },
        {
          "time": {
            "arrival": "2024-06-24T10:05:29Z",
            "departure": "2024-06-24T10:10:29Z"
          },
          "load": [
            5
          ],
          "activities": [
            {
              "jobId": "Job_5_Brandenburg_an_der_Havel",
              "type": "delivery",
              "location": {
                "lat": 52.403784877078074,
                "lng": 12.551846355199816
              },
              "time": {
                "start": "2024-06-24T10:05:29Z",
                "end": "2024-06-24T10:10:29Z",
                "arrival": "2024-06-24T10:05:29Z"
              }
            }
          ],
          "location": {
            "lat": 52.403784877078074,
            "lng": 12.551846355199816
          },
          "distance": 157631,
          "consumption": 29.5391
        },
        {
          "time": {
            "arrival": "2024-06-24T10:53:25Z",
            "departure": "2024-06-24T10:58:25Z"
          },
          "load": [
            4
          ],
          "activities": [
            {
              "jobId": "Job_6_Potsdam",
              "type": "delivery",
              "location": {
                "lat": 52.397707342242505,
                "lng": 13.04578176699579
              },
              "time": {
                "start": "2024-06-24T10:53:25Z",
                "end": "2024-06-24T10:58:25Z",
                "arrival": "2024-06-24T10:53:25Z"
              }
            }
          ],
          "location": {
            "lat": 52.397707342242505,
            "lng": 13.04578176699579
          },
          "distance": 213541,
          "consumption": 41.7807
        },
        {
          "time": {
            "arrival": "2024-06-24T11:03:41Z",
            "departure": "2024-06-24T11:43:06Z"
          },
          "load": [
            4
          ],
          "activities": [
            {
              "jobId": "here:pds:place:276u33615qnyw-aGVyZS1ldjplY29tb3ZlbWVudDoxNjE2NjgyNjU2",
              "type": "recharge",
              "jobTag": "charging-station-here:pds:place:276u33615qnyw-aGVyZS1ldjplY29tb3ZlbWVudDoxNjE2NjgyNjU2",
              "location": {
                "lat": 52.40186,
                "lng": 13.06028
              },
              "time": {
                "start": "2024-06-24T11:03:41Z",
                "end": "2024-06-24T11:43:06Z",
                "arrival": "2024-06-24T11:03:41Z"
              }
            }
          ],
          "location": {
            "lat": 52.40186,
            "lng": 13.06028
          },
          "distance": 215408,
          "consumption": 41.9242
        },
        {
          "time": {
            "arrival": "2024-06-24T12:18:34Z",
            "departure": "2024-06-24T12:23:34Z"
          },
          "load": [
            3
          ],
          "activities": [
            {
              "jobId": "Job_7_Zossen",
              "type": "delivery",
              "location": {
                "lat": 52.21758094651013,
                "lng": 13.466836363077164
              },
              "time": {
                "start": "2024-06-24T12:18:34Z",
                "end": "2024-06-24T12:23:34Z",
                "arrival": "2024-06-24T12:18:34Z"
              }
            }
          ],
          "location": {
            "lat": 52.21758094651013,
            "lng": 13.466836363077164
          },
          "distance": 262920,
          "consumption": 52.0252
        },
        {
          "time": {
            "arrival": "2024-06-24T12:59:27Z",
            "departure": "2024-06-24T13:04:27Z"
          },
          "load": [
            2
          ],
          "activities": [
            {
              "jobId": "Job_8_Storkow",
              "type": "delivery",
              "location": {
                "lat": 52.25225447270385,
                "lng": 13.926220647990707
              },
              "time": {
                "start": "2024-06-24T12:59:27Z",
                "end": "2024-06-24T13:04:27Z",
                "arrival": "2024-06-24T12:59:27Z"
              }
            }
          ],
          "location": {
            "lat": 52.25225447270385,
            "lng": 13.926220647990707
          },
          "distance": 300683,
          "consumption": 57.5036
        },
        {
          "time": {
            "arrival": "2024-06-24T13:40:31Z",
            "departure": "2024-06-24T13:45:31Z"
          },
          "load": [
            1
          ],
          "activities": [
            {
              "jobId": "Job_10_Muncheberg",
              "type": "delivery",
              "location": {
                "lat": 52.50679458191002,
                "lng": 14.122798070311548
              },
              "time": {
                "start": "2024-06-24T13:40:31Z",
                "end": "2024-06-24T13:45:31Z",
                "arrival": "2024-06-24T13:40:31Z"
              }
            }
          ],
          "location": {
            "lat": 52.50679458191002,
            "lng": 14.122798070311548
          },
          "distance": 337790,
          "consumption": 63.4091
        },
        {
          "time": {
            "arrival": "2024-06-24T14:28:56Z",
            "departure": "2024-06-24T14:33:56Z"
          },
          "load": [
            0
          ],
          "activities": [
            {
              "jobId": "Job_9_Kopenick",
              "type": "delivery",
              "location": {
                "lat": 52.441362207320445,
                "lng": 13.581075668334964
              },
              "time": {
                "start": "2024-06-24T14:28:56Z",
                "end": "2024-06-24T14:33:56Z",
                "arrival": "2024-06-24T14:28:56Z"
              }
            }
          ],
          "location": {
            "lat": 52.441362207320445,
            "lng": 13.581075668334964
          },
          "distance": 380592,
          "consumption": 69.2981
        },
        {
          "time": {
            "arrival": "2024-06-24T15:07:35Z",
            "departure": "2024-06-24T15:07:35Z"
          },
          "load": [
            0
          ],
          "activities": [
            {
              "jobId": "arrival",
              "type": "arrival",
              "location": {
                "lat": 52.531,
                "lng": 13.38461
              },
              "time": {
                "start": "2024-06-24T15:07:35Z",
                "end": "2024-06-24T15:07:35Z",
                "arrival": "2024-06-24T15:07:35Z"
              }
            }
          ],
          "location": {
            "lat": 52.531,
            "lng": 13.38461
          },
          "distance": 400630,
          "consumption": 71.1756
        }
      ],
      "statistic": {
        "cost": 476.34000000000003,
        "distance": 400630,
        "duration": 32855,
        "times": {
          "driving": 23325,
          "serving": 3000,
          "waiting": 0,
          "stopping": 0,
          "break": 0,
          "intraStop": 0,
          "charging": 6530
        },
        "intraStopDistance": 0,
        "consumption": 71.1756
      },
      "shiftIndex": 0
    }
  ]
}

The consumption-based solution demonstrates the following improvements over the distance-based approach:

  • Total distance: 400 km (compared to 448 km with distance-based method, a 10.7% reduction)
  • Total cost: 476.34 (compared to 526.54 with distance-based method, a 9.5% reduction)
  • Total consumption: 71.18 kWh (cumulative energy used across the entire tour)
  • Charging pattern: Two public charging stations plus one private station
  • Consumption tracking: Each stop includes precise energy consumption data in kWh

The consumption parameter represents the cumulative kilowatt-hours (kWh) of energy consumed up to that point in the tour. For example:

  • First delivery (Job_1_Tegel): 1.08 kWh consumed
  • After first charge (recharge-1): 2.72 kWh consumed
  • After stop 5 (Job_4_Nauen): 23.53 kWh consumed
  • Final stop (arrival): 71.18 kWh consumed total

The consumption-based example uses three recharge stops, matching the distance-based approach but using different locations. Two of these stops occur at public charging stations identified by HERE IDs (starting with here:pds:place:). The API automatically discovers these stations.

Additionally, in this consumption-based scenario, the cumulative consumption field tracks total energy usage throughout the tour, enabling precise battery management. Each stop's consumption value allows drivers and fleet managers to monitor energy depletion and plan recharges strategically.

Conclusions

The consumption-based method enhances route efficiency by:

  • Providing precise energy calculations rather than relying on simplified distance estimates.
  • Considering factors such as terrain, traffic, vehicle speed, and load weight to enhance prediction accuracy.
  • Accessing charging infrastructure data through HERE's public station database for broader network access.
  • Optimizing charging duration based on the actual battery state and operational requirements.
  • Offering consumption information at each stop to support more detailed energy tracking.

Next steps

  • For more information about obtaining EV profile IDs, see Introduction to EV Profiles.
  • For an in-depth exploration of the HERE Tour Planning API methods, endpoints, and parameters, see the API Reference.

Did this page help you?