コード例 #1
0
ファイル: SparseOrdering.cs プロジェクト: detlevn/OsmSharp
        /// <summary>
        /// Calculates the ordering.
        /// </summary>
        /// <param name="vertex"></param>
        /// <returns></returns>
        public float Calculate(uint vertex)
        {
            var neighbours = _data.GetEdges(vertex);

            // check the proper conditions.
            if (neighbours.Length == 2)
            {
                return(-1);
            }
            return(float.MaxValue);
        }
コード例 #2
0
        /// <summary>
        /// Moves to the next item.
        /// </summary>
        /// <returns></returns>
        public bool MoveNext()
        {
            if (_current == null)
            {
                _current = this.FindHighest();
                _index.Add(_current.Vertex);
                _currentCount = 1;
                return(_current != null);
            }

            // search for the next arc.
            KeyValuePair <uint, CHEdgeData>[] edges = _graph.GetEdges(_current.Vertex);
            int arcIdx = _current.ArcIdx;

            arcIdx++;
            while (arcIdx < edges.Length)
            { // check if it is 'lower'.
                if (edges[arcIdx].Value.ToLower &&
                    !_index.Contains(edges[arcIdx].Key))
                {                             // yes the arc is 'lower' take it!
                    _current.ArcIdx = arcIdx; // move the arcIdx.

                    Position newPosition = new Position();
                    newPosition.Parent = _current;
                    newPosition.ArcIdx = -1;
                    newPosition.Vertex = edges[arcIdx].Key;
                    newPosition.Depth  = _current.Depth + 1;
                    _current           = newPosition;

                    _index.Add(_current.Vertex);
                    _currentCount++;
                    return(true);
                }
                arcIdx++; // move to the next arc.
            }

            // move to parent.
            if (_current.Parent != null)
            { // set parent as current and move next.
                _current = _current.Parent;
                return(this.MoveNext());
            }

            // also enumerate all the other 'islands' of vertices unconnected to the current vertices.
            return(this.MoveToNextIsland());
        }
コード例 #3
0
        /// <summary>
        /// Returns the arcs that point to lower vertices.
        /// </summary>
        /// <param name="graph"></param>
        /// <param name="vertexId"></param>
        /// <returns></returns>
        public static KeyValuePair <uint, CHEdgeData>[] GetArcsLower(this IDynamicGraph <CHEdgeData> graph,
                                                                     uint vertexId)
        {
            KeyValuePair <uint, CHEdgeData>[] arcs       = graph.GetEdges(vertexId);
            KeyValuePair <uint, CHEdgeData>[] higherArcs = new KeyValuePair <uint, CHEdgeData> [arcs.Length];
            int higherIdx = 0;

            for (int idx = 0; idx < arcs.Length; idx++)
            {
                if (!arcs[idx].Value.ToHigher)
                {
                    higherArcs[higherIdx] = arcs[idx];
                    higherIdx++;
                }
            }
            Array.Resize(ref higherArcs, higherIdx);
            return(higherArcs);
        }
