/// <summary> /// Compresses the graph by deleting vertices. /// </summary> private void CompressGraph() { // initialize status variables. uint vertex = 1; uint nextCompressedPosition = 1; // search edge until a real node. float latitude, longitude; float latestProgress = -1; while (vertex <= _graph.VertexCount) { var edges = _graph.GetEdges(vertex); if (edges != null && edges.Length > 0) { // ok, this vertex has edges. if (nextCompressedPosition != vertex) { // this vertex should go in another place. _graph.GetVertex(vertex, out latitude, out longitude); // set the next coordinates. _graph.SetVertex(nextCompressedPosition, latitude, longitude); // set the new edges. _graph.RemoveEdges(nextCompressedPosition); foreach (var edge in edges) { // add all arcs. if (edge.Key != vertex) { // this edge is not an edge that has the same end-start point. if (edge.Value.Forward) { _graph.AddEdge(nextCompressedPosition, edge.Key, edge.Value, null); } else { _graph.AddEdge(nextCompressedPosition, edge.Key, (LiveEdge)edge.Value.Reverse(), null); } } else { // this edge is an edge that has the same end-start point. _graph.AddEdge(nextCompressedPosition, nextCompressedPosition, edge.Value, null); } // update other arcs. if (edge.Key != vertex) { // do not update other arcs if other vertex is the same. var reverseEdges = _graph.GetEdges(edge.Key); if (reverseEdges != null) { // there are reverse edges, check if there is a reference to vertex. reverseEdges = reverseEdges.Clone() as KeyValuePair <uint, LiveEdge>[]; foreach (var reverseEdge in reverseEdges) { // check each edge for vertex. if (reverseEdge.Key == vertex) { // ok, replace this edge. GeoCoordinateSimple[] reverseEdgeCoordinates; if (!_graph.GetEdgeShape(edge.Key, reverseEdge.Key, out reverseEdgeCoordinates)) { reverseEdgeCoordinates = null; } _graph.RemoveEdge(edge.Key, vertex); if (reverseEdge.Value.Forward) { _graph.AddEdge(edge.Key, nextCompressedPosition, reverseEdge.Value, reverseEdgeCoordinates, null); } else { _graph.AddEdge(edge.Key, nextCompressedPosition, (LiveEdge)reverseEdge.Value.Reverse(), reverseEdgeCoordinates, null); } } } } } } } nextCompressedPosition++; } // move to the next vertex. vertex++; // report progress. float progress = (float)System.Math.Round((((double)vertex / (double)_graph.VertexCount) * 100)); if (progress != latestProgress) { OsmSharp.Logging.Log.TraceEvent("LiveEdgePreprocessor", TraceEventType.Information, "Compressing graph... {0}%", progress); latestProgress = progress; } } // remove all extra space. _graph.Compress(); _graph.Trim(); }