/// <summary> /// Serializes the given scene. /// </summary> /// <param name="stream"></param> /// <param name="scene"></param> /// <param name="compress"></param> public static void Serialize(Stream stream, TagsCollectionBase metaTags, Scene2D scene, bool compress) { RuntimeTypeModel typeModel = SceneSerializer.BuildRuntimeTypeModel(); // [MetaIndexLenght:4][Metadata][SeneIndexLength:4][SceneIndex][SceneLengths:4*zoomFactors.length][Scenes] // MetaIndexLenght: int The lenght of the meta index. // Metadata: a number of serialized tags. // SceneIndexLength: int The length of the sceneindex in bytes. // SceneIndex: the serialized scene index. // SceneLengths: int[] The lengths of the scenes per zoom level as in the zoomfactors array. // Scenes: The serialized scenes themselves. // serialize meta tags. byte[] tagsBytes = (new TagsCollectionSerializer()).Serialize(metaTags); stream.Write(BitConverter.GetBytes(tagsBytes.Length), 0, 4); stream.Write(tagsBytes, 0, tagsBytes.Length); // index index. SceneIndex sceneIndex = new SceneIndex(); sceneIndex.LineStyles = scene.GetStyleLines(); sceneIndex.PointStyles = scene.GetStylePoints(); sceneIndex.PolygonStyles = scene.GetStylePolygons(); sceneIndex.TextStyles = scene.GetStyleTexts(); sceneIndex.ZoomRanges = scene.GetZoomRanges(); sceneIndex.ZoomFactors = scene.GetZoomFactors(); sceneIndex.IconImage = scene.GetImages(); // write SceneIndex long positionAfterMeta = stream.Position; stream.Seek(positionAfterMeta + 4, SeekOrigin.Begin); long indexStart = stream.Position; typeModel.Serialize(stream, sceneIndex); // write SeneIndexLength int indexSize = (int)(stream.Position - indexStart); stream.Seek(positionAfterMeta + 0, SeekOrigin.Begin); stream.Write(BitConverter.GetBytes(indexSize), 0, 4); // write Scenes. stream.Seek(positionAfterMeta + 4 + indexSize + 4 * sceneIndex.ZoomFactors.Length, SeekOrigin.Begin); // index into r-trees and serialize. int[] lengths = new int[sceneIndex.ZoomFactors.Length]; for (int idx = 0; idx < lengths.Length; idx++) { long position = stream.Position; Dictionary <uint, SceneObject> sceneAtZoom = scene.GetObjectsAt(idx); RTreeMemoryIndex <SceneObject> memoryIndex = new RTreeMemoryIndex <SceneObject>(); float latestProgress = 0; int sceneObjectIdx = 0; foreach (KeyValuePair <uint, SceneObject> sceneObjectPair in sceneAtZoom) { // loop over all primitives in order. SceneObject sceneObject = sceneObjectPair.Value; uint id = sceneObjectPair.Key; switch (sceneObject.Enum) { case SceneObjectType.IconObject: case SceneObjectType.PointObject: case SceneObjectType.TextObject: OsmSharp.UI.Renderer.Scene.Scene2D.ScenePoint geo = scene.GetPoint(sceneObject.GeoId); PointF2D point = new PointF2D(geo.X, geo.Y); memoryIndex.Add(new BoxF2D(point), sceneObject); break; case SceneObjectType.LineObject: case SceneObjectType.LineTextObject: case SceneObjectType.PolygonObject: OsmSharp.UI.Renderer.Scene.Scene2D.ScenePoints geos = scene.GetPoints(sceneObject.GeoId); memoryIndex.Add(new BoxF2D(geos.X, geos.Y), sceneObject); break; } float progress = (float)System.Math.Round((((double)sceneObjectIdx / (double)sceneAtZoom.Count) * 100)); if (progress != latestProgress) { OsmSharp.Logging.Log.TraceEvent("SceneSerializer", OsmSharp.Logging.TraceEventType.Information, "Indexing scene objects at zoom {1} ({2}/{3})... {0}%", progress, sceneIndex.ZoomFactors[idx], sceneObjectIdx, sceneAtZoom.Count); latestProgress = progress; } sceneObjectIdx++; } // serialize the r-tree. OsmSharp.Logging.Log.TraceEvent("SceneSerializer", OsmSharp.Logging.TraceEventType.Information, "Serializing RTRee..."); SceneObjectRTreeSerializer memoryIndexSerializer = new SceneObjectRTreeSerializer( scene, compress, idx, SceneSerializer.CalculateScaleFactor(sceneIndex.ZoomFactors[idx])); memoryIndexSerializer.Serialize(new LimitedStream(stream), memoryIndex); lengths[idx] = (int)(stream.Position - position); } // write SceneLengths long end = stream.Position; stream.Seek(positionAfterMeta + 4 + indexSize, SeekOrigin.Begin); for (int idx = 0; idx < lengths.Length; idx++) { stream.Write(BitConverter.GetBytes(lengths[idx]), 0, 4); } stream.Seek(end, SeekOrigin.Begin); }
/// <summary> /// Serializes the given scene. /// </summary> /// <param name="stream"></param> /// <param name="scene"></param> /// <param name="compress"></param> public static void Serialize(Stream stream, TagsCollectionBase metaTags, Scene2D scene, bool compress) { RuntimeTypeModel typeModel = SceneSerializer.BuildRuntimeTypeModel(); // [MetaIndexLenght:4][Metadata][SeneIndexLength:4][SceneIndex][SceneLengths:4*zoomFactors.length][Scenes] // MetaIndexLenght: int The lenght of the meta index. // Metadata: a number of serialized tags. // SceneIndexLength: int The length of the sceneindex in bytes. // SceneIndex: the serialized scene index. // SceneLengths: int[] The lengths of the scenes per zoom level as in the zoomfactors array. // Scenes: The serialized scenes themselves. // serialize meta tags. (new TagsCollectionSerializer()).SerializeWithSize(metaTags, stream); // index index. SceneIndex sceneIndex = new SceneIndex(); sceneIndex.LineStyles = scene.GetStyleLines(); sceneIndex.PointStyles = scene.GetStylePoints(); sceneIndex.PolygonStyles = scene.GetStylePolygons(); sceneIndex.TextStyles = scene.GetStyleTexts(); sceneIndex.ZoomRanges = scene.GetZoomRanges(); sceneIndex.ZoomFactors = scene.GetZoomFactors(); sceneIndex.IconImage = scene.GetImages(); // write SceneIndex long positionAfterMeta = stream.Position; stream.Seek(positionAfterMeta + 4, SeekOrigin.Begin); long indexStart = stream.Position; typeModel.Serialize(stream, sceneIndex); // write SeneIndexLength int indexSize = (int)(stream.Position - indexStart); stream.Seek(positionAfterMeta + 0, SeekOrigin.Begin); stream.Write(BitConverter.GetBytes(indexSize), 0, 4); // write Scenes. stream.Seek(positionAfterMeta + 4 + indexSize + 4 * sceneIndex.ZoomFactors.Length, SeekOrigin.Begin); // index into r-trees and serialize. int[] lengths = new int[sceneIndex.ZoomFactors.Length]; for (int idx = 0; idx < lengths.Length; idx++) { long position = stream.Position; Dictionary<uint, SceneObject> sceneAtZoom = scene.GetObjectsAt(idx); RTreeMemoryIndex<SceneObject> memoryIndex = new RTreeMemoryIndex<SceneObject>(50, 100); float latestProgress = 0; int sceneObjectIdx = 0; foreach (KeyValuePair<uint, SceneObject> sceneObjectPair in sceneAtZoom) { // loop over all primitives in order. SceneObject sceneObject = sceneObjectPair.Value; uint id = sceneObjectPair.Key; switch (sceneObject.Enum) { case SceneObjectType.IconObject: case SceneObjectType.PointObject: case SceneObjectType.TextObject: OsmSharp.UI.Renderer.Scene.Scene2D.ScenePoint geo = scene.GetPoint(sceneObject.GeoId); PointF2D point = new PointF2D(geo.X, geo.Y); memoryIndex.Add(new BoxF2D(point), sceneObject); break; case SceneObjectType.LineObject: case SceneObjectType.LineTextObject: case SceneObjectType.PolygonObject: OsmSharp.UI.Renderer.Scene.Scene2D.ScenePoints geos = scene.GetPoints(sceneObject.GeoId); memoryIndex.Add(new BoxF2D(geos.X, geos.Y), sceneObject); break; } float progress = (float)System.Math.Round((((double)sceneObjectIdx / (double)sceneAtZoom.Count) * 100)); if (progress != latestProgress) { OsmSharp.Logging.Log.TraceEvent("SceneSerializer", OsmSharp.Logging.TraceEventType.Information, "Indexing scene objects at zoom {1} ({2}/{3})... {0}%", progress, sceneIndex.ZoomFactors[idx], sceneObjectIdx, sceneAtZoom.Count); latestProgress = progress; } sceneObjectIdx++; } // serialize the r-tree. OsmSharp.Logging.Log.TraceEvent("SceneSerializer", OsmSharp.Logging.TraceEventType.Information, "Serializing RTRee..."); SceneObjectRTreeSerializer memoryIndexSerializer = new SceneObjectRTreeSerializer( scene, compress, idx, SceneSerializer.CalculateScaleFactor(sceneIndex.ZoomFactors[idx])); memoryIndexSerializer.Serialize(new LimitedStream(stream), memoryIndex); lengths[idx] = (int)(stream.Position - position); } // write SceneLengths long end = stream.Position; stream.Seek(positionAfterMeta + 4 + indexSize, SeekOrigin.Begin); for (int idx = 0; idx < lengths.Length; idx++) { stream.Write(BitConverter.GetBytes(lengths[idx]), 0, 4); } stream.Seek(end, SeekOrigin.Begin); }