< Summary

Class:Itinero.Network.Tiles.NetworkTileEnumerator
Assembly:Itinero
File(s):/home/runner/work/routing2/routing2/src/Itinero/Network/Tiles/NetworkTileEnumerator.cs
Covered lines:193
Uncovered lines:33
Coverable lines:226
Total lines:464
Line coverage:85.3% (193 of 226)
Covered branches:57
Total branches:100
Branch coverage:57% (57 of 100)
Tag:232_15462506344

Metrics

MethodBranch coverage Cyclomatic complexity Line coverage
.ctor()100%1100%
get_Tile()100%1100%
get_TileId()100%2100%
MoveTo(...)100%1100%
MoveTo(...)50%473.33%
MoveTo(...)60%3098.24%
Reset()50%277.77%
get_IsEmpty()100%10%
get_EdgePointer()100%1100%
MoveNext()68.75%32100%
get_Shape()75%477.77%
get_Attributes()50%266.66%
get_Tail()100%1100%
get_TailLocation()0%20%
get_Head()100%1100%
get_HeadLocation()0%20%
get_EdgeId()100%1100%
get_Forward()100%1100%
get_EdgeTypeId()100%1100%
get_Length()100%1100%
get_HeadOrder()100%1100%
get_TailOrder()100%1100%
GetTurnCostToTail(...)50%487.5%
GetTurnCostFromTail(...)50%487.5%
GetTurnCostToHead(...)50%487.5%
GetTurnCostFromHead(...)50%487.5%
GetVertex(...)0%40%

File(s)

/home/runner/work/routing2/routing2/src/Itinero/Network/Tiles/NetworkTileEnumerator.cs

