Beispiel #1
0
 /// <summary>
 /// Relocates data internally in the most compact way possible.
 /// </summary>
 /// <param name="updateEdgeId">The edge id's may change. This action can be used to hook into every change.</param>
 public void Compress(Action <uint, uint> updateEdgeId)
 {
     _graph.Compress((originalId, newId) =>
     {
         updateEdgeId(originalId, newId);
         _shapes.Switch(originalId, newId);
     });
     _shapes.Resize(_graph.EdgeCount);
     _coordinates.Resize(_graph.VertexCapacity * 2);
 }
Beispiel #2
0
 /// <summary>
 /// Relocates data internally in the most compact way possible.
 /// </summary>
 /// <param name="updateEdgeId">The edge id's may change. This action can be used to hook into every change.</param>
 public void Compress(Action <uint, uint> updateEdgeId)
 {
     _graph.Compress((originalId, newId) =>
     {
         updateEdgeId(originalId, newId);
         _shapes.Switch(originalId, newId);
     });
     _shapes.Resize(_graph.EdgeCount);
     if (_coordinates.Length > _graph.VertexCapacity * 2)
     {
         _coordinates.Resize(_graph.VertexCapacity * 2);
     }
     if (_elevation != null && _elevation.Length > _graph.VertexCapacity)
     {
         _elevation?.Resize(_graph.VertexCapacity);
     }
 }
Beispiel #3
0
        /// <summary>
        /// Adds a new edge.
        /// </summary>
        /// <returns></returns>
        public uint AddEdge(uint vertex1, uint vertex2, uint[] data, ShapeBase shape)
        {
            var edgeId = _graph.AddEdge(vertex1, vertex2, data);

            if (edgeId >= _shapes.Length)
            { // increase coordinates length.
                var newBlocks = 1;
                while (edgeId >= _shapes.Length + (BLOCKSIZE * newBlocks))
                {
                    newBlocks++;
                }
                _shapes.Resize(_shapes.Length + (newBlocks * BLOCKSIZE));
            }

            _shapes[edgeId] = shape;
            return(edgeId);
        }
        /// <summary>
        /// Adds a new edge and it's inline data.
        /// </summary>
        /// <param name="vertex1">The first vertex.</param>
        /// <param name="vertex2">The second vertex.</param>
        /// <param name="data">The inline data.</param>
        /// <param name="shape">The edge shape.</param>
        /// <returns>The edge id.</returns>
        public uint AddEdge(VertexId vertex1, VertexId vertex2, IReadOnlyList <byte> data = null,
                            IEnumerable <Coordinate> shape = null)
        {
            // try to find vertex1.
            var(vertex1Pointer, capacity1) = FindTile(vertex1.TileId);
            if (vertex1Pointer == GraphConstants.TileNotLoaded ||
                vertex1.LocalId >= capacity1)
            {
                throw new ArgumentException($"{vertex1} does not exist.");
            }

            // try to find vertex2.
            var(vertex2Pointer, capacity2) = FindTile(vertex2.TileId);
            if (vertex2Pointer == GraphConstants.TileNotLoaded ||
                vertex2.LocalId >= capacity2)
            {
                throw new ArgumentException($"{vertex2} does not exist.");
            }

            // get edge pointers.
            var edgePointer1 = _edgePointers[vertex1Pointer + vertex1.LocalId];
            var edgePointer2 = _edgePointers[vertex2Pointer + vertex2.LocalId];

            // make sure there is enough space.
            var rawPointer = (_edgePointer * _edgeSize);

            if (rawPointer + _edgeSize > _edges.Length)
            {
                _edges.EnsureMinimumSize(rawPointer + _edgeSize);
            }

            // add edge pointers with new edge.
            rawPointer += WriteToEdges(rawPointer, vertex1);
            rawPointer += WriteToEdges(rawPointer, vertex2);
            // write pointer to previous edge.
            if (edgePointer1 == GraphConstants.NoEdges)
            { // if there is no previous edge, write 0
                rawPointer += WriteToEdges(rawPointer, 0);
            }
            else
            { // write pointer but offset by 1.
                rawPointer += WriteToEdges(rawPointer, edgePointer1 + 1);
            }
            // write pointer to previous edge.
            if (edgePointer2 == GraphConstants.NoEdges)
            { // if there is no previous edge, write 0
                rawPointer += WriteToEdges(rawPointer, 0);
            }
            else
            { // write pointer but offset by 1.
                rawPointer += WriteToEdges(rawPointer, edgePointer2 + 1);
            }
            rawPointer += WriteToEdges(rawPointer, data); // write data package.

            // update edge pointers.
            var newEdgePointer = _edgePointer;

            _edgePointers[vertex1Pointer + vertex1.LocalId] = newEdgePointer;
            _edgePointers[vertex2Pointer + vertex2.LocalId] = newEdgePointer;
            _edgePointer += 1;

            // add shape if any.
            if (shape != null)
            {
                if (_shapes.Length <= newEdgePointer)
                { // TODO: this resizing should be in the shapes array.
                    _shapes.Resize(newEdgePointer + 1024);
                }
                _shapes[newEdgePointer] = new ShapeEnumerable(shape);
            }

            return(newEdgePointer);
        }