Exemplo n.º 1
0
        /// <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();
        }