| | 1 | | using System; |
| | 2 | | using System.Collections; |
| | 3 | | using System.Collections.Generic; |
| | 4 | | using System.Linq; |
| | 5 | | using Itinero.Network; |
| | 6 | | using Itinero.Network.Enumerators.Edges; |
| | 7 | | using NetTopologySuite.Features; |
| | 8 | | using NetTopologySuite.Geometries; |
| | 9 | |
|
| | 10 | | namespace Itinero.Geo; |
| | 11 | |
|
| | 12 | | internal class RoutingNetworkEnumerator : IEnumerator<IFeature> |
| | 13 | | { |
| | 14 | | private readonly RoutingNetwork _network; |
| | 15 | |
|
| | 16 | | private readonly Func<IEnumerable<(string key, string value)>, IEnumerable<(string key, string value)>> |
| | 17 | | _preprocessEdge; |
| | 18 | |
|
| | 19 | | private readonly IEnumerator<VertexId> _vertexIds; |
| | 20 | |
|
| 4 | 21 | | private readonly HashSet<EdgeId> _seenVertices = new(); |
| | 22 | |
|
| | 23 | |
|
| | 24 | | private readonly RoutingNetworkEdgeEnumerator _edges; |
| | 25 | |
|
| | 26 | | private bool _edgesAreInitiated; |
| | 27 | |
|
| 4 | 28 | | public RoutingNetworkEnumerator(RoutingNetwork network, |
| 4 | 29 | | Func<IEnumerable<(string key, string value)>, IEnumerable<(string key, string value)>> preprocessEdge) |
| 4 | 30 | | { |
| 4 | 31 | | _network = network; |
| 4 | 32 | | _preprocessEdge = preprocessEdge; |
| 4 | 33 | | _vertexIds = network.GetVertices().GetEnumerator(); |
| 4 | 34 | | _edges = network.GetEdgeEnumerator(); |
| 4 | 35 | | } |
| | 36 | |
|
| | 37 | | public bool MoveNext() |
| 22 | 38 | | { |
| 22 | 39 | | if (!_edgesAreInitiated) |
| 11 | 40 | | { |
| 11 | 41 | | var hasNext = _vertexIds.MoveNext(); |
| 11 | 42 | | if (!hasNext) |
| 4 | 43 | | { |
| 4 | 44 | | return false; |
| | 45 | | } |
| | 46 | |
|
| 7 | 47 | | _edges.MoveTo(_vertexIds.Current); |
| 7 | 48 | | _edgesAreInitiated = true; |
| 7 | 49 | | var attrs = new AttributesTable { |
| 7 | 50 | | {"_vertex_id", "" + _vertexIds.Current} |
| 7 | 51 | | }; |
| 7 | 52 | | _network.TryGetVertex(_vertexIds.Current, out var lon, out var lat, out var el); |
| 7 | 53 | | this.Current = new Feature( |
| 7 | 54 | | new Point(lon, lat, el ?? 0f), attrs); |
| | 55 | |
|
| 7 | 56 | | return true; |
| | 57 | | } |
| | 58 | |
|
| 11 | 59 | | var hasNextEdge = false; |
| | 60 | | do |
| 15 | 61 | | { |
| 15 | 62 | | hasNextEdge = _edges.MoveNext(); |
| 30 | 63 | | } while (_seenVertices.Contains(_edges.EdgeId) && hasNextEdge); |
| | 64 | |
|
| 11 | 65 | | if (!hasNextEdge) |
| 7 | 66 | | { |
| 7 | 67 | | _edgesAreInitiated = false; |
| 7 | 68 | | return this.MoveNext(); |
| | 69 | | } |
| 4 | 70 | | _seenVertices.Add(_edges.EdgeId); |
| | 71 | |
|
| | 72 | |
|
| 4 | 73 | | var attrTable = new AttributesTable(); |
| 4 | 74 | | var rawAttr = _edges.Attributes; |
| 4 | 75 | | if (_preprocessEdge != null) |
| 0 | 76 | | { |
| 0 | 77 | | rawAttr = _preprocessEdge.Invoke(rawAttr); |
| 0 | 78 | | } |
| | 79 | |
|
| 12 | 80 | | foreach (var kv in rawAttr) |
| 0 | 81 | | { |
| 0 | 82 | | attrTable.Add(kv.key, kv.value); |
| 0 | 83 | | } |
| | 84 | |
|
| 4 | 85 | | var shape = _edges.Shape.ToList(); |
| 4 | 86 | | var coors = new Coordinate[shape.Count + 2]; |
| 4 | 87 | | var (frLon, frLat, _) = _edges.TailLocation; |
| 4 | 88 | | coors[0] = new Coordinate(frLon, frLat); |
| 4 | 89 | | var (toLon, toLat, _) = _edges.HeadLocation; |
| 4 | 90 | | coors[^1] = new Coordinate(toLon, toLat); |
| 14 | 91 | | for (var i = 0; i < shape.Count(); i++) |
| 3 | 92 | | { |
| 3 | 93 | | var shp = shape[i]; |
| 3 | 94 | | coors[i + 1] = new Coordinate(shp.longitude, shp.latitude); |
| 3 | 95 | | } |
| | 96 | |
|
| 4 | 97 | | this.Current = new Feature( |
| 4 | 98 | | new LineString(coors), attrTable); |
| | 99 | |
|
| 4 | 100 | | return true; |
| 22 | 101 | | } |
| | 102 | |
|
| | 103 | | public void Reset() |
| 0 | 104 | | { |
| 0 | 105 | | _edges.Reset(); |
| 0 | 106 | | _vertexIds.Reset(); |
| 0 | 107 | | _seenVertices.Clear(); |
| 0 | 108 | | } |
| | 109 | |
|
| 22 | 110 | | public IFeature Current { get; private set; } |
| | 111 | |
|
| 0 | 112 | | object IEnumerator.Current => this.Current; |
| | 113 | |
|
| | 114 | | public void Dispose() |
| 4 | 115 | | { |
| 4 | 116 | | _vertexIds.Dispose(); |
| 4 | 117 | | } |
| | 118 | | } |