Exemplo n.º 1
0
        /// <summary>
        /// Adds and arc to an existing vertex.
        /// </summary>
        /// <param name="from"></param>
        /// <param name="to"></param>
        /// <param name="data"></param>
        /// <param name="comparer">Comparator to compare edges and replace obsolete ones.</param>
        public void AddArc(uint from, uint to, TEdgeData data, IDynamicGraphEdgeComparer <TEdgeData> comparer)
        {
            if (_vertices.Length > from)
            {
                KeyValuePair <uint, TEdgeData>[] arcs =
                    _vertices[from];
                int idx = -1;
                if (arcs != null)
                {     // check for an existing edge first.
                    if (comparer != null)
                    { // there is no comparer, just skip this check.
                        for (int arcIdx = 0; arcIdx < arcs.Length; arcIdx++)
                        {
                            if (arcs[arcIdx].Key == to &&
                                comparer != null && comparer.Overlaps(data, arcs[arcIdx].Value))
                            { // an arc was found that represents the same directional information.
                                arcs[arcIdx] = new KeyValuePair <uint, TEdgeData>(
                                    to, data);
                                return;
                            }
                        }
                    }

                    // if here: there did not exist an edge yet!
                    idx = arcs.Length;
                    Array.Resize <KeyValuePair <uint, TEdgeData> >(ref arcs, arcs.Length + 1);
                    _vertices[from] = arcs;
                }
                else
                { // create an arcs array.
                    arcs            = new KeyValuePair <uint, TEdgeData> [1];
                    idx             = 0;
                    _vertices[from] = arcs;
                }

                // set the arc.
                arcs[idx] = new KeyValuePair <uint, TEdgeData>(
                    to, data);

                return;
            }
            throw new ArgumentOutOfRangeException("from");
        }
Exemplo n.º 2
0
        /// <summary>
        /// Adds an edge with the associated data.
        /// </summary>
        /// <param name="vertex1"></param>
        /// <param name="vertex2"></param>
        /// <param name="data"></param>
        /// <param name="coordinates"></param>
        /// <param name="comparer">Comparator to compare edges and replace obsolete ones.</param>
        public void AddEdge(uint vertex1, uint vertex2, TEdgeData data, GeoCoordinateSimple[] coordinates, IDynamicGraphEdgeComparer <TEdgeData> comparer)
        {
            // if (!data.Forward) { throw new ArgumentOutOfRangeException("data", "Edge data has to be forward."); }

            if (vertex1 == vertex2)
            {
                throw new ArgumentException("Given vertices must be different.");
            }
            if (_nextVertexId <= vertex1)
            {
                throw new ArgumentOutOfRangeException("vertex1", "vertex1 is not part of this graph.");
            }
            if (_nextVertexId <= vertex2)
            {
                throw new ArgumentOutOfRangeException("vertex2", "vertex2 is not part of this graph.");
            }

            var edgeId = _vertices[vertex1];

            if (_vertices[vertex1] != NO_EDGE)
            { // check for an existing edge first.
                // check if the arc exists already.
                edgeId = _vertices[vertex1];
                uint nextEdgeSlot = 0;
                while (edgeId != NO_EDGE)
                { // keep looping.
                    uint otherVertexId  = 0;
                    uint previousEdgeId = edgeId;
                    bool forward        = true;
                    if (_edges[edgeId + NODEA] == vertex1)
                    {
                        otherVertexId = _edges[edgeId + NODEB];
                        nextEdgeSlot  = edgeId + NEXTNODEA;
                        edgeId        = _edges[edgeId + NEXTNODEA];
                    }
                    else
                    {
                        otherVertexId = _edges[edgeId + NODEA];
                        nextEdgeSlot  = edgeId + NEXTNODEB;
                        edgeId        = _edges[edgeId + NEXTNODEB];
                        forward       = false;
                    }
                    if (otherVertexId == vertex2)
                    { // this is the edge we need.
                        if (!forward)
                        {
                            data = (TEdgeData)data.Reverse();
                        }
                        if (comparer != null)
                        { // there is a comparer.
                            var existingData = _edgeData[previousEdgeId / 4];
                            if (comparer.Overlaps(data, existingData))
                            { // an arc was found that represents the same directional information.
                                _edgeData[previousEdgeId / 4]   = data;
                                _edgeShapes[previousEdgeId / 4] = coordinates;
                            }
                            return;
                        }
                        _edgeData[previousEdgeId / 4]   = data;
                        _edgeShapes[previousEdgeId / 4] = coordinates;
                        return;
                    }
                }

                // create a new edge.
                edgeId = _nextEdgeId;
                if (_nextEdgeId + NEXTNODEB >= _edges.Length)
                { // there is a need to increase edges array.
                    this.IncreaseEdgeSize();
                }
                _edges[_nextEdgeId + NODEA]     = vertex1;
                _edges[_nextEdgeId + NODEB]     = vertex2;
                _edges[_nextEdgeId + NEXTNODEA] = NO_EDGE;
                _edges[_nextEdgeId + NEXTNODEB] = NO_EDGE;
                _nextEdgeId = _nextEdgeId + EDGE_SIZE;

                // append the new edge to the from list.
                _edges[nextEdgeSlot] = edgeId;

                // set data.
                _edgeData[edgeId / 4]   = data;
                _edgeShapes[edgeId / 4] = coordinates;
            }
            else
            { // create a new edge and set.
                edgeId             = _nextEdgeId;
                _vertices[vertex1] = _nextEdgeId;

                if (_nextEdgeId + NEXTNODEB >= _edges.Length)
                { // there is a need to increase edges array.
                    this.IncreaseEdgeSize();
                }
                _edges[_nextEdgeId + NODEA]     = vertex1;
                _edges[_nextEdgeId + NODEB]     = vertex2;
                _edges[_nextEdgeId + NEXTNODEA] = NO_EDGE;
                _edges[_nextEdgeId + NEXTNODEB] = NO_EDGE;
                _nextEdgeId = _nextEdgeId + EDGE_SIZE;

                // set data.
                _edgeData[edgeId / 4]   = data;
                _edgeShapes[edgeId / 4] = coordinates;
            }

            var toEdgeId = _vertices[vertex2];

            if (toEdgeId != NO_EDGE)
            { // there are existing edges.
                uint nextEdgeSlot = 0;
                while (toEdgeId != NO_EDGE)
                { // keep looping.
                    uint otherVertexId = 0;
                    if (_edges[toEdgeId + NODEA] == vertex2)
                    {
                        otherVertexId = _edges[toEdgeId + NODEB];
                        nextEdgeSlot  = toEdgeId + NEXTNODEA;
                        toEdgeId      = _edges[toEdgeId + NEXTNODEA];
                    }
                    else
                    {
                        otherVertexId = _edges[toEdgeId + NODEA];
                        nextEdgeSlot  = toEdgeId + NEXTNODEB;
                        toEdgeId      = _edges[toEdgeId + NEXTNODEB];
                    }
                }
                _edges[nextEdgeSlot] = edgeId;
            }
            else
            { // there are no existing edges point the vertex straight to it's first edge.
                _vertices[vertex2] = edgeId;
            }

            return;
        }