private Dictionary <TopoTroncon, TopoNode> GetAccessibleNodes(Topology topology, TopoNode topoNode) { Dictionary <TopoTroncon, TopoNode> nodesByTroncon = new Dictionary <TopoTroncon, TopoNode>(); if (topoNode.IdTroncons.Any()) { foreach (var idTroncon in topoNode.IdTroncons) { if (topology.TopoTroncons.ContainsKey(idTroncon)) { TopoTroncon trn = topology.TopoTroncons[idTroncon]; int idNode = trn.IdNodes.Except(new int[] { topoNode.Id }).SingleOrDefault(); nodesByTroncon[trn] = topology.TopoNodes[idNode]; } } } return(nodesByTroncon); }
private void Compute() { // 1. Add all edges start and end points -> distinct topology nodes // We want to have a pointer for each troncon to start and end geometry int index = 0; foreach (Troncon troncon in Troncons) { SqlGeometry start = troncon.StartPoint; SqlGeometry end = troncon.EndPoint; if (!NodeAdded(start)) { AddNode(start, index++); } if (!NodeAdded(end)) { AddNode(end, index++); } } // 2. get connections between nodes and edges Dictionary <int, TopoNode> newNodes = new Dictionary <int, TopoNode>(); foreach (var topoNode in TopoNodes) { var connectedTroncons = Troncons.Where(t => t.StartPoint.STEquals(topoNode.Value.Geometry).IsTrue || t.EndPoint.STEquals(topoNode.Value.Geometry).IsTrue) .ToList(); // Is the topology node an "IGN node" ? // Yes => proceed // No => IGN indicates that this is a bridge or tunnel and there are in fact // multiple nodes connecting only two edges at once if (IsIgnNode(topoNode) || connectedTroncons.Count == 1) { topoNode.Value.IdTroncons.UnionWith(connectedTroncons.Select(t => t.Id)); } else { if (connectedTroncons.Count % 2 != 0) { Trace.TraceWarning($"Bridge or tunnel has a weird number of connections. Edges: {string.Join<int>(", ", connectedTroncons.Select(t=>t.Id))}"); } List <ColinearGroup> colinearGroups = FindColinearTroncons(connectedTroncons, topoNode.Value.Geometry); bool firstGroup = true; foreach (var group in colinearGroups) { // avoid to make topoNode orphan // add new node on second iteration only if (!firstGroup) { index++; //Debug.WriteLine("new " + index.ToString()); var newNode = new TopoNode(index, topoNode.Value); newNodes.Add(index, newNode); newNode.IdTroncons.UnionWith(group.ColinearTroncons.Select(t => t.Id)); } else { Debug.Assert(topoNode.Value.IdTroncons.Count == 0, "Toponode is already connected."); topoNode.Value.IdTroncons.UnionWith(group.ColinearTroncons.Select(t => t.Id)); firstGroup = false; } } } } // 3. Merge nodes foreach (var newNode in newNodes) { TopoNodes.Add(newNode.Key, newNode.Value); } TopoTroncons = new Dictionary <int, TopoTroncon>(); foreach (var topoNode in TopoNodes) { foreach (var idTroncon in topoNode.Value.IdTroncons) { if (!TopoTroncons.ContainsKey(idTroncon)) { TopoTroncons[idTroncon] = new TopoTroncon { IdTroncon = idTroncon, Geometry = Troncons.First(t => t.Id == idTroncon).Geometry }; } TopoTroncons[idTroncon].IdNodes.Add(topoNode.Value.Id); } } }