Ejemplo n.º 1
0
        /// <summary>
        /// Switches the data around for the two given vertices.
        /// </summary>
        /// <typeparam name="TEdgeData"></typeparam>
        /// <param name="graph"></param>
        /// <param name="vertex1"></param>
        /// <param name="vertex2"></param>
        public static void Switch <TEdgeData>(this GraphBase <TEdgeData> graph, uint vertex1, uint vertex2)
            where TEdgeData : struct, IGraphEdgeData
        {
            // get all existing data.
            var   edges1 = new List <Edge <TEdgeData> >(graph.GetEdges(vertex1));
            var   edges2 = new List <Edge <TEdgeData> >(graph.GetEdges(vertex2));
            float vertex1Latitude, vertex1Longitude;

            graph.GetVertex(vertex1, out vertex1Latitude, out vertex1Longitude);
            float vertex2Latitude, vertex2Longitude;

            graph.GetVertex(vertex2, out vertex2Latitude, out vertex2Longitude);

            // remove all edges.
            graph.RemoveEdges(vertex1);
            graph.RemoveEdges(vertex2);

            // update location.
            graph.SetVertex(vertex1, vertex2Latitude, vertex2Longitude);
            graph.SetVertex(vertex2, vertex1Latitude, vertex1Longitude);

            // add edges again.
            foreach (var edge in edges1)
            {
                // update existing data.
                if (edge.Neighbour == vertex1)
                {
                    edge.Neighbour = vertex2;
                }
                else if (edge.Neighbour == vertex2)
                {
                    edge.Neighbour = vertex1;
                }
                graph.AddEdge(vertex2, edge.Neighbour, edge.EdgeData, edge.Intermediates);
            }
            foreach (var edge in edges2)
            {
                // update existing data.
                if (edge.Neighbour == vertex1)
                {
                    edge.Neighbour = vertex2;
                }
                else if (edge.Neighbour == vertex2)
                {
                    edge.Neighbour = vertex1;
                }
                graph.AddEdge(vertex1, edge.Neighbour, edge.EdgeData, edge.Intermediates);
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Builds the reverse index for a directed graph.
        /// </summary>
        /// <typeparam name="TEdgeData"></typeparam>
        /// <returns></returns>
        public static IDictionary <uint, List <uint> > BuildReverse <TEdgeData>(this GraphBase <TEdgeData> graph)
            where TEdgeData : struct, IGraphEdgeData
        {
            if (!graph.IsDirected)
            {
                throw new ArgumentException("Building a reverse index for a non-directed graph is not supported.");
            }

            var reverse = new Dictionary <uint, List <uint> >();

            for (uint vertex = 1; vertex <= graph.VertexCount; vertex++)
            {
                foreach (var edge in graph.GetEdges(vertex))
                {
                    var         to = edge.Neighbour;
                    List <uint> neighbours;
                    if (!reverse.TryGetValue(to, out neighbours))
                    { // create an entry here.
                        neighbours = new List <uint>();
                    }
                    neighbours.Add(vertex);
                    reverse[to] = neighbours; // explicitly set again because this may be another kind of dictionary soon.
                }
            }
            return(reverse);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Copies all data from the given graph.
        /// </summary>
        /// <typeparam name="TEdgeData"></typeparam>
        /// <param name="copyTo"></param>
        /// <param name="copyFrom"></param>
        public static void CopyFrom <TEdgeData>(this GraphBase <TEdgeData> copyTo, GraphBase <TEdgeData> copyFrom)
            where TEdgeData : struct, IGraphEdgeData
        {
            float latitude, longitude;

            for (uint vertex = 1; vertex <= copyFrom.VertexCount; vertex++)
            {
                copyFrom.GetVertex(vertex, out latitude, out longitude);
                uint newVertex = copyTo.AddVertex(latitude, longitude);
                if (newVertex != vertex)
                {
                    throw new Exception("Graph should be empty when copy new data to it.");
                }
            }

            for (uint vertex = 1; vertex <= copyFrom.VertexCount; vertex++)
            {
                var edges = new List <Edge <TEdgeData> >(copyFrom.GetEdges(vertex));
                foreach (var edge in edges)
                {
                    copyTo.AddEdge(vertex, edge.Neighbour, edge.EdgeData, edge.Intermediates);
                }
            }
        }
Ejemplo n.º 4
0
 /// <summary>
 /// Returns the edge enumerator for the given vertex.
 /// </summary>
 /// <param name="vertexId"></param>
 /// <returns></returns>
 public override EdgeEnumerator <TEdgeData> GetEdges(uint vertexId)
 {
     return(_graph.GetEdges(vertexId));
 }
Ejemplo n.º 5
0
        /// <summary>
        /// Switches the locations around for the two given vertices.
        /// </summary>
        /// <typeparam name="TEdgeData"></typeparam>
        public static void Switch <TEdgeData>(this GraphBase <TEdgeData> graph, uint vertex1, uint vertex2,
                                              IDictionary <uint, List <uint> > reverse)
            where TEdgeData : struct, IGraphEdgeData
        {
            if (graph.IsDirected && reverse == null)
            {
                throw new ArgumentException("Cannot switch two vertices on a directed graph without it's reverse index.");
            }

            if (vertex1 == vertex2)
            { // switching identical vertices (?).
                return;
            }

            float vertex1Latitude, vertex1Longitude;

            graph.GetVertex(vertex1, out vertex1Latitude, out vertex1Longitude);
            float vertex2Latitude, vertex2Longitude;

            graph.GetVertex(vertex2, out vertex2Latitude, out vertex2Longitude);

            // update location.
            graph.SetVertex(vertex1, vertex2Latitude, vertex2Longitude);
            graph.SetVertex(vertex2, vertex1Latitude, vertex1Longitude);

            // switch and update edges, this is easy!
            var edges1 = new List <Edge <TEdgeData> >();

            foreach (var edge in graph.GetEdges(vertex1))
            {
                edges1.Add(new Edge <TEdgeData>()
                {
                    EdgeData      = edge.EdgeData,
                    Neighbour     = edge.Neighbour,
                    Intermediates = edge.Intermediates != null ? new CoordinateArrayCollection <GeoCoordinateSimple>(
                        edge.Intermediates.ToSimpleArray()) : null
                });
            }
            var edges2 = new List <Edge <TEdgeData> >();

            foreach (var edge in graph.GetEdges(vertex2))
            {
                edges2.Add(new Edge <TEdgeData>()
                {
                    EdgeData      = edge.EdgeData,
                    Neighbour     = edge.Neighbour,
                    Intermediates = edge.Intermediates != null ? new CoordinateArrayCollection <GeoCoordinateSimple>(
                        edge.Intermediates.ToSimpleArray()) : null
                });
            }

            graph.RemoveEdges(vertex1);
            graph.RemoveEdges(vertex2);

            foreach (var edge in edges1)
            { // update existing data.
                var neighbour    = edge.Neighbour;
                var newNeighbour = edge.Neighbour;
                if (newNeighbour == vertex2)
                {
                    newNeighbour = vertex1;
                }
                graph.AddEdge(vertex2, newNeighbour, edge.EdgeData, edge.Intermediates);

                if (reverse != null)
                { // update reverse set if present.
                    List <uint> neighbours = null;
                    if (reverse.TryGetValue(neighbour, out neighbours))
                    { // remove.
                        neighbours.Remove(vertex1);
                        reverse[neighbour] = neighbours;
                    }
                    if (reverse.TryGetValue(newNeighbour, out neighbours))
                    { // add.
                        neighbours.Add(vertex2);
                    }
                    else
                    { // add new.
                        neighbours = new List <uint>();
                        neighbours.Add(vertex2);
                    }
                    reverse[newNeighbour] = neighbours;
                }
            }
            foreach (var edge in edges2)
            { // update existing data.
                var neighbour    = edge.Neighbour;
                var newNeighbour = edge.Neighbour;
                if (newNeighbour == vertex1)
                {
                    newNeighbour = vertex2;
                }
                graph.AddEdge(vertex1, newNeighbour, edge.EdgeData, edge.Intermediates);

                if (reverse != null)
                { // update reverse set if present.
                    List <uint> neighbours = null;
                    if (reverse.TryGetValue(neighbour, out neighbours))
                    { // remove.
                        neighbours.Remove(vertex2);
                        reverse[neighbour] = neighbours;
                    }
                    if (reverse.TryGetValue(newNeighbour, out neighbours))
                    { // add.
                        neighbours.Add(vertex1);
                    }
                    else
                    { // add new.
                        neighbours = new List <uint>();
                        neighbours.Add(vertex1);
                    }
                    reverse[newNeighbour] = neighbours;
                }
            }

            if (graph.IsDirected)
            { // in a directed graph, there is more work to be done.
                var         toUpdateSet = new HashSet <uint>();
                List <uint> neighbours1 = null;
                if (reverse.TryGetValue(vertex1, out neighbours1))
                {
                    for (var i = 0; i < neighbours1.Count; i++)
                    {
                        if (neighbours1[i] == vertex2)
                        {
                            neighbours1[i] = vertex1;
                        }
                        else
                        {
                            toUpdateSet.Add(neighbours1[i]);
                        }
                    }
                    reverse[vertex1] = neighbours1;
                }
                List <uint> neighbours2 = null;
                if (reverse.TryGetValue(vertex2, out neighbours2))
                {
                    for (var i = 0; i < neighbours2.Count; i++)
                    {
                        if (neighbours2[i] == vertex1)
                        {
                            neighbours2[i] = vertex2;
                        }
                        else
                        {
                            toUpdateSet.Add(neighbours2[i]);
                        }
                    }
                    reverse[vertex2] = neighbours2;
                }

                // switch reverses.
                if (neighbours2 == null)
                {
                    reverse.Remove(vertex1);
                }
                else
                {
                    reverse[vertex1] = neighbours2;
                }
                if (neighbours1 == null)
                {
                    reverse.Remove(vertex2);
                }
                else
                {
                    reverse[vertex2] = neighbours1;
                }

                // update all edges in these vertices.
                var updatedEdges = new List <Edge <TEdgeData> >();
                foreach (var toUpdate in toUpdateSet)
                {
                    updatedEdges.Clear();

                    foreach (var edge in graph.GetEdges(toUpdate))
                    {
                        if (edge.Neighbour == vertex1)
                        {
                            updatedEdges.Add(new Edge <TEdgeData>()
                            {
                                EdgeData      = edge.EdgeData,
                                Neighbour     = vertex2,
                                Intermediates = edge.Intermediates != null ? new CoordinateArrayCollection <GeoCoordinateSimple>(
                                    edge.Intermediates.ToSimpleArray()) : null
                            });
                        }
                        else if (edge.Neighbour == vertex2)
                        {
                            updatedEdges.Add(new Edge <TEdgeData>()
                            {
                                EdgeData      = edge.EdgeData,
                                Neighbour     = vertex1,
                                Intermediates = edge.Intermediates != null ? new CoordinateArrayCollection <GeoCoordinateSimple>(
                                    edge.Intermediates.ToSimpleArray()) : null
                            });
                        }
                    }

                    graph.RemoveEdge(toUpdate, vertex1);
                    graph.RemoveEdge(toUpdate, vertex2);

                    foreach (var updatedEdge in updatedEdges)
                    {
                        graph.AddEdge(toUpdate, updatedEdge.Neighbour, updatedEdge.EdgeData, updatedEdge.Intermediates);
                    }
                }
            }
        }