Ejemplo n.º 1
0
        private int WriteToEdges(long pointer, VertexId vertex)
        {
            WriteToEdges(pointer, vertex.TileId);
            WriteToEdges(pointer + 4, vertex.LocalId);

            return(8);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Tries to get the given vertex.
        /// </summary>
        /// <param name="vertex">The vertex.</param>
        /// <param name="location">The location of the vertex.</param>
        /// <returns>The vertex.</returns>
        public bool TryGetVertex(VertexId vertex, out Coordinate location)
        {
            var localTileId = vertex.TileId;

            // try to find the tile.
            var(vertexPointer, capacity) = FindTile(localTileId);
            if (vertexPointer == GraphConstants.TileNotLoaded)
            {
                location = default;
                return(false);
            }

            if (vertex.LocalId >= capacity)
            {
                location = default;
                return(false);
            }

            var tile = Tile.FromLocalId(localTileId, _zoom);

            if (!TryGetEncodedVertex(vertexPointer + vertex.LocalId, tile, out location))
            {
                return(false);
            }
            return(true);
        }
Ejemplo n.º 3
0
            internal Enumerator(Graph graph)
            {
                _forward        = false;
                _firstEdge      = true;
                _vertex         = VertexId.Empty;
                _rawPointer     = uint.MaxValue;
                _nextRawPointer = uint.MaxValue;
                _graph          = graph;

                this.To = VertexId.Empty;
            }
Ejemplo n.º 4
0
            /// <summary>
            /// Moves the enumerator to the first edge of the given vertex.
            /// </summary>
            /// <param name="vertex">The vertex.</param>
            /// <returns>True if the vertex exists.</returns>
            public bool MoveTo(VertexId vertex)
            {
                _firstEdge      = true;
                _forward        = false;
                _vertex         = vertex;
                _rawPointer     = uint.MaxValue;
                _nextRawPointer = uint.MaxValue;

                // try to find vertex.
                var(vertex1Pointer, capacity1) = _graph.FindTile(vertex.TileId);
                if (vertex1Pointer == GraphConstants.TileNotLoaded ||
                    vertex.LocalId >= capacity1)
                {
                    return(false);
                }

                // get edge pointer.
                var edgePointer = _graph._edgePointers[vertex1Pointer + vertex.LocalId];

                // set the raw pointer if there is data.
                if (edgePointer == GraphConstants.NoEdges)
                {
                    _rawPointer = GraphConstants.NoEdges;
                }
                else if (edgePointer == uint.MaxValue)
                {
                    // try to find vertex again, tile was moved?.
                    (vertex1Pointer, capacity1) = _graph.FindTile(vertex.TileId);
                    if (vertex1Pointer == GraphConstants.TileNotLoaded ||
                        vertex.LocalId >= capacity1)
                    {
                        return(false);
                    }

                    // get edge pointer.
                    edgePointer = _graph._edgePointers[vertex1Pointer + vertex.LocalId];
                }
                else
                {
                    _rawPointer = (uint)(edgePointer * _graph._edgeSize);
                }

                return(true);
            }
Ejemplo n.º 5
0
        /// <summary>
        /// Gets the given vertex.
        /// </summary>
        /// <param name="vertex">The vertex.</param>
        /// <returns>The vertex.</returns>
        public Coordinate GetVertex(VertexId vertex)
        {
            var localTileId = vertex.TileId;

            // try to find the tile.
            var(vertexPointer, capacity) = FindTile(localTileId);
            if (vertexPointer == GraphConstants.TileNotLoaded)
            {
                throw new ArgumentException($"{vertex} does not exist.");
            }
            if (vertex.LocalId >= capacity)
            {
                throw new ArgumentException($"{vertex} does not exist.");
            }

            var tile = Tile.FromLocalId(localTileId, _zoom);

            if (!TryGetEncodedVertex(vertexPointer + vertex.LocalId, tile, out var location))
            {
                throw new ArgumentException($"{vertex} does not exist.");
            }
            return(location);
        }
Ejemplo n.º 6
0
            /// <summary>
            /// Moves the enumerator to the given edge.
            /// </summary>
            /// <param name="edgeId">The edge id.</param>
            /// <param name="forward">The forward flag, when false the enumerator is in a state as it was enumerated to the edge via its last vertex. When true the enumerator is in a state as it was enumerated to the edge via its first vertex.</param>
            public bool MoveToEdge(uint edgeId, bool forward = true)
            {
                _forward        = false;
                _vertex         = VertexId.Empty;
                _rawPointer     = uint.MaxValue;
                _nextRawPointer = uint.MaxValue;

                // build raw edge pointer.
                _rawPointer = (uint)(edgeId * _graph._edgeSize);
                if (_graph._edges.Length <= _rawPointer)
                {
                    _rawPointer = uint.MaxValue;
                    return(false);
                }

                // set the state of the enumerator.
                if (forward)
                {
                    _firstEdge = false;
                    _vertex    = _graph.ReadFromEdgeVertexId(_rawPointer);
                    var vertex2 = _graph.ReadFromEdgeVertexId(_rawPointer + 8);
                    _forward        = true;
                    this.To         = vertex2;
                    _nextRawPointer = (uint)((_graph.ReadFromEdgeUInt32(_rawPointer + 16) - 1) * _graph._edgeSize);
                }
                else
                {
                    _firstEdge = false;
                    _vertex    = _graph.ReadFromEdgeVertexId(_rawPointer + 8);
                    var vertex2 = _graph.ReadFromEdgeVertexId(_rawPointer);
                    _forward        = false;
                    this.To         = vertex2;
                    _nextRawPointer = (uint)((_graph.ReadFromEdgeUInt32(_rawPointer + 16 + 4) - 1) * _graph._edgeSize);
                }

                return(true);
            }
Ejemplo n.º 7
0
        /// <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);
        }