#LineLine coverage
 1using System;
 2using System.Collections.Generic;
 3using System.Linq;
 4using Itinero.Network.Storage;
 5using Itinero.Network.Tiles.Standalone;
 6
 7namespace Itinero.Network.Tiles;
 8
 9internal class NetworkTileEnumerator : INetworkTileEdge, IStandaloneNetworkTileEnumerator
 10{
 11    private uint _localId;
 12    private uint? _nextEdgePointer;
 13    private uint? _shapePointer;
 14    private uint? _attributesPointer;
 15    private byte? _tailOrder;
 16    private byte? _headOrder;
 17
 18    /// <summary>
 19    /// Creates a new graph tile enumerator.
 20    /// </summary>
 50021    internal NetworkTileEnumerator()
 50022    {
 50023    }
 24
 2033825    public NetworkTile? Tile { get; private set; }
 26
 27    /// <summary>
 28    /// Gets the tile id.
 29    /// </summary>
 168230    public uint TileId => this.Tile?.TileId ?? uint.MaxValue;
 31
 32    /// <summary>
 33    /// Moves to the given tile.
 34    /// </summary>
 35    /// <param name="graphTile">The graph tile to move to.</param>
 36    /// <returns>True if the move succeeds.</returns>
 37    public void MoveTo(NetworkTile graphTile)
 47538    {
 47539        this.Tile = graphTile;
 40
 47541        this.Reset();
 47542    }
 43
 44    /// <summary>
 45    /// Move to the vertex.
 46    /// </summary>
 47    /// <param name="vertex">The vertex.</param>
 48    /// <returns>True if the move succeeds and the vertex exists.</returns>
 49    public bool MoveTo(VertexId vertex)
 39150    {
 39151        if (this.Tile == null)
 052        {
 053            throw new InvalidOperationException("Move to graph tile first.");
 54        }
 55
 39156        if (vertex.LocalId >= this.Tile.VertexCount)
 057        {
 058            return false;
 59        }
 60
 39161        _headLocation = null;
 39162        _tailLocation = null;
 39163        _localId = vertex.LocalId;
 39164        _nextEdgePointer = uint.MaxValue;
 39165        this.EdgePointer = uint.MaxValue;
 66
 39167        this.Tail = vertex;
 39168        return true;
 39169    }
 70
 71    /// <summary>
 72    /// Move to the given edge.
 73    /// </summary>
 74    /// <param name="edge">The edge.</param>
 75    /// <param name="forward">The forward flag.</param>
 76    /// <returns>True if the move succeeds and the edge exists.</returns>
 77    public bool MoveTo(EdgeId edge, bool forward)
 67178    {
 67179        if (this.Tile == null) throw new InvalidOperationException("Move to graph tile first.");
 80
 67181        if (this.TileId != edge.TileId) throw new ArgumentOutOfRangeException(nameof(edge),
 082                "Cannot move to edge not in current tile, move to the tile first.");
 83
 67184        if (this.Tile.IsEdgeDeleted(edge)) return false;
 85
 67186        _headLocation = null;
 67187        _tailLocation = null;
 67188        _nextEdgePointer = edge.LocalId;
 67189        if (edge.LocalId >= EdgeId.MinCrossId)
 290        {
 291            _nextEdgePointer = this.Tile.GetEdgeCrossPointer(edge.LocalId - EdgeId.MinCrossId);
 292        }
 67193        this.EdgePointer = _nextEdgePointer.Value;
 94
 95        // decode edge data.
 67196        this.EdgeId = edge;
 67197        var size = this.Tile.DecodeVertex(_nextEdgePointer.Value, out var localId, out var tileId);
 67198        var vertex1 = new VertexId(tileId, localId);
 67199        _nextEdgePointer += size;
 671100        size = this.Tile.DecodeVertex(_nextEdgePointer.Value, out localId, out tileId);
 671101        var vertex2 = new VertexId(tileId, localId);
 671102        _nextEdgePointer += size;
 671103        size = this.Tile.DecodePointer(_nextEdgePointer.Value, out var vp1);
 671104        _nextEdgePointer += size;
 671105        size = this.Tile.DecodePointer(_nextEdgePointer.Value, out var vp2);
 671106        _nextEdgePointer += size;
 107
 671108        if (vertex1.TileId != vertex2.TileId)
 2109        {
 2110            size = this.Tile.DecodeEdgeCrossId(_nextEdgePointer.Value, out var edgeCrossId);
 2111            _nextEdgePointer += size;
 112
 2113            this.EdgeId = new EdgeId(vertex1.TileId, edgeCrossId);
 2114        }
 115
 116        // get edge profile id.
 671117        size = this.Tile.DecodeEdgePointerId(_nextEdgePointer.Value, out var edgeProfileId);
 671118        _nextEdgePointer += size;
 671119        this.EdgeTypeId = edgeProfileId;
 120
 121        // get length.
 671122        size = this.Tile.DecodeEdgePointerId(_nextEdgePointer.Value, out var length);
 671123        _nextEdgePointer += size;
 671124        this.Length = length;
 125
 126        // get tail and head order.
 671127        this.Tile.GetTailHeadOrder(_nextEdgePointer.Value, ref _tailOrder, ref _headOrder);
 671128        _nextEdgePointer++;
 129
 671130        size = this.Tile.DecodePointer(_nextEdgePointer.Value, out _shapePointer);
 671131        _nextEdgePointer += size;
 671132        size = this.Tile.DecodePointer(_nextEdgePointer.Value, out _attributesPointer);
 133
 671134        if (forward)
 477135        {
 477136            this.Tail = vertex1;
 477137            this.Head = vertex2;
 477138            this.Forward = true;
 139
 477140            _nextEdgePointer = vp1;
 477141        }
 142        else
 194143        {
 194144            this.Tail = vertex2;
 194145            this.Head = vertex1;
 194146            this.Forward = false;
 147
 194148            (_headOrder, _tailOrder) = (_tailOrder, _headOrder);
 149
 194150            _nextEdgePointer = vp2;
 194151        }
 152
 671153        return true;
 671154    }
 155
 156    /// <summary>
 157    /// Resets this enumerator.
 158    /// </summary>
 159    /// <remarks>
 160    /// Reset this enumerator to:
 161    /// - the first vertex for the currently selected edge.
 162    /// - the first vertex for the graph tile if there is no selected edge.
 163    /// </remarks>
 164    public void Reset()
 488165    {
 488166        if (this.Tile == null)
 0167        {
 0168            throw new InvalidOperationException("Cannot reset an empty enumerator.");
 169        }
 170
 488171        _headLocation = null;
 488172        _tailLocation = null;
 488173        this.EdgePointer = uint.MaxValue;
 488174        _nextEdgePointer = uint.MaxValue;
 488175    }
 176
 0177    public bool IsEmpty => this.Tile == null;
 178
 3439179    internal uint EdgePointer { get; private set; } = uint.MaxValue;
 180
 181    /// <summary>
 182    /// Moves to the next edge for the current vertex.
 183    /// </summary>
 184    /// <returns>True when there is a new edge.</returns>
 185    public bool MoveNext()
 830186    {
 834187        while (true)
 834188        {
 834189            _headLocation = null;
 834190            _tailLocation = null;
 834191            _headOrder = null;
 834192            _tailOrder = null;
 834193            this.EdgePointer = uint.MaxValue;
 194
 834195            if (this.Tile == null) throw new InvalidOperationException("Move to graph tile first.");
 196
 834197            if (_nextEdgePointer == uint.MaxValue)
 403198            {
 199                // move to the first edge.
 403200                _nextEdgePointer = this.Tile.VertexEdgePointer(_localId).DecodeNullableData();
 403201            }
 202
 834203            if (_nextEdgePointer == null)
 301204            {
 205                // no more data available.
 301206                return false;
 207            }
 208
 209            // decode edge data.
 533210            this.EdgePointer = _nextEdgePointer.Value;
 533211            this.EdgeId = new EdgeId(this.Tile.TileId, _nextEdgePointer.Value);
 533212            var size = this.Tile.DecodeVertex(_nextEdgePointer.Value, out var localId, out var tileId);
 533213            var vertex1 = new VertexId(tileId, localId);
 533214            _nextEdgePointer += size;
 533215            size = this.Tile.DecodeVertex(_nextEdgePointer.Value, out localId, out tileId);
 533216            var vertex2 = new VertexId(tileId, localId);
 533217            _nextEdgePointer += size;
 533218            size = this.Tile.DecodePointer(_nextEdgePointer.Value, out var vp1);
 533219            _nextEdgePointer += size;
 533220            size = this.Tile.DecodePointer(_nextEdgePointer.Value, out var vp2);
 533221            _nextEdgePointer += size;
 222
 533223            if (vertex1.TileId != vertex2.TileId)
 7224            {
 7225                size = this.Tile.DecodeEdgeCrossId(_nextEdgePointer.Value, out var edgeCrossId);
 7226                _nextEdgePointer += size;
 227
 7228                this.EdgeId = new EdgeId(vertex1.TileId, edgeCrossId);
 7229            }
 230
 231            // get edge profile id.
 533232            size = this.Tile.DecodeEdgePointerId(_nextEdgePointer.Value, out var edgeProfileId);
 533233            _nextEdgePointer += size;
 533234            this.EdgeTypeId = edgeProfileId;
 235
 236            // get length.
 533237            size = this.Tile.DecodeEdgePointerId(_nextEdgePointer.Value, out var length);
 533238            _nextEdgePointer += size;
 533239            this.Length = length;
 240
 241            // get tail and head order.
 533242            this.Tile.GetTailHeadOrder(_nextEdgePointer.Value, ref _tailOrder, ref _headOrder);
 533243            _nextEdgePointer++;
 244
 245            // get shape and attribute pointers.
 533246            size = this.Tile.DecodePointer(_nextEdgePointer.Value, out _shapePointer);
 533247            _nextEdgePointer += size;
 533248            size = this.Tile.DecodePointer(_nextEdgePointer.Value, out _attributesPointer);
 249
 533250            if (vertex1.TileId == this.Tile.TileId && vertex1.LocalId == _localId)
 294251            {
 294252                _nextEdgePointer = vp1;
 253
 294254                this.Head = vertex2;
 294255                this.Forward = true;
 294256            }
 257            else
 239258            {
 239259                _nextEdgePointer = vp2;
 260
 239261                this.Head = vertex1;
 239262                this.Forward = false;
 263
 239264                (_headOrder, _tailOrder) = (_tailOrder, _headOrder);
 239265            }
 266
 533267            if (this.Tile.IsEdgeDeleted(this.EdgeId))
 4268            {
 4269                continue;
 270            }
 271
 529272            return true;
 273        }
 830274    }
 275
 276    /// <summary>
 277    /// Gets the shape of the given edge (not including vertex locations).
 278    /// </summary>
 279    public IEnumerable<(double longitude, double latitude, float? e)> Shape
 280    {
 281        get
 370282        {
 370283            if (this.Tile == null)
 0284            {
 0285                throw new InvalidOperationException("Move to graph tile first.");
 286            }
 287
 370288            if (!this.Forward)
 121289            {
 121290                return this.Tile.GetShape(_shapePointer).Reverse();
 291            }
 292
 249293            return this.Tile.GetShape(_shapePointer);
 370294        }
 295    }
 296
 297    /// <summary>
 298    /// Gets the attributes of the given edge.
 299    /// </summary>
 300    public IEnumerable<(string key, string value)> Attributes
 301    {
 302        get
 290303        {
 290304            if (this.Tile == null)
 0305            {
 0306                throw new InvalidOperationException("Move to graph tile first.");
 307            }
 308
 290309            return this.Tile.GetAttributes(_attributesPointer);
 290310        }
 311    }
 312
 313    /// <summary>
 314    /// Gets the first vertex.
 315    /// </summary>
 1594316    public VertexId Tail { get; private set; }
 317
 318    private (double longitude, double latitude, float? e)? _tailLocation;
 319
 320    /// <inheritdoc/>
 321    public (double longitude, double latitude, float? e) TailLocation
 322    {
 323        get
 0324        {
 0325            _tailLocation ??= this.GetVertex(this.Tail);
 326
 0327            return _tailLocation.Value;
 0328        }
 329    }
 330
 331    /// <summary>
 332    /// Gets the second vertex.
 333    /// </summary>
 1794334    public VertexId Head { get; private set; }
 335
 336    private (double longitude, double latitude, float? e)? _headLocation;
 337
 338    /// <inheritdoc/>
 339    public (double longitude, double latitude, float? e) HeadLocation
 340    {
 341        get
 0342        {
 0343            _headLocation ??= this.GetVertex(this.Head);
 344
 0345            return _headLocation.Value;
 0346        }
 347    }
 348
 349    /// <summary>
 350    /// Gets the local edge id.
 351    /// </summary>
 2575352    public EdgeId EdgeId { get; private set; }
 353
 354    /// <summary>
 355    /// Gets the forward/backward flag.
 356    /// </summary>
 357    /// <remarks>
 358    /// When true the attributes can be interpreted normally, when false they represent the direction from tail -> head.
 359    /// </remarks>
 2134360    public bool Forward { get; private set; }
 361
 362    /// <summary>
 363    /// Gets the edge profile id, if any.
 364    /// </summary>
 1256365    public uint? EdgeTypeId { get; private set; }
 366
 367    /// <summary>
 368    /// Gets the length in centimeters, if any.
 369    /// </summary>
 1646370    public uint? Length { get; private set; }
 371
 372    /// <summary>
 373    /// Gets the head index of this edge in the turn cost table.
 374    /// </summary>
 166375    public byte? HeadOrder => _headOrder;
 376
 377    /// <summary>
 378    /// Gets the tail index of this edge in the turn cost table.
 379    /// </summary>
 108380    public byte? TailOrder => _tailOrder;
 381
 382    /// <summary>
 383    /// Gets the turn cost at the tail turn (source -> [tail -> head]).
 384    /// </summary>
 385    /// <param name="sourceOrder">The order of the source edge.</param>
 386    /// <returns>The turn costs if any.</returns>
 387    public IEnumerable<(uint turnCostType, IEnumerable<(string key, string value)> attributes, uint cost, IEnumerable<Ed
 388        byte sourceOrder)
 18389    {
 18390        if (this.Tile == null)
 0391            return ArraySegment<(uint turnCostType, IEnumerable<(string key, string value)> attributes, uint cost, IEnum
 392
 18393        var order = _tailOrder;
 18394        return order == null
 18395            ? ArraySegment<(uint turnCostType, IEnumerable<(string key, string value)> attributes, uint cost, IEnumerabl
 18396            : this.Tile.GetTurnCosts(this.Tail, sourceOrder, order.Value);
 18397    }
 398
 399    /// <summary>
 400    /// Gets the turn cost at the tail turn ([head -> tail] -> target).
 401    /// </summary>
 402    /// <param name="targetOrder">The order of the target edge.</param>
 403    /// <returns>The turn costs if any.</returns>
 404    public IEnumerable<(uint turnCostType, IEnumerable<(string key, string value)> attributes, uint cost, IEnumerable<Ed
 405        byte targetOrder)
 1406    {
 1407        if (this.Tile == null)
 0408            return ArraySegment<(uint turnCostType, IEnumerable<(string key, string value)> attributes, uint cost, IEnum
 409
 1410        var order = _tailOrder;
 1411        return order == null
 1412            ? ArraySegment<(uint turnCostType, IEnumerable<(string key, string value)> attributes, uint cost, IEnumerabl
 1413            : this.Tile.GetTurnCosts(this.Tail, order.Value, targetOrder);
 1414    }
 415
 416    /// <summary>
 417    /// Gets the turn cost at the tail turn (source -> [head -> tail]).
 418    /// </summary>
 419    /// <param name="sourceOrder">The order of the source edge.</param>
 420    /// <returns>The turn costs if any.</returns>
 421    public IEnumerable<(uint turnCostType, IEnumerable<(string key, string value)> attributes, uint cost, IEnumerable<Ed
 422        byte sourceOrder)
 1423    {
 1424        if (this.Tile == null)
 0425            return ArraySegment<(uint turnCostType, IEnumerable<(string key, string value)> attributes, uint cost, IEnum
 426
 1427        var order = _headOrder;
 1428        return order == null
 1429            ? ArraySegment<(uint turnCostType, IEnumerable<(string key, string value)> attributes, uint cost, IEnumerabl
 1430            : this.Tile.GetTurnCosts(this.Head, sourceOrder, order.Value);
 1431    }
 432
 433    /// <summary>
 434    /// Gets the turn cost at the tail turn ([tail -> head] -> target).
 435    /// </summary>
 436    /// <param name="targetOrder">The order of the target edge.</param>
 437    /// <returns>The turn costs if any.</returns>
 438    public IEnumerable<(uint turnCostType, IEnumerable<(string key, string value)> attributes, uint cost, IEnumerable<Ed
 439        byte targetOrder)
 1440    {
 1441        if (this.Tile == null)
 0442            return ArraySegment<(uint turnCostType, IEnumerable<(string key, string value)> attributes, uint cost, IEnum
 443
 1444        var order = _headOrder;
 1445        return order == null
 1446            ? ArraySegment<(uint turnCostType, IEnumerable<(string key, string value)> attributes, uint cost, IEnumerabl
 1447            : this.Tile.GetTurnCosts(this.Head, order.Value, targetOrder);
 1448    }
 449
 450    private (double longitude, double latitude, float? e) GetVertex(VertexId vertex)
 0451    {
 0452        if (this.Tile == null)
 0453        {
 0454            throw new ArgumentOutOfRangeException(nameof(vertex), $"Vertex {vertex} not found!");
 455        }
 456
 0457        if (!this.Tile.TryGetVertex(vertex, out var longitude, out var latitude, out var e))
 0458        {
 0459            throw new ArgumentOutOfRangeException(nameof(vertex), $"Vertex {vertex} not found!");
 460        }
 461
 0462        return (longitude, latitude, e);
 0463    }
 464}