/// <summary> /// Deserializes the given leaf. /// </summary> /// <param name="typeModel"></param> /// <param name="data"></param> /// <param name="boxes"></param> /// <returns></returns> protected override List <Primitive2D> DeSerialize(RuntimeTypeModel typeModel, byte[] data, out List <BoxF2D> boxes) { if (_compressed) { // decompress if needed. data = GZipStream.UncompressBuffer(data); } List <Primitive2D> dataLists = new List <Primitive2D>(); boxes = new List <BoxF2D>(); int scaleFactor = _scaleFactor; // Assume the following stuff already exists in the current scene: // - ZoomRanges // - Styles // deserialize the leaf data. SceneObjectBlock leafData = typeModel.Deserialize( new MemoryStream(data), null, typeof(SceneObjectBlock)) as SceneObjectBlock; // decode for (int idx = 0; idx < leafData.PointsX.Count; idx++) { leafData.PointsX[idx] = leafData.PointsX[idx] + leafData.PointsXMin; leafData.PointsY[idx] = leafData.PointsY[idx] + leafData.PointsYMin; } // store the next points. bool[] pointsStarts = new bool[leafData.PointsX.Count]; // loop over all points. for (int idx = 0; idx < leafData.PointPointId.Count; idx++) { pointsStarts[leafData.PointPointId[idx]] = true; } // loop over all text-points. for (int idx = 0; idx < leafData.TextPointPointId.Count; idx++) { pointsStarts[leafData.TextPointPointId[idx]] = true; } // loop over all icons. for (int idx = 0; idx < leafData.IconPointId.Count; idx++) { pointsStarts[leafData.IconPointId[idx]] = true; } // loop over all lines. for (int idx = 0; idx < leafData.LinePointsId.Count; idx++) { pointsStarts[leafData.LinePointsId[idx]] = true; } // loop over all polygons. for (int idx = 0; idx < leafData.PolygonPointsId.Count; idx++) { pointsStarts[leafData.PolygonPointsId[idx]] = true; } // loop over all line-texts. for (int idx = 0; idx < leafData.LineTextPointsId.Count; idx++) { pointsStarts[leafData.LineTextPointsId[idx]] = true; } Dictionary <int, int> pointsBoundaries = new Dictionary <int, int>(); int previous = 0; for (int idx = 1; idx < pointsStarts.Length; idx++) { if (pointsStarts[idx]) { // there is a start here. pointsBoundaries[previous] = idx - previous; previous = idx; } } pointsBoundaries[previous] = pointsStarts.Length - previous; // loop over all points. for (int idx = 0; idx < leafData.PointPointId.Count; idx++) { // get properties. int pointId = leafData.PointPointId[idx]; uint styleId = leafData.PointStyleId[idx]; // get point/style/zoomrange. double x = (double)leafData.PointsX[pointId] / (double)scaleFactor; double y = (double)leafData.PointsY[pointId] / (double)scaleFactor; StylePoint style = _index.PointStyles[styleId]; // build the primitive. Point2D point = new Point2D(x, y, style.Color, style.Size); point.Layer = style.Layer; point.MinZoom = style.MinZoom; point.MaxZoom = style.MaxZoom; dataLists.Add(point); boxes.Add(new BoxF2D(new PointF2D(x, y))); } // loop over all text-points. for (int idx = 0; idx < leafData.TextPointPointId.Count; idx++) { // get properties. int pointId = leafData.TextPointPointId[idx]; uint styleId = leafData.TextPointStyleId[idx]; string text = leafData.TextPointText[idx]; // get point/style/zoomrange. float x = (float)leafData.PointsX[pointId] / (float)scaleFactor; float y = (float)leafData.PointsY[pointId] / (float)scaleFactor; StyleText style = _index.TextStyles[styleId]; // build the primitive. Text2D text2D = new Text2D(x, y, text, style.Color, style.Size); text2D.Layer = style.Layer; text2D.HaloColor = style.HaloColor; text2D.HaloRadius = style.HaloRadius; text2D.MinZoom = style.MinZoom; text2D.MaxZoom = style.MaxZoom; dataLists.Add(text2D); boxes.Add(new BoxF2D(new PointF2D(x, y))); } // loop over all icons. for (int idx = 0; idx < leafData.IconPointId.Count; idx++) { // get properties. int pointId = leafData.IconPointId[idx]; uint imageId = leafData.IconImageId[idx]; // get point/style/zoomrange. double x = (double)leafData.PointsX[pointId] / (double)scaleFactor; double y = (double)leafData.PointsY[pointId] / (double)scaleFactor; byte[] image = _index.IconImage[(int)imageId]; // build the primitive. Icon2D icon = new Icon2D(x, y, image); icon.Layer = 0; // TODO: layer and zoom level. style.MinZoom, style.MaxZoom dataLists.Add(icon); boxes.Add(new BoxF2D(new PointF2D(x, y))); } // loop over all lines. for (int idx = 0; idx < leafData.LinePointsId.Count; idx++) { // get properties. int pointsId = leafData.LinePointsId[idx]; uint styleId = leafData.LineStyleId[idx]; // get points/style/zoomrange. int pointsCount = pointsBoundaries[pointsId]; double[] x = leafData.PointsX.GetRange(pointsId, pointsCount).ConvertFromLongArray(scaleFactor); double[] y = leafData.PointsY.GetRange(pointsId, pointsCount).ConvertFromLongArray(scaleFactor); StyleLine style = _index.LineStyles[styleId]; // build the primitive. Line2D line = new Line2D(x, y, style.Color, style.Width, style.LineJoin, style.Dashes); line.Layer = style.Layer; line.MinZoom = style.MinZoom; line.MaxZoom = style.MaxZoom; dataLists.Add(line); boxes.Add(new BoxF2D(x, y)); } // loop over all polygons. for (int idx = 0; idx < leafData.PolygonPointsId.Count; idx++) { // get properties. int pointsId = leafData.PolygonPointsId[idx]; uint styleId = leafData.PolygonStyleId[idx]; // get points/style/zoomrange. int pointsCount = pointsBoundaries[pointsId]; double[] x = leafData.PointsX.GetRange(pointsId, pointsCount).ConvertFromLongArray(scaleFactor); double[] y = leafData.PointsY.GetRange(pointsId, pointsCount).ConvertFromLongArray(scaleFactor); StylePolygon style = _index.PolygonStyles[styleId]; // build the primitive. Polygon2D polygon = new Polygon2D(x, y, style.Color, style.Width, style.Fill); polygon.Layer = style.Layer; polygon.MaxZoom = style.MaxZoom; polygon.MinZoom = style.MinZoom; dataLists.Add(polygon); boxes.Add(new BoxF2D(x, y)); } // loop over all line-texts. for (int idx = 0; idx < leafData.LineTextPointsId.Count; idx++) { // get properties. int pointsId = leafData.LineTextPointsId[idx]; uint styleId = leafData.LineTextStyleId[idx]; string text = leafData.LineTextText[idx]; // get points/style/zoomrange. int pointsCount = pointsBoundaries[pointsId]; double[] x = leafData.PointsX.GetRange(pointsId, pointsCount).ConvertFromLongArray(scaleFactor); double[] y = leafData.PointsY.GetRange(pointsId, pointsCount).ConvertFromLongArray(scaleFactor); StyleText style = _index.TextStyles[styleId]; // build the primitive. LineText2D lineText = new LineText2D(x, y, style.Color, style.Size, text); lineText.Layer = style.Layer; lineText.Font = style.Font; lineText.HaloColor = style.HaloColor; lineText.HaloRadius = style.HaloRadius; lineText.MinZoom = style.MinZoom; lineText.MaxZoom = style.MaxZoom; dataLists.Add(lineText); boxes.Add(new BoxF2D(x, y)); } return(dataLists); }
/// <summary> /// Serializes one leaf. /// </summary> /// <param name="typeModel"></param> /// <param name="data"></param> /// <param name="boxes"></param> /// <returns></returns> protected override byte[] Serialize(RuntimeTypeModel typeModel, List <SceneObject> data, List <BoxF2D> boxes) { int scaleFactor = _scaleFactor; Dictionary <uint, int> addedPoint = new Dictionary <uint, int>(); Dictionary <uint, int> addedPoints = new Dictionary <uint, int>(); SceneObjectBlock leafData = new SceneObjectBlock(); //leafData.PointsIndexes = new List<int>(); leafData.PointsX = new List <long>(); leafData.PointsY = new List <long>(); leafData.IconPointId = new List <int>(); leafData.IconImageId = new List <uint>(); leafData.LinePointsId = new List <int>(); leafData.LineStyleId = new List <uint>(); leafData.LineTextPointsId = new List <int>(); leafData.LineTextStyleId = new List <uint>(); leafData.LineTextText = new List <string>(); leafData.PointPointId = new List <int>(); leafData.PointStyleId = new List <uint>(); leafData.PolygonPointsId = new List <int>(); leafData.PolygonStyleId = new List <uint>(); leafData.TextPointPointId = new List <int>(); leafData.TextPointStyleId = new List <uint>(); leafData.TextPointText = new List <string>(); foreach (SceneObject sceneObject in data) { int geoId = -1; OsmSharp.UI.Renderer.Scene.Scene2D.ScenePoint point; OsmSharp.UI.Renderer.Scene.Scene2D.ScenePoints points; switch (sceneObject.Enum) { case SceneObjectType.IconObject: // get point. point = _scene.GetPoint(sceneObject.GeoId); // set point data and keep id. if (!addedPoint.TryGetValue(sceneObject.GeoId, out geoId)) { // the point was not added yet. geoId = leafData.PointsX.Count; //leafData.PointsIndexes.Add(geoId); leafData.PointsX.Add((long)(scaleFactor * point.X)); leafData.PointsY.Add((long)(scaleFactor * point.Y)); addedPoint.Add(sceneObject.GeoId, geoId); } leafData.IconPointId.Add(geoId); // add point. // add image id. leafData.IconImageId.Add(sceneObject.StyleId); break; case SceneObjectType.PointObject: // get point. point = _scene.GetPoint(sceneObject.GeoId); // set point data and keep id. if (!addedPoint.TryGetValue(sceneObject.GeoId, out geoId)) { // the point was not added yet. geoId = leafData.PointsX.Count; leafData.PointsX.Add((long)(scaleFactor * point.X)); leafData.PointsY.Add((long)(scaleFactor * point.Y)); //leafData.PointsIndexes.Add(leafData.PointsY.Count); addedPoint.Add(sceneObject.GeoId, geoId); } leafData.PointPointId.Add(geoId); // add point style. leafData.PointStyleId.Add(sceneObject.StyleId); break; case SceneObjectType.TextObject: // get point. point = _scene.GetPoint(sceneObject.GeoId); // set point data and keep id. if (!addedPoint.TryGetValue(sceneObject.GeoId, out geoId)) { // the point was not added yet. geoId = leafData.PointsX.Count; leafData.PointsX.Add((long)(scaleFactor * point.X)); leafData.PointsY.Add((long)(scaleFactor * point.Y)); //leafData.PointsIndexes.Add(leafData.PointsY.Count); addedPoint.Add(sceneObject.GeoId, geoId); } leafData.TextPointPointId.Add(geoId); // add point style. leafData.TextPointStyleId.Add(sceneObject.StyleId); // add text. leafData.TextPointText.Add( _scene.GetText((sceneObject as SceneTextObject).TextId)); break; case SceneObjectType.LineObject: // get points. points = _scene.GetPoints(sceneObject.GeoId); // set points data and keep id. if (!addedPoints.TryGetValue(sceneObject.GeoId, out geoId)) { // the point was not added yet. geoId = leafData.PointsX.Count; leafData.PointsX.AddRange(points.X.ConvertToLongArray(scaleFactor)); leafData.PointsY.AddRange(points.Y.ConvertToLongArray(scaleFactor)); //leafData.PointsIndexes.Add(leafData.PointsY.Count); addedPoints.Add(sceneObject.GeoId, geoId); } leafData.LinePointsId.Add(geoId); // add point style. leafData.LineStyleId.Add(sceneObject.StyleId); break; case SceneObjectType.LineTextObject: // get points. points = _scene.GetPoints(sceneObject.GeoId); // set points data and keep id. if (!addedPoints.TryGetValue(sceneObject.GeoId, out geoId)) { // the point was not added yet. geoId = leafData.PointsX.Count; leafData.PointsX.AddRange(points.X.ConvertToLongArray(scaleFactor)); leafData.PointsY.AddRange(points.Y.ConvertToLongArray(scaleFactor)); //leafData.PointsIndexes.Add(leafData.PointsY.Count); addedPoints.Add(sceneObject.GeoId, geoId); } leafData.LineTextPointsId.Add(geoId); // add point style. leafData.LineTextStyleId.Add(sceneObject.StyleId); // add text. leafData.LineTextText.Add( _scene.GetText((sceneObject as SceneLineTextObject).TextId)); break; case SceneObjectType.PolygonObject: // get points. points = _scene.GetPoints(sceneObject.GeoId); // set points data and keep id. if (!addedPoints.TryGetValue(sceneObject.GeoId, out geoId)) { // the point was not added yet. geoId = leafData.PointsX.Count; leafData.PointsX.AddRange(points.X.ConvertToLongArray(scaleFactor)); leafData.PointsY.AddRange(points.Y.ConvertToLongArray(scaleFactor)); //leafData.PointsIndexes.Add(leafData.PointsY.Count); addedPoints.Add(sceneObject.GeoId, geoId); } leafData.PolygonPointsId.Add(geoId); // add point style. leafData.PolygonStyleId.Add(sceneObject.StyleId); break; } } // get the mins. leafData.PointsXMin = leafData.PointsX.Min(); leafData.PointsYMin = leafData.PointsY.Min(); // encode. for (int idx = 0; idx < leafData.PointsX.Count; idx++) { leafData.PointsX[idx] = leafData.PointsX[idx] - leafData.PointsXMin; leafData.PointsY[idx] = leafData.PointsY[idx] - leafData.PointsYMin; } // serialize. MemoryStream stream = new MemoryStream(); typeModel.Serialize(stream, leafData); byte[] serializedData = stream.ToArray(); stream.Dispose(); if (_compressed) { // compress. serializedData = GZipStream.CompressBuffer(serializedData); } return(serializedData); }