Пример #1
0
        /// <summary>
        /// Calculates the edge path between this router point and the given router point.
        /// </summary>
        public static EdgePath <T> EdgePathTo <T>(this RouterPoint point, RouterDb db, WeightHandler <T> weightHandler, RouterPoint target)
            where T : struct
        {
            if (point.EdgeId != target.EdgeId)
            {
                throw new ArgumentException("Target point must be part of the same edge.");
            }
            if (point.Offset == target.Offset)
            { // path is possible but it has a weight of 0.
                return(new EdgePath <T>(point.VertexId(db)));
            }
            var forward  = point.Offset < target.Offset;
            var edge     = db.Network.GetEdge(point.EdgeId);
            var distance = ((float)System.Math.Abs((int)point.Offset - (int)target.Offset) / (float)ushort.MaxValue) *
                           edge.Data.Distance;
            Factor factor;
            var    weight = weightHandler.Calculate(edge.Data.Profile, distance, out factor);

            if (factor.Value <= 0)
            { // not possible to travel here.
                return(null);
            }
            if (factor.Direction == 0 ||
                (forward && factor.Direction == 1) ||
                (!forward && factor.Direction == 2))
            { // ok, directions match.
                if (forward)
                {
                    return(new EdgePath <T>(target.VertexId(db), weight, point.EdgeId, new EdgePath <T>(point.VertexId(db))));
                }
                return(new EdgePath <T>(target.VertexId(db), weight, -point.EdgeId, new EdgePath <T>(point.VertexId(db))));
            }
            return(null);
        }
Пример #2
0
        /// <summary>
        /// Adds the router point as a vertex.
        /// </summary>
        public static uint AddAsVertex(this RouterDb routerDb, RouterPoint point)
        {
            if (routerDb.HasContracted)
            {
                throw new InvalidOperationException("Cannot add new vertices to a routerDb with contracted versions of the network.");
            }

            if (point.IsVertex())
            { // the router point is already a vertex.
                return(point.VertexId(routerDb));
            }

            // add a new vertex at the router point location.
            var location = point.LocationOnNetwork(routerDb);
            var vertex   = routerDb.Network.VertexCount;

            routerDb.Network.AddVertex(vertex, location.Latitude, location.Longitude);

            // add two new edges.
            var edge      = routerDb.Network.GetEdge(point.EdgeId);
            var shapeFrom = point.ShapePointsTo(routerDb, edge.From);

            shapeFrom.Reverse(); // we need this shape from edge.From -> vertex.
            var shapeTo      = point.ShapePointsTo(routerDb, edge.To);
            var distanceFrom = point.DistanceTo(routerDb, edge.From);
            var distanceTo   = point.DistanceTo(routerDb, edge.To);

            // remove edge id.
            routerDb.Network.RemoveEdge(point.EdgeId);

            // split in two.
            routerDb.Network.AddEdge(edge.From, vertex, new Data.Network.Edges.EdgeData()
            {
                Distance = distanceFrom,
                MetaId   = edge.Data.MetaId,
                Profile  = edge.Data.Profile
            }, shapeFrom);
            routerDb.Network.AddEdge(vertex, edge.To, new Data.Network.Edges.EdgeData()
            {
                Distance = distanceTo,
                MetaId   = edge.Data.MetaId,
                Profile  = edge.Data.Profile
            }, shapeTo);

            // sort the vertices again.
            routerDb.Network.Sort((v1, v2) =>
            {
                if (vertex == v1)
                {
                    vertex = (uint)v2;
                }
                else if (vertex == v2)
                {
                    vertex = (uint)v1;
                }
            });
            return(vertex);
        }