itinero / routing

The routing core of itinero.
Apache License 2.0
221 stars 70 forks source link

Small discrepancies between single / matrix routes, and between routes / weights #269

Open airbreather opened 5 years ago

airbreather commented 5 years ago

Same overall setup as in #267, just found some more discrepancies when running a larger calculation.

Output:

Loading router DB from disk... done after 57.140 seconds.

Loading contracted DB from disk... done after 124.672 seconds.

Starting calculation for car.shortest (contracted)... done after 3.720 seconds.
    Total distance (single weight): 2,414.147 miles
    Total distance (matrix weight): 2,414.142 miles
    Total distance (single route):  2,414.155 miles
    Total distance (matrix route):  2,414.155 miles
    Total time (single route):      4,370.132 minutes
    Total time (matrix route):      4,370.132 minutes

ConsoleApp0.csproj

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp2.2</TargetFramework>
    <ServerGarbageCollection>true</ServerGarbageCollection>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Reminiscence" Version="1.3.0-pre06" />
    <PackageReference Include="Itinero" Version="1.4.0" />
  </ItemGroup>

</Project>
using System;
using System.Diagnostics;
using System.IO;

using Itinero;
using Itinero.LocalGeo;
using Itinero.Osm.Vehicles;

static class Program
{
    const string RouterDbPath = @"C:\Projects\itinero\north-america-190602.routerdb";
    const string ContractedPath = @"C:\Projects\itinero\north-america-190602.minDistance.contracteddb";

    const float SrcLat = 42.329434f;
    const float SrcLon = -83.038549f;

    const float DstLat = 33.806898f;
    const float DstLon = -118.146133f;

    static void Main()
    {
        var minDistance = Vehicle.Car.Shortest();

        var routerDb = LoadRouterDb();
        var router = new Router(routerDb);

        AddContracted(routerDb);
        Run(router, minDistance);
    }

    static void Run(Router router, Itinero.Profiles.Profile profile)
    {
        Console.WriteLine();

        var src = new Coordinate(SrcLat, SrcLon);
        var dst = new Coordinate(DstLat, DstLon);

        var srcResolved = router.Resolve(profile, src, 100);
        var tgtResolved = router.Resolve(profile, dst, 100);

        Console.Write($"Starting calculation for {profile.FullName} ({(router.Db.HasContractedFor(profile) ? "" : "not ")}contracted)...");
        var sw = Stopwatch.StartNew();
        var res1 = router.TryCalculateWeight(profile, router.GetDefaultWeightHandler(profile), srcResolved, tgtResolved).Value;
        var res2 = router.TryCalculateWeight(profile, router.GetDefaultWeightHandler(profile), new[] { srcResolved }, new[] { tgtResolved }, null, null).Value[0][0];
        var res3 = router.TryCalculate(profile, new[] { srcResolved }, new[] { tgtResolved }).Value[0][0];
        var res4 = router.TryCalculate(profile, srcResolved, tgtResolved).Value;
        sw.Stop();

        Console.WriteLine($" done after {sw.ElapsedTicks / (double)Stopwatch.Frequency:N3} seconds.");
        // too noisy, and the route variants don't have any discrepancy, so skip them:
        ////Console.WriteLine($"    GeoJSON (single):               {res3.ToGeoJson(false, false, false)}");
        ////Console.WriteLine($"    GeoJSON (matrix):               {res4.ToGeoJson(false, false, false)}");
        Console.WriteLine($"    Total distance (single weight): {(res1 / 1609.344):N3} miles");
        Console.WriteLine($"    Total distance (matrix weight): {(res2 / 1609.344):N3} miles");
        Console.WriteLine($"    Total distance (single route):  {(res3.TotalDistance / 1609.344):N3} miles");
        Console.WriteLine($"    Total distance (matrix route):  {(res4.TotalDistance / 1609.344):N3} miles");
        Console.WriteLine($"    Total time (single route):      {(res3.TotalTime / 60.0):N3} minutes");
        Console.WriteLine($"    Total time (matrix route):      {(res4.TotalTime / 60.0):N3} minutes");
        Console.WriteLine();
    }

    static RouterDb LoadRouterDb()
    {
        Console.WriteLine();

        Console.Write("Loading router DB from disk...");
        using (var rdb = File.OpenRead(RouterDbPath))
        {
            var sw = Stopwatch.StartNew();
            RouterDb result = RouterDb.Deserialize(rdb);
            sw.Stop();
            Console.WriteLine($" done after {sw.ElapsedTicks / (double)Stopwatch.Frequency:N3} seconds.");
            Console.WriteLine();
            return result;
        }
    }

    static void AddContracted(RouterDb routerDb)
    {
        Console.WriteLine();
        Console.Write("Loading contracted DB from disk...");
        using (var cont = File.OpenRead(ContractedPath))
        {
            var sw = Stopwatch.StartNew();
            routerDb.DeserializeAndAddContracted(cont);
            sw.Stop();
            Console.WriteLine($" done after {sw.ElapsedTicks / (double)Stopwatch.Frequency:N3} seconds.");
            Console.WriteLine();
        }
    }
}