| | | 1 | | using System; |
| | | 2 | | using System.Collections.Generic; |
| | | 3 | | using Itinero.Network.Enumerators.Edges; |
| | | 4 | | using Itinero.Routing.Costs; |
| | | 5 | | |
| | | 6 | | namespace Itinero.Network.Search.Islands; |
| | | 7 | | |
| | | 8 | | internal static class ICostFunctionExtensions |
| | | 9 | | { |
| | | 10 | | /// <summary> |
| | | 11 | | /// Gets the cost of a turn from the previous edges sequence to the given edge in the enumerator in a forward direct |
| | | 12 | | /// |
| | | 13 | | /// This does NOT include the cost of the previous edges. |
| | | 14 | | /// </summary> |
| | | 15 | | /// <param name="costFunction">The cost function.</param> |
| | | 16 | | /// <param name="enumerator">The edge to test.</param> |
| | | 17 | | /// <param name="forward">Then true, calculate the cost including turn cost from (previousEdge ->) enumerator.tail - |
| | | 18 | | /// <param name="previousEdges">A sequence of previously traversed edge, if any.</param> |
| | | 19 | | /// <returns>True if the current edge is traversable and the turn cost allows the turn.</returns> |
| | | 20 | | public static bool GetIslandBuilderCost(this ICostFunction costFunction, |
| | | 21 | | RoutingNetworkEdgeEnumerator enumerator, bool forward = true, IEnumerable<(EdgeId edgeId, byte? turn)>? previous |
| | 364 | 22 | | { |
| | 364 | 23 | | var cost = costFunction.Get(enumerator, forward, previousEdges); |
| | | 24 | | |
| | 364 | 25 | | return cost is { canAccess: true, turnCost: < double.MaxValue }; |
| | 364 | 26 | | } |
| | | 27 | | |
| | | 28 | | /// <summary> |
| | | 29 | | /// Gets the cost of traversing through a shared vertex from <paramref name="from"/> to |
| | | 30 | | /// <paramref name="to"/>, including the turn cost at the shared vertex. |
| | | 31 | | /// |
| | | 32 | | /// Both enumerators must be pre-positioned in their respective traversal directions |
| | | 33 | | /// such that the shared vertex is at <c>from.Head</c> and at <c>to.Tail</c>. |
| | | 34 | | /// </summary> |
| | | 35 | | /// <returns>True if <paramref name="from"/> is traversable in its direction, |
| | | 36 | | /// <paramref name="to"/> is traversable in its direction, AND the turn from |
| | | 37 | | /// <paramref name="from"/> through the shared vertex into <paramref name="to"/> is |
| | | 38 | | /// allowed (turn cost < <see cref="double.MaxValue"/>).</returns> |
| | | 39 | | public static bool GetIslandBuilderCost(this ICostFunction costFunction, |
| | | 40 | | RoutingNetworkEdgeEnumerator from, |
| | | 41 | | RoutingNetworkEdgeEnumerator to) |
| | 11728 | 42 | | { |
| | | 43 | | // from-edge must be traversable in its current direction at all. |
| | | 44 | | // without this check a one-way edge whose only allowed direction goes the |
| | | 45 | | // OPPOSITE way of the requested traversal would still appear to enable a |
| | | 46 | | // turn into the to-edge. |
| | 11728 | 47 | | var fromCost = costFunction.Get(from, tailToHead: true, null); |
| | 11846 | 48 | | if (!fromCost.canAccess) return false; |
| | | 49 | | |
| | 11610 | 50 | | var fromOrder = from.HeadOrder; |
| | 11610 | 51 | | var previousEdges = fromOrder.HasValue |
| | 11610 | 52 | | ? new (EdgeId edgeId, byte? turn)[] { (from.EdgeId, fromOrder) } |
| | 11610 | 53 | | : null; |
| | | 54 | | |
| | 11610 | 55 | | var cost = costFunction.Get(to, tailToHead: true, previousEdges); |
| | 11610 | 56 | | return cost is { canAccess: true, turnCost: < double.MaxValue }; |
| | 11728 | 57 | | } |
| | | 58 | | } |