0

I'm developing an iOS project in Xcode using the Here SDK. I'm using the Premium Edition (v3.17). When calculating a route using NMACoreRouter, I found that the duration typically is over estimated. It depends a bit on the country how much.

Examples (compared to Google Maps estimations):

  • In Mexico a route with mostly highway, is overestimated by 25% compared to Google Maps.
  • In Germany, a route with mostly highway, is overestimated by 5% compared to Google Maps
  • In US, a route with mostly highway, is overestimated by 10% compared to Google Maps.

Please note that Google Maps is taking traffic into account, while I'm not taking traffic into account with the HERE SDK, so actual differences will be even higher.

How can I decrease/lower route duration estimation in HERE Maps SDK?

Things I've tried:

  • The routingMode of NMACoreRouter has a property speedProfile which can be set to NMASpeedProfile.fast, however this only works for truck routing and results in a crash when using this value for car routing. So, not an option for my app.

  • The dynamicPenalty property of NMACoreRouter: With this, basically you set a custom speedLimit for an array of NMARoadElement. I created this extension for that:

     extension NMACoreRouter {
    
         func adjustDurationCalculationFor(roadElements: [NMARoadElement], factor: Float) {
             self.dynamicPenalty = nil
             let penalties = NMADynamicPenalty()
             for roadElement in roadElements {
                 if roadElement.speedLimit > 0 {
                     penalties.addPenalty(for: roadElement, drivingDirection: .both, speed: UInt(roadElement.speedLimit*3.6*factor))
                 }
             }
             self.dynamicPenalty = penalties
         }
     }
    

This presents a difficulty though: For the speedLimit adjustments to have effect, the dynamicPenalty needs to be set before the route is calculated. So, you need to know the roadElements for which you want adjust the speedLimit, before the route has been calculated. I found two solutions for that:

  1. All NMARoadElements in the boundingbox of the route (in my app I know key points along the route before calculating it, and can use those to get boundingBox)

      let roadElements = self.mapView.roadElements(inArea: boundingBoxContainingTheRouteKeyPoints)
      self.coreRouter.adjustDurationCalculationFor(roadElements: roadElements, factor: 0.75)
    

This doesn't appear to work though. I get the same duration with or without penalties set. On top of that, disadvantage: It takes very long to set dynamicPenalty for that many roadElements (about 20-30 seconds on an iPhone 12 Pro for a boundingBox of about 50km by 100km).

  1. Calculate the route first without dynamicPenalty. From the NMARoute resulting from the calculation, the NMARoadElements in the route can be derived. Call adjustDurationCalculationFor for those elements and then recalculate the route.

I have not tried this, but I imagine it has the same problem that it doesn't work like nr 1 where duration reported is same with or without speed limits adjusted. Should it work, then this might be a better option than 1 as the number of NMARoadElements is a lot smaller so setting 'dynamicPenalty' will be a lot faster too. This presents a disadvantages though: - route calculations need to be done twice, also during navigation when user deviates from route and routes need to be recalculated.

So now, my question is, is there a better way to decrease/lower route duration estimation? The API documentation for dynamicPenalty mentions

...you can use this class to set an area penalty to indicate that the travel speed in an area is 50% slower than the legal speed limit.

How would one go about doing that?

Or is there another way entirely that I have not found? Are there some kind of configurable fallback values perhaps that are used when speed limit of a NMARoadElement is not known?

guido
  • 2,792
  • 1
  • 21
  • 40
  • I can confirm route tta does not consider speed limit dynamic penalty. Dynamic penalties are used in route calculations though. i.e. When you decrease road elements speed limit on the fastest route and create new one, it will likely be created via different road elements. Since tta is calculated based on the speed limit stored on routing server, I would not suggest or recommend any workarounds you listed. Could you please share a route whose tta significantly differs from real tta or tta's from other SDKs? So we can start internal investigation. Thanks! – dashchak Apr 28 '21 at 17:23
  • Sure. Start: -100.40750,20.61359 End: -99.28089,19.39520. Google Maps: 2h26min with traffic. HERE SDK 2h56min without traffic, fast routing mode, no avoidances. Google: https://cutt.ly/Gbo5sJZ Here: https://cutt.ly/Sbo6mq0 – guido Apr 28 '21 at 18:07
  • Sidenote... my app is for motorcycle riders, who are typically faster then cars. Some riders are faster than others obviously. It would be very nice if several NMASpeedProfiles would be available for the car routing as well. E.g. NMASpeedProfile.verySlow, .slow, .normal, .fast, .veryFast. Or make it a factor. – guido Apr 28 '21 at 18:16

0 Answers0