Пример #1
0
        /// <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);
        }
Пример #2
0
        /// <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);
        }