/// <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); }
/// <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); } }
/// <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); }