コード例 #4
0
        /// <summary>
        /// Starts pre-processing all nodes.
        /// </summary>
        public void Start()
        {
            // build the empty coordinate list.
            var emptyCoordinateList = new GeoCoordinateSimple[0];
            var verticesList        = new HashSet <uint>();

            // initialize status variables.
            uint nextToProcess = 0;
            uint nextPosition  = 0;

            // search edge until a real node.
            double latestProgress = 0;

            while (nextToProcess < _graph.VertexCount)
            { // keep looping until all vertices have been processed.
                // select a new vertext to select.
                var vertexToProcess = nextToProcess;
                var edges           = _graph.GetEdges(vertexToProcess);
                if (edges.Length == 2)
                { // find one of the neighbours that is usefull.
                    vertexToProcess = edges[0].Key;
                    edges           = _graph.GetEdges(vertexToProcess);
                    verticesList.Clear();
                    verticesList.Add(vertexToProcess);
                    while (edges.Length == 2)
                    { // keep looping until there is a vertex that is usefull.
                        vertexToProcess = edges[0].Key;
                        if (verticesList.Contains(vertexToProcess))
                        { // take the other vertex.
                            vertexToProcess = edges[1].Key;
                            if (verticesList.Contains(vertexToProcess))
                            { // an island was detected with only vertices having two neighbours.
                                // TODO: find a way to handle this!
                                edges = new KeyValuePair <uint, LiveEdge> [0];
                                break;
                            }
                        }
                        verticesList.Add(vertexToProcess);
                        edges = _graph.GetEdges(vertexToProcess);
                    }
                }
                if (edges.Length > 0)
                { // ok, the vertex was not already processed.
                    nextPosition++;
                    var oldEdges   = edges.Clone() as KeyValuePair <uint, LiveEdge>[];
                    var ignoreList = new HashSet <uint>();
                    foreach (var oldEdge in oldEdges)
                    {
                        if (ignoreList.Contains(oldEdge.Key))
                        { // ignore this edge: already removed in a previous iteration.
                            break;
                        }

                        // don't re-process edges that already have coordinates.
                        GeoCoordinateSimple[] oldEdgeValueCoordinates;
                        _graph.GetEdgeShape(vertexToProcess, oldEdge.Key, out oldEdgeValueCoordinates);
                        if (oldEdgeValueCoordinates != null)
                        { // this edge has already been processed.
                            break;
                        }

                        // STEP1: Build list of vertices that are only for form.

                        // set current/previous.
                        var distance = oldEdge.Value.Distance;
                        var current  = oldEdge.Key;
                        var previous = vertexToProcess;

                        // build list of vertices.
                        var vertices = new List <uint>();
                        vertices.Add(previous);
                        vertices.Add(current);

                        // get next edges list.
                        var nextEdges = _graph.GetEdges(current);
                        while (nextEdges.Length == 2)
                        { // ok the current vertex can be removed.
                            var nextEdge = nextEdges[0];
                            if (nextEdge.Key == previous)
                            { // it's the other edge!
                                nextEdge = nextEdges[1];
                            }

                            // compare edges.
                            if (nextEdge.Value.Forward != oldEdge.Value.Forward ||
                                nextEdge.Value.Tags != oldEdge.Value.Tags)
                            { // oeps, edges are different!
                                break;
                            }

                            // check for intermediates.
                            GeoCoordinateSimple[] nextEdgeValueCoordinates;
                            _graph.GetEdgeShape(current, nextEdge.Key, out nextEdgeValueCoordinates);
                            if (nextEdgeValueCoordinates != null)
                            { // oeps, there are intermediates already, this can occur when two osm-ways are drawn on top of eachother.
                                break;
                            }

                            // add distance.
                            distance = distance + nextEdge.Value.Distance;

                            // set current/previous.
                            previous = current;
                            current  = nextEdge.Key;
                            vertices.Add(current);

                            // get next edges.
                            nextEdges = _graph.GetEdges(current);
                        }

                        // check if the edge contains intermediate points.
                        if (vertices.Count == 2)
                        { // no intermediate points: add the empty coordinate list.
                            var oldEdgeValue = oldEdge.Value;

                            // keep edges that already have intermediates.
                            GeoCoordinateSimple[] edgeToKeepValueCoordinates = null;
                            var edgesToKeep = new List <Tuple <uint, LiveEdge, GeoCoordinateSimple[]> >();
                            foreach (var edgeToKeep in _graph.GetEdges(vertexToProcess))
                            {
                                edgeToKeepValueCoordinates = null;
                                if (edgeToKeep.Key == oldEdge.Key &&
                                    _graph.GetEdgeShape(vertexToProcess, edgeToKeep.Key, out edgeToKeepValueCoordinates))
                                {
                                    edgesToKeep.Add(new Tuple <uint, LiveEdge, GeoCoordinateSimple[]>(
                                                        edgeToKeep.Key, edgeToKeep.Value, edgeToKeepValueCoordinates));
                                }
                            }

                            // delete olds arcs.
                            _graph.RemoveEdge(vertexToProcess, oldEdge.Key);

                            // add new arc.
                            if (oldEdgeValue.Forward)
                            {
                                _graph.AddEdge(vertexToProcess, oldEdge.Key, oldEdgeValue, null);
                            }
                            else
                            {
                                _graph.AddEdge(vertexToProcess, oldEdge.Key, (LiveEdge)oldEdgeValue.Reverse(), null);
                            }

                            // add edges to keep.
                            foreach (var edgeToKeep in edgesToKeep)
                            {
                                _graph.AddEdge(vertexToProcess, edgeToKeep.Item1, edgeToKeep.Item2, edgeToKeep.Item3);
                            }
                        }
                        else
                        { // intermediate points: build array.
                            // STEP2: Build array of coordinates.
                            var   coordinates = new GeoCoordinateSimple[vertices.Count - 2];
                            float latitude, longitude;
                            for (int idx = 1; idx < vertices.Count - 1; idx++)
                            {
                                _graph.GetVertex(vertices[idx], out latitude, out longitude);
                                coordinates[idx - 1] = new GeoCoordinateSimple()
                                {
                                    Latitude  = latitude,
                                    Longitude = longitude
                                };
                            }

                            // STEP3: Remove all unneeded edges.
                            _graph.RemoveEdge(vertices[0], vertices[1]); // remove first edge.
                            for (int idx = 1; idx < vertices.Count - 1; idx++)
                            {                                            // delete all intermidiate arcs.
                                _graph.RemoveEdges(vertices[idx]);
                            }
                            _graph.RemoveEdge(vertices[vertices.Count - 1], vertices[vertices.Count - 2]); // remove last edge.
                            if (vertices[0] == vertices[vertices.Count - 1])
                            {                                                                              // also remove outgoing edge.
                                ignoreList.Add(vertices[vertices.Count - 2]);                              // make sure this arc is ignored in next iteration.
                            }

                            // STEP4: Add new edge.
                            if (oldEdge.Value.Forward)
                            {
                                _graph.AddEdge(vertices[0], vertices[vertices.Count - 1], new LiveEdge()
                                {
                                    Forward  = oldEdge.Value.Forward,
                                    Tags     = oldEdge.Value.Tags,
                                    Distance = distance
                                }, coordinates, this);
                            }
                            else
                            {
                                var reverse = new GeoCoordinateSimple[coordinates.Length];
                                coordinates.CopyToReverse(reverse, 0);
                                _graph.AddEdge(vertices[vertices.Count - 1], vertices[0], new LiveEdge()
                                {
                                    Forward  = !oldEdge.Value.Forward,
                                    Tags     = oldEdge.Value.Tags,
                                    Distance = distance
                                }, reverse, this);
                            }
                        }
                    }
                }
                // move to the next position.
                nextToProcess++;

                // report progress.
                float progress = (float)System.Math.Round((((double)nextToProcess / (double)_graph.VertexCount) * 100));
                if (progress != latestProgress)
                {
                    OsmSharp.Logging.Log.TraceEvent("LiveEdgePreprocessor", TraceEventType.Information,
                                                    "Removing edges... {0}%", progress);
                    latestProgress = progress;
                }
            }

            // compress the graph.
            this.CompressGraph();
        }
コード例 #5
0
 /// <summary>
 /// Returns all arcs starting at a given vertex.
 /// </summary>
 /// <param name="vertexId"></param>
 /// <returns></returns>
 public KeyValuePair <uint, TEdgeData>[] GetEdges(uint vertexId)
 {
     return(_graph.GetEdges(vertexId));
 }
コード例 #6
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.
            var 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.
                var bin = heightBins[binIdx];
                if (bin == null)
                { // create new bin.
                    bin = new List <uint>();
                    heightBins[binIdx] = bin;
                }
                bin.Add(vertexDepth.VertexId);
            }

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

            for (int idx = 0; idx < heightBins.Length; idx++)
            {
                var 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++)
            {
                var 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.GetEdges(binVertexId);
                        foreach (KeyValuePair <uint, CHEdgeData> arc in arcs)
                        {
                            // get target vertex.
                            uint nextVertexArcId = CHEdgeDataDataSourceSerializer.SearchVertex(arc.Key, currentBinIds, heightBins);
                            // convert edge.
                            var 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.AddEdge(newVertexId, nextVertexArcId, newEdge, null);
                        }
                    }
                }
            }
            return(sortedGraph);
        }