示例#1
0
        /// <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());
            }
        }