/// <summary> /// Compresses the data in this graph to it's smallest size. /// </summary> /// <param name="toReadonly">Flag to make the graph even smaller by converting it to a readonly version.</param> public void Compress(bool toReadonly) { if (toReadonly) { if (_readonly) { throw new Exception("Graph is readonly."); } // copy everything in a better structure after the last edge. var offset = _nextEdgeId; var nextEdgeId = _nextEdgeId; for (int vertex = 2; vertex < _nextVertexId * VERTEX_SIZE; vertex = vertex + 2) { // assume vertices are sorted correctly. var newEdge = nextEdgeId; // move edges. for (uint oldEdgeId = _vertices[vertex + FIRST_EDGE]; oldEdgeId < _vertices[vertex + EDGE_COUNT] + _vertices[vertex + FIRST_EDGE]; oldEdgeId++) { if (nextEdgeId + 1 >= _edges.Length) { // edges need to be increased. this.IncreaseEdgeSize(); } _edges[nextEdgeId] = _edges[oldEdgeId]; _edgeData[nextEdgeId] = _edgeData[oldEdgeId]; _edgeShapes[nextEdgeId] = _edgeShapes[oldEdgeId]; nextEdgeId++; } // update vertex. _vertices[vertex + FIRST_EDGE] = newEdge - offset; } // copy everything back to the beginning. for (uint edgeId = 0; edgeId < nextEdgeId - _nextEdgeId; edgeId++) { _edges[edgeId] = _edges[edgeId + offset]; _edgeData[edgeId] = _edgeData[edgeId + offset]; _edgeShapes[edgeId] = _edgeShapes[edgeId + offset]; } _nextEdgeId = nextEdgeId - _nextEdgeId; // ... and trim. this.Trim(); // ... compress the coordinates index. _edgeShapes.Compress(); // ... last, but not least, set readonly flag. _readonly = true; } }
public void TestSerialize() { OsmSharp.Math.Random.StaticRandomGenerator.Set(116542346); var box = new GeoCoordinateBox( new GeoCoordinate(90, 180), new GeoCoordinate(-90, -180)); var size = 5; var maxCollectionSize = 4; var referenceDictionary = new Dictionary <long, ICoordinateCollection>(); var coordinates = new HugeCoordinateCollectionIndex(100); for (int idx = 0; idx < size; idx++) { var currentSize = OsmSharp.Math.Random.StaticRandomGenerator.Get().Generate(maxCollectionSize) + 1; var coordinatesArray = new GeoCoordinate[currentSize]; while (currentSize > 0) { coordinatesArray[currentSize - 1] = box.GenerateRandomIn(OsmSharp.Math.Random.StaticRandomGenerator.Get()); currentSize--; } var coordinatesCollection = new CoordinateArrayCollection <GeoCoordinate>(coordinatesArray); referenceDictionary[idx] = coordinatesCollection; coordinates[idx] = coordinatesCollection; } coordinates.Trim(); coordinates.Compress(); byte[] data = null; using (var stream = new MemoryStream()) { long length = coordinates.Serialize(stream); data = stream.ToArray(); Assert.AreEqual(168, length); Assert.AreEqual(data.Length, length); } var result = HugeCoordinateCollectionIndex.Deserialize(new MemoryStream(data)); // check result. for (int idx = 0; idx < size; idx++) { var referenceCollection = referenceDictionary[idx]; var collection = result[idx]; referenceCollection.Reset(); collection.Reset(); while (referenceCollection.MoveNext()) { Assert.IsTrue(collection.MoveNext()); Assert.AreEqual(referenceCollection.Latitude, collection.Latitude); Assert.AreEqual(referenceCollection.Longitude, collection.Longitude); } Assert.IsFalse(collection.MoveNext()); } result = HugeCoordinateCollectionIndex.Deserialize(new MemoryStream(data), true); // check result. for (int idx = 0; idx < size; idx++) { var referenceCollection = referenceDictionary[idx]; var collection = result[idx]; referenceCollection.Reset(); collection.Reset(); while (referenceCollection.MoveNext()) { Assert.IsTrue(collection.MoveNext()); Assert.AreEqual(referenceCollection.Latitude, collection.Latitude); Assert.AreEqual(referenceCollection.Longitude, collection.Longitude); } Assert.IsFalse(collection.MoveNext()); } }