/// <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); }
/// <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); }