Пример #1
0
        /// <summary>
        /// Returns a topologically sorted version of the given graph.
        /// </summary>
        /// <param name="graph"></param>
        /// <returns></returns>
        public IDynamicGraph <CHEdgeData> SortGraph(IDynamicGraph <CHEdgeData> graph)
        {
            // also add all downward edges.
            graph.AddDownwardEdges();

            // sort the topologically ordered vertices into bins representing a certain height range.
            List <uint>[] heightBins = new List <uint> [1000];
            foreach (var vertexDepth in new CHDepthFirstEnumerator(graph))
            { // enumerates all vertixes depth-first.
                int binIdx = (int)(vertexDepth.Depth / _heightBinSize);
                if (heightBins.Length < binIdx)
                { // resize bin array if needed.
                    Array.Resize(ref heightBins, System.Math.Max(heightBins.Length + 1000, binIdx + 1));
                }

                // add to the current bin.
                List <uint> bin = heightBins[binIdx];
                if (bin == null)
                { // create new bin.
                    bin = new List <uint>();
                    heightBins[binIdx] = bin;
                }
                bin.Add(vertexDepth.VertexId);
            }

            // temp test.
            MemoryDynamicGraph <CHEdgeData> sortedGraph   = new MemoryDynamicGraph <CHEdgeData>();
            Dictionary <uint, uint>         currentBinIds = new Dictionary <uint, uint>();
            uint newVertexId;

            for (int idx = 0; idx < heightBins.Length; idx++)
            {
                List <uint> bin = heightBins[idx];
                if (bin != null)
                { // translate ids.
                    // fill current bin ids and add vertices to the new graph.
                    foreach (uint binVertexId in bin)
                    {
                        float latitude, longitude;
                        graph.GetVertex(binVertexId, out latitude, out longitude);
                        newVertexId = sortedGraph.AddVertex(latitude, longitude);

                        currentBinIds.Add(binVertexId, newVertexId); // add to the current bin index.
                    }
                }
            }

            // rebuild the CH graph based on the new ordering and build the CHRegions.
            newVertexId = 0;
            for (int idx = 0; idx < heightBins.Length; idx++)
            {
                List <uint> bin = heightBins[idx];
                if (bin != null)
                { // translate ids.
                    foreach (uint binVertexId in bin)
                    {
                        currentBinIds.TryGetValue(binVertexId, out newVertexId);

                        // get the higher arcs and convert their ids.
                        //KeyValuePair<uint, CHEdgeData>[] arcs = graph.GetArcsHigher(binVertexId);
                        KeyValuePair <uint, CHEdgeData>[] arcs = graph.GetArcs(binVertexId);
                        foreach (KeyValuePair <uint, CHEdgeData> arc in arcs)
                        {
                            if (arc.Value.IsInformative || arc.Value.ToHigher)
                            {
                                // get target vertex.
                                uint nextVertexArcId = CHEdgeDataDataSourceSerializer.SearchVertex(arc.Key, currentBinIds, heightBins);
                                // convert edge.
                                CHEdgeData newEdge = new CHEdgeData();
                                newEdge.Direction = arc.Value.Direction;
                                if (arc.Value.HasContractedVertex)
                                { // contracted info.
                                    newEdge.ContractedVertexId = CHEdgeDataDataSourceSerializer.SearchVertex(arc.Value.ContractedVertexId, currentBinIds, heightBins);
                                }
                                else
                                { // no contracted info.
                                    newEdge.ContractedVertexId = 0;
                                }
                                newEdge.Tags   = arc.Value.Tags;
                                newEdge.Weight = arc.Value.Weight;
                                sortedGraph.AddArc(newVertexId, nextVertexArcId, newEdge, null);
                            }
                        }
                    }
                }
            }
            return(sortedGraph);
        }