< 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:224_14471318300

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>
 43921    internal NetworkTileEnumerator()
 43922    {
 43923    }
 24
 1875825    public NetworkTile? Tile { get; private set; }
 26
 27    /// <summary>
 28    /// Gets the tile id.
 29    /// </summary>
 151930    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)
 41438    {
 41439        this.Tile = graphTile;
 40
 41441        this.Reset();
 41442    }
 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)
 36250    {
 36251        if (this.Tile == null)
 052        {
 053            throw new InvalidOperationException("Move to graph tile first.");
 54        }
 55
 36256        if (vertex.LocalId >= this.Tile.VertexCount)
 057        {
 058            return false;
 59        }
 60
 36261        _headLocation = null;
 36262        _tailLocation = null;
 36263        _localId = vertex.LocalId;
 36264        _nextEdgePointer = uint.MaxValue;
 36265        this.EdgePointer = uint.MaxValue;
 66
 36267        this.Tail = vertex;
 36268        return true;
 36269    }
 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)
 60478    {
 60479        if (this.Tile == null) throw new InvalidOperationException("Move to graph tile first.");
 80
 60481        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
 60484        if (this.Tile.IsEdgeDeleted(edge)) return false;
 85
 60486        _headLocation = null;
 60487        _tailLocation = null;
 60488        _nextEdgePointer = edge.LocalId;
 60489        if (edge.LocalId >= EdgeId.MinCrossId)
 290        {
 291            _nextEdgePointer = this.Tile.GetEdgeCrossPointer(edge.LocalId - EdgeId.MinCrossId);
 292        }
 60493        this.EdgePointer = _nextEdgePointer.Value;
 94
 95        // decode edge data.
 60496        this.EdgeId = edge;
 60497        var size = this.Tile.DecodeVertex(_nextEdgePointer.Value, out var localId, out var tileId);
 60498        var vertex1 = new VertexId(tileId, localId);
 60499        _nextEdgePointer += size;
 604100        size = this.Tile.DecodeVertex(_nextEdgePointer.Value, out localId, out tileId);
 604101        var vertex2 = new VertexId(tileId, localId);
 604102        _nextEdgePointer += size;
 604103        size = this.Tile.DecodePointer(_nextEdgePointer.Value, out var vp1);
 604104        _nextEdgePointer += size;
 604105        size = this.Tile.DecodePointer(_nextEdgePointer.Value, out var vp2);
 604106        _nextEdgePointer += size;
 107
 604108        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.
 604117        size = this.Tile.DecodeEdgePointerId(_nextEdgePointer.Value, out var edgeProfileId);
 604118        _nextEdgePointer += size;
 604119        this.EdgeTypeId = edgeProfileId;
 120
 121        // get length.
 604122        size = this.Tile.DecodeEdgePointerId(_nextEdgePointer.Value, out var length);
 604123        _nextEdgePointer += size;
 604124        this.Length = length;
 125
 126        // get tail and head order.
 604127        this.Tile.GetTailHeadOrder(_nextEdgePointer.Value, ref _tailOrder, ref _headOrder);
 604128        _nextEdgePointer++;
 129
 604130        size = this.Tile.DecodePointer(_nextEdgePointer.Value, out _shapePointer);
 604131        _nextEdgePointer += size;
 604132        size = this.Tile.DecodePointer(_nextEdgePointer.Value, out _attributesPointer);
 133
 604134        if (forward)
 436135        {
 436136            this.Tail = vertex1;
 436137            this.Head = vertex2;
 436138            this.Forward = true;
 139
 436140            _nextEdgePointer = vp1;
 436141        }
 142        else
 168143        {
 168144            this.Tail = vertex2;
 168145            this.Head = vertex1;
 168146            this.Forward = false;
 147
 168148            (_headOrder, _tailOrder) = (_tailOrder, _headOrder);
 149
 168150            _nextEdgePointer = vp2;
 168151        }
 152
 604153        return true;
 604154    }
 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()
 427165    {
 427166        if (this.Tile == null)
 0167        {
 0168            throw new InvalidOperationException("Cannot reset an empty enumerator.");
 169        }
 170
 427171        _headLocation = null;
 427172        _tailLocation = null;
 427173        this.EdgePointer = uint.MaxValue;
 427174        _nextEdgePointer = uint.MaxValue;
 427175    }
 176
 0177    public bool IsEmpty => this.Tile == null;
 178
 3132179    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()
 773186    {
 777187        while (true)
 777188        {
 777189            _headLocation = null;
 777190            _tailLocation = null;
 777191            _headOrder = null;
 777192            _tailOrder = null;
 777193            this.EdgePointer = uint.MaxValue;
 194
 777195            if (this.Tile == null) throw new InvalidOperationException("Move to graph tile first.");
 196
 777197            if (_nextEdgePointer == uint.MaxValue)
 374198            {
 199                // move to the first edge.
 374200                _nextEdgePointer = this.Tile.VertexEdgePointer(_localId).DecodeNullableData();
 374201            }
 202
 777203            if (_nextEdgePointer == null)
 276204            {
 205                // no more data available.
 276206                return false;
 207            }
 208
 209            // decode edge data.
 501210            this.EdgePointer = _nextEdgePointer.Value;
 501211            this.EdgeId = new EdgeId(this.Tile.TileId, _nextEdgePointer.Value);
 501212            var size = this.Tile.DecodeVertex(_nextEdgePointer.Value, out var localId, out var tileId);
 501213            var vertex1 = new VertexId(tileId, localId);
 501214            _nextEdgePointer += size;
 501215            size = this.Tile.DecodeVertex(_nextEdgePointer.Value, out localId, out tileId);
 501216            var vertex2 = new VertexId(tileId, localId);
 501217            _nextEdgePointer += size;
 501218            size = this.Tile.DecodePointer(_nextEdgePointer.Value, out var vp1);
 501219            _nextEdgePointer += size;
 501220            size = this.Tile.DecodePointer(_nextEdgePointer.Value, out var vp2);
 501221            _nextEdgePointer += size;
 222
 501223            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.
 501232            size = this.Tile.DecodeEdgePointerId(_nextEdgePointer.Value, out var edgeProfileId);
 501233            _nextEdgePointer += size;
 501234            this.EdgeTypeId = edgeProfileId;
 235
 236            // get length.
 501237            size = this.Tile.DecodeEdgePointerId(_nextEdgePointer.Value, out var length);
 501238            _nextEdgePointer += size;
 501239            this.Length = length;
 240
 241            // get tail and head order.
 501242            this.Tile.GetTailHeadOrder(_nextEdgePointer.Value, ref _tailOrder, ref _headOrder);
 501243            _nextEdgePointer++;
 244
 245            // get shape and attribute pointers.
 501246            size = this.Tile.DecodePointer(_nextEdgePointer.Value, out _shapePointer);
 501247            _nextEdgePointer += size;
 501248            size = this.Tile.DecodePointer(_nextEdgePointer.Value, out _attributesPointer);
 249
 501250            if (vertex1.TileId == this.Tile.TileId && vertex1.LocalId == _localId)
 278251            {
 278252                _nextEdgePointer = vp1;
 253
 278254                this.Head = vertex2;
 278255                this.Forward = true;
 278256            }
 257            else
 223258            {
 223259                _nextEdgePointer = vp2;
 260
 223261                this.Head = vertex1;
 223262                this.Forward = false;
 263
 223264                (_headOrder, _tailOrder) = (_tailOrder, _headOrder);
 223265            }
 266
 501267            if (this.Tile.IsEdgeDeleted(this.EdgeId))
 4268            {
 4269                continue;
 270            }
 271
 497272            return true;
 273        }
 773274    }
 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
 363282        {
 363283            if (this.Tile == null)
 0284            {
 0285                throw new InvalidOperationException("Move to graph tile first.");
 286            }
 287
 363288            if (!this.Forward)
 123289            {
 123290                return this.Tile.GetShape(_shapePointer).Reverse();
 291            }
 292
 240293            return this.Tile.GetShape(_shapePointer);
 363294        }
 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
 283303        {
 283304            if (this.Tile == null)
 0305            {
 0306                throw new InvalidOperationException("Move to graph tile first.");
 307            }
 308
 283309            return this.Tile.GetAttributes(_attributesPointer);
 283310        }
 311    }
 312
 313    /// <summary>
 314    /// Gets the first vertex.
 315    /// </summary>
 1521316    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>
 1661334    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>
 2361352    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>
 1973360    public bool Forward { get; private set; }
 361
 362    /// <summary>
 363    /// Gets the edge profile id, if any.
 364    /// </summary>
 1157365    public uint? EdgeTypeId { get; private set; }
 366
 367    /// <summary>
 368    /// Gets the length in centimeters, if any.
 369    /// </summary>
 1533370    public uint? Length { get; private set; }
 371
 372    /// <summary>
 373    /// Gets the head index of this edge in the turn cost table.
 374    /// </summary>
 141375    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}