Example #1
0
        /// <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();
        }
Example #2
0
        /// <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();
        }