itinero / routing

The routing core of itinero.
Apache License 2.0
222 stars 71 forks source link

RouteNotFound Exception (following issue #69) #76

Closed alecava58 closed 7 years ago

alecava58 commented 7 years ago

Hi Ben, I've done a lot of tests regarding this exception and I saw something strange that I'm trying to explain:

DB1 = I have a simple db: italy with standard vehicles and standard profiles. Not contracted. DB2 = a db with italy + a custom lua vehicle (called hazmat) with standard profiles + custom profile called (fastest_nogo). Not contracted.

With the snippet I wrote on the issue #69 I'm try to calculate the route using the following 2 methods: M1: var ret = router.Calculate(profile, rp.ToArray()); M2: ret = router.Calculate(profile, (float)lat[0], (float)lon[0], (float)lat[1], (float)lon[1]);

ResolveConnected always ok

DB1 + car + shortest = M1:fail M2:fail DB1 + car + fastest = M1:ok M2:fail DB1 + car + classifications = M1:ok M2:fail DB2 + car + shortest = M1:fail M2:fail DB2 + car + classifications = M1:ok M2:fail DB2 + hazmat + shortest = M1:fail M2:fail DB2 + hazmat + classifications = M1:ok M2:fail DB2 + hazmat + fastest_nogo = M1:ok M2:fail

xivk commented 7 years ago

DB1 + car + shortest = M1:fail M2:fail DB1 + car + fastest = M1:ok M2:fail DB1 + car + classifications = M1:ok M2:fail DB2 + car + shortest = M1:fail M2:fail DB2 + car + classifications = M1:ok M2:fail DB2 + hazmat + shortest = M1:fail M2:fail DB2 + hazmat + classifications = M1:ok M2:fail DB2 + hazmat + fastest_nogo = M1:ok M2:fail

For M2 it's normal, they can fail because they are not checked for connectivity. For M1, it's possible the connectivity radius is not high enough. What happens when you increase this?

Another option is to resolve with 'shortest', use a radius in 'meters' for example 2000m and then route using another profile. The only condition is that there are no differences in access restrictions between the two profiles.

xivk commented 7 years ago

Oh, and the last option, another bug somewhere that I don't see at the moment.

alecava58 commented 7 years ago

If I use: r = router.TryResolveConnected(localVehicle.Profile("shortest"), (float)lat[i], (float)lon[i], radiusInMeter: 2000, maxSearchDistance: 1000);

all the above M1 test is ok

xivk commented 7 years ago

Ok, then that's the issue.

I would recommend, to keep performance, using this as a backup and only when a route without connectivity checks fails.

This should also work with the classifications profile but the issue there is that the metric is not 'time' or 'distance' but something completely arbitrary to represent the priorities of the roads mixed with travel times. Check the profile for what I mean:

https://github.com/itinero/routing/blob/develop/src/Itinero/Osm/Vehicles/car.lua#L226

alecava58 commented 7 years ago

Ben, I can use for TryResolveConneted a fixed profile (shortest or fastest). Don't worry about using classification for TryResolveConnected.

I don't understand the performace problem about using large area for TryResolveConnect. Do you mean that first af all I have to try with smaller (or default) parameters and after, if it fails, try again with larger parameters?

xivk commented 7 years ago

Yes, but if you don't have big performance constraints you might as well just check a larger area first and keep your code simple. From fast to 'slow':

  1. TryResolve()
  2. TryResolveConnected(200)
  3. TryResolveConnected(2000)
  4. ....

For example in a webservice with a large # of expected requests I would first try 1 then move to 3 when the routing fails.

xivk commented 7 years ago

Fixed connectivity check to always use distance, whatever profile is used.