private int WriteToEdges(long pointer, VertexId vertex) { WriteToEdges(pointer, vertex.TileId); WriteToEdges(pointer + 4, vertex.LocalId); return(8); }
/// <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); }
internal Enumerator(Graph graph) { _forward = false; _firstEdge = true; _vertex = VertexId.Empty; _rawPointer = uint.MaxValue; _nextRawPointer = uint.MaxValue; _graph = graph; this.To = VertexId.Empty; }
/// <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); }
/// <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); }
/// <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); }
/// <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); }