/// <summary> /// Optimizes the network by removing irrelevant vertex. /// </summary> public static void OptimizeNetwork(this RouterDb routerDb, float simplifyEpsilonInMeter = Constants.DEFAULT_SIMPL_E) { var router = new Router(routerDb); var factorFunctions = new List <Func <ushort, Factor> >(); foreach (var vehicle in routerDb.GetSupportedVehicles()) { foreach (var profile in vehicle.GetProfiles()) { factorFunctions.Add(router.GetDefaultGetFactor(profile)); } } var algorithm = new Itinero.Algorithms.Networks.NetworkOptimizer( routerDb.Network, routerDb.GetHasAnyRestriction(), (Itinero.Data.Network.Edges.EdgeData edgeData1, bool inverted1, Itinero.Data.Network.Edges.EdgeData edgeData2, bool inverted2, out Itinero.Data.Network.Edges.EdgeData mergedEdgeData, out bool mergedInverted) => { mergedEdgeData = new Itinero.Data.Network.Edges.EdgeData() { Distance = edgeData1.Distance + edgeData2.Distance, MetaId = edgeData2.MetaId, Profile = edgeData2.Profile }; mergedInverted = inverted2; if (edgeData1.MetaId != edgeData2.MetaId) { // different meta data, do not merge. return(false); } if (inverted1 != inverted2) { // directions are the same. foreach (var factorFunction in factorFunctions) { var edge1Factor = factorFunction(edgeData1.Profile); var edge2Factor = factorFunction(edgeData2.Profile); if (edge1Factor.Value != edge2Factor.Value) { return(false); } if (edge1Factor.Direction == 0) { if (edge2Factor.Direction == 1) { return(false); } else if (edgeData2.Distance == 2) { return(false); } } else if (edge1Factor.Direction == 1) { if (edge2Factor.Direction != 2) { return(false); } } else if (edge1Factor.Direction == 2) { if (edge2Factor.Direction != 1) { return(false); } } } } else { foreach (var factorFunction in factorFunctions) { var edge1Factor = factorFunction(edgeData1.Profile); var edge2Factor = factorFunction(edgeData2.Profile); if (edge1Factor.Value != edge2Factor.Value) { return(false); } if (edge1Factor.Direction != edge2Factor.Direction) { return(false); } } } return(true); }, simplifyEpsilonInMeter); algorithm.Run(); }
/// <summary> /// Optimizes the network by removing irrelevant vertex. /// </summary> public static void OptimizeNetwork(this RouterDb routerDb, float simplifyEpsilonInMeter, CancellationToken cancellationToken) { var router = new Router(routerDb); var factorFunctions = new List <Func <ushort, Factor> >(); foreach (var vehicle in routerDb.GetSupportedVehicles()) { foreach (var profile in vehicle.GetProfiles()) { factorFunctions.Add(router.GetDefaultGetFactor(profile)); } } var algorithm = new Itinero.Algorithms.Networks.NetworkOptimizer( routerDb.Network, routerDb.GetHasAnyRestriction(), (Itinero.Data.Network.Edges.EdgeData edgeData1, bool inverted1, Itinero.Data.Network.Edges.EdgeData edgeData2, bool inverted2, out Itinero.Data.Network.Edges.EdgeData mergedEdgeData, out bool mergedInverted) => { mergedEdgeData = new Itinero.Data.Network.Edges.EdgeData() { Distance = edgeData1.Distance + edgeData2.Distance, MetaId = edgeData2.MetaId, Profile = edgeData2.Profile }; mergedInverted = inverted2; if (edgeData1.MetaId != edgeData2.MetaId) { // different meta data, do not merge. return(false); } if (inverted1 != inverted2) { // directions are the different. foreach (var factorFunction in factorFunctions) { var edge1Factor = factorFunction(edgeData1.Profile); var edge2Factor = factorFunction(edgeData2.Profile); if (edge1Factor.Value != edge2Factor.Value) { return(false); } if (edge1Factor.Direction == 0) { if (edge2Factor.Direction == 1) { return(false); } else if (edge2Factor.Direction == 2) { return(false); } } else if (edge1Factor.Direction == 1) { if (edge2Factor.Direction != 2) { return(false); } } else if (edge1Factor.Direction == 2) { if (edge2Factor.Direction != 1) { return(false); } } } } else { foreach (var factorFunction in factorFunctions) { var edge1Factor = factorFunction(edgeData1.Profile); var edge2Factor = factorFunction(edgeData2.Profile); if (edge1Factor.Value != edge2Factor.Value) { return(false); } if (edge1Factor.Direction != edge2Factor.Direction) { return(false); } } } return(true); }, simplifyEpsilonInMeter); var edgeMetaDb = routerDb.EdgeData; var edgeMetaKeys = edgeMetaDb.Names; algorithm.CanMerge = (edgeId1, edgeId2) => { foreach (var key in edgeMetaKeys) { var edgeMeta = edgeMetaDb.Get(key); return(edgeMeta.Equal(edgeId1, edgeId2)); } return(true); }; algorithm.NewEdge = (oldEdgeId, newEdgeId) => { foreach (var key in edgeMetaKeys) { var edgeMeta = edgeMetaDb.Get(key); if (oldEdgeId >= edgeMeta.Count) { continue; } edgeMeta.Copy(newEdgeId, oldEdgeId); } }; algorithm.Run(cancellationToken); algorithm.CheckHasRunAndHasSucceeded(); }