/// <summary> /// Adds a point. /// </summary> /// <returns>The point.</returns> /// <param name="coordinate">Coordinate.</param> /// <param name="sizePixels">Size pixels.</param> public void AddPoint(GeoCoordinate coordinate, float sizePixels, int color) { double[] projectedCoordinates = _projection.ToPixel( coordinate); uint pointId = _scene.AddPoint(projectedCoordinates[0], projectedCoordinates[1]); _scene.AddStylePoint(pointId, 0, float.MinValue, float.MaxValue, color, sizePixels); this.RaiseLayerChanged(); }
/// <summary> /// Adds a point. /// </summary> /// <returns>The point.</returns> /// <param name="coordinate">Coordinate.</param> /// <param name="sizePixels">Size pixels.</param> /// <param name="color"></param> public void AddPoint(GeoCoordinate coordinate, float sizePixels, int color) { // update envelope. if (_envelope == null) { // create initial envelope. _envelope = new GeoCoordinateBox(coordinate, coordinate); } // also include the current point. _envelope.ExpandWith(coordinate); double[] projectedCoordinates = _projection.ToPixel(coordinate); uint pointId = _scene.AddPoint(projectedCoordinates[0], projectedCoordinates[1]); _scene.AddStylePoint(pointId, 0, float.MinValue, float.MaxValue, color, sizePixels); this.RaiseLayerChanged(); }
/// <summary> /// Merges objects from the given scene for the given zoom level. /// </summary> /// <param name="target"></param> /// <param name="source"></param> /// <param name="idx"></param> private void MergeObjects(Scene2D target, Scene2D source, int idx) { var lines = new Dictionary <Scene2D.ScenePoints, Scene2DStylesSet>(); var linesIndex = new QuadTree <PointF2D, Scene2D.ScenePoints>(); var polygons = new Dictionary <Scene2D.ScenePoints, Scene2DStylesSet>(); //var polygonsIndex = new QuadTree<PointF2D, Scene2D.ScenePoints>(); Dictionary <uint, SceneObject> sceneObjects = source.GetSceneObjectsAt(idx); float zoomFactor = source.GetMaximumZoomFactorAt(idx); float epsilon = source.CalculateSimplificationEpsilon(zoomFactor); foreach (var sceneObject in sceneObjects) { if (sceneObject.Value.Enum == SceneObjectType.LineObject) { // the scene object is a line object. var sceneLineObject = sceneObject.Value as SceneLineObject; Scene2D.ScenePoints scenePoints = source.GetPoints(sceneLineObject.GeoId); Scene2DStylesSet stylesSet = null; if (!lines.TryGetValue(scenePoints, out stylesSet)) { // create styles set. stylesSet = new Scene2DStylesSet(); lines.Add(scenePoints, stylesSet); // add scenePoints to the index. linesIndex.Add(new PointF2D(scenePoints.X[0], scenePoints.Y[0]), scenePoints); linesIndex.Add(new PointF2D(scenePoints.X[scenePoints.X.Length - 1], scenePoints.Y[scenePoints.Y.Length - 1]), scenePoints); } stylesSet.AddStyleLine(sceneLineObject.StyleId); } else if (sceneObject.Value.Enum == SceneObjectType.LineTextObject) { var sceneLineTextObject = sceneObject.Value as SceneLineTextObject; Scene2D.ScenePoints scenePoints = source.GetPoints(sceneLineTextObject.GeoId); Scene2DStylesSet stylesSet = null; if (!lines.TryGetValue(scenePoints, out stylesSet)) { // create styles set. stylesSet = new Scene2DStylesSet(); lines.Add(scenePoints, stylesSet); // add scenePoints to the index. linesIndex.Add(new PointF2D(scenePoints.X[0], scenePoints.Y[0]), scenePoints); linesIndex.Add(new PointF2D(scenePoints.X[scenePoints.X.Length - 1], scenePoints.Y[scenePoints.Y.Length - 1]), scenePoints); } stylesSet.AddStyleLineText(sceneLineTextObject.StyleId, sceneLineTextObject.TextId); } else if (sceneObject.Value.Enum == SceneObjectType.IconObject) { throw new NotSupportedException("Icons not yet supported!"); //var sceneIconObject = (sceneObject.Value as SceneIconObject); //Scene2D.ScenePoint scenePoint = source.GetPoint(sceneIconObject.GeoId); //source.GetStyleIcon( //target.AddIcon(target.AddPoint(scenePoint.X, scenePoint.Y); } else if (sceneObject.Value.Enum == SceneObjectType.PointObject) { var scenePointObject = (sceneObject.Value as ScenePointObject); Scene2D.ScenePoint scenePoint = source.GetPoint(scenePointObject.GeoId); StylePoint stylePoint = source.GetStylePoint(scenePointObject.StyleId); target.AddStylePoint(target.AddPoint(scenePoint.X, scenePoint.Y), stylePoint.Layer, stylePoint.MinZoom, stylePoint.MaxZoom, stylePoint.Color, stylePoint.Size); } else if (sceneObject.Value.Enum == SceneObjectType.PolygonObject) { // the scene object is a polygon. var scenePolygonObject = (sceneObject.Value as ScenePolygonObject); Scene2D.ScenePoints scenePoints = source.GetPoints(sceneObject.Value.GeoId); Scene2DStylesSet stylesSet = null; if (!polygons.TryGetValue(scenePoints, out stylesSet)) { // create styles set. stylesSet = new Scene2DStylesSet(); polygons.Add(scenePoints, stylesSet); //// add scenePoints to the index. //polygonsIndex.Add(new PointF2D(scenePoints.X[0], scenePoints.Y[0]), scenePoints); //polygonsIndex.Add(new PointF2D(scenePoints.X[scenePoints.X.Length - 1], scenePoints.Y[scenePoints.Y.Length - 1]), scenePoints); } stylesSet.AddStylePolygon(scenePolygonObject.StyleId); //var scenePolygonObject = (sceneObject.Value as ScenePolygonObject); //Scene2D.ScenePoints scenePoints = source.GetPoints(sceneObject.Value.GeoId); //StylePolygon stylePolygon = source.GetStylePolygon(sceneObject.Value.StyleId); //uint? pointsId = target.AddPoints(scenePoints.X, scenePoints.Y); //if (pointsId.HasValue) //{ // target.AddStylePolygon(pointsId.Value, stylePolygon.Layer, stylePolygon.MinZoom, stylePolygon.MaxZoom, // stylePolygon.Color, stylePolygon.Width, stylePolygon.Fill); //} } else if (sceneObject.Value.Enum == SceneObjectType.TextObject) { var sceneTextObject = (sceneObject.Value as SceneTextObject); Scene2D.ScenePoint scenePoint = source.GetPoint(sceneObject.Value.GeoId); StyleText styleText = source.GetStyleText(sceneTextObject.StyleId); string text = source.GetText(sceneTextObject.TextId); target.AddText(target.AddPoint(scenePoint.X, scenePoint.Y), styleText.Layer, styleText.MinZoom, styleText.MaxZoom, styleText.Size, text, styleText.Color, styleText.HaloColor, styleText.HaloRadius, styleText.Font); } } // loop until there are no more candidates. int totalLines = lines.Count; float latestProgress = 0; while (lines.Count > 0) { var line = lines.First(); lines.Remove(line.Key); // report progress. float progress = (float)System.Math.Round((((double)(totalLines - lines.Count) / (double)totalLines) * 100)); if (progress != latestProgress) { OsmSharp.Logging.Log.TraceEvent("SceneSerializer", OsmSharp.Logging.TraceEventType.Information, "Merging lines @z{3}e{4} ({1}/{2})... {0}%", progress, totalLines - lines.Count, totalLines, zoomFactor, epsilon); latestProgress = progress; } // copy the coordinates to lists. double[] x = line.Key.X.Clone() as double[]; double[] y = line.Key.Y.Clone() as double[]; // find a matching line. int mergeCount = 1; Scene2D.ScenePoints found; MatchPosition foundPosition = this.FindMatch(linesIndex, lines, x, y, line.Value, epsilon, out found); while (found != null) { // TODO: keep expanding and duplicating until not possible anymore. // remove the found line. lines.Remove(found); // report progress. progress = (float)System.Math.Round((((double)(totalLines - lines.Count) / (double)totalLines) * 100)); if (progress != latestProgress) { OsmSharp.Logging.Log.TraceEvent("SceneSerializer", OsmSharp.Logging.TraceEventType.Information, "Merging lines @z{3}e{4} ({1}/{2})... {0}%", progress, totalLines - lines.Count, totalLines, zoomFactor, epsilon); latestProgress = progress; } // add the line. int lengthBefore = x.Length; Array.Resize(ref x, x.Length + found.X.Length - 1); Array.Resize(ref y, y.Length + found.Y.Length - 1); switch (foundPosition) { case MatchPosition.FirstFirst: found.X.InsertToReverse(1, x, 0, found.X.Length - 1); found.Y.InsertToReverse(1, y, 0, found.Y.Length - 1); break; case MatchPosition.FirstLast: found.X.InsertTo(0, x, 0, found.X.Length - 1); found.Y.InsertTo(0, y, 0, found.Y.Length - 1); break; case MatchPosition.LastFirst: found.X.CopyTo(x, lengthBefore - 1); found.Y.CopyTo(y, lengthBefore - 1); break; case MatchPosition.LastLast: found.X.CopyToReverse(x, lengthBefore - 1); found.Y.CopyToReverse(y, lengthBefore - 1); break; } // select a new line. foundPosition = this.FindMatch(linesIndex, lines, x, y, line.Value, epsilon, out found); mergeCount++; } // simplify first. double[][] simplified = OsmSharp.Math.Algorithms.SimplifyCurve.Simplify(new double[][] { x, y }, epsilon); // add the new points. uint?pointsId = target.AddPoints(simplified[0], simplified[1]); // add points again with appropriate styles. if (pointsId.HasValue) { foreach (var style in line.Value) { var scene2DStyleLine = (style as Scene2DStyleLine); if (scene2DStyleLine != null) { StyleLine styleLine = source.GetStyleLine(scene2DStyleLine.StyleLineId); target.AddStyleLine(pointsId.Value, styleLine.Layer, styleLine.MinZoom, styleLine.MaxZoom, styleLine.Color, styleLine.Width, styleLine.LineJoin, styleLine.Dashes); continue; } var scene2DStyleLineText = (style as Scene2DStyleLineText); if (scene2DStyleLineText != null) { StyleText styleText = source.GetStyleLineText(scene2DStyleLineText.StyleLineTextId); string text = source.GetText(scene2DStyleLineText.TextId); target.AddStyleLineText(pointsId.Value, styleText.Layer, styleText.MinZoom, styleText.MaxZoom, styleText.Color, styleText.Size, text, styleText.Font, styleText.HaloColor, styleText.HaloRadius); continue; } } } } // loop until there are no more candidates. totalLines = polygons.Count; latestProgress = 0; while (polygons.Count > 0) { var polygon = polygons.First(); polygons.Remove(polygon.Key); // report progress. float progress = (float)System.Math.Round((((double)(totalLines - polygons.Count) / (double)totalLines) * 100)); if (progress != latestProgress) { OsmSharp.Logging.Log.TraceEvent("SceneSerializer", OsmSharp.Logging.TraceEventType.Information, "Merging polygons @z{3}e{4} ({1}/{2})... {0}%", progress, totalLines - polygons.Count, totalLines, zoomFactor, epsilon); latestProgress = progress; } // copy the coordinates to lists. double[] x = polygon.Key.X.Clone() as double[]; double[] y = polygon.Key.Y.Clone() as double[]; //// find a matching line. //int mergeCount = 1; //Scene2D.ScenePoints found; //MatchPosition foundPosition = this.FindMatch(linesIndex, lines, x, y, line.Value, epsilon, out found); //while (found != null) //{ // TODO: keep expanding and duplicating until not possible anymore. // // remove the found line. // lines.Remove(found); // // report progress. // progress = (float)System.Math.Round((((double)(totalLines - lines.Count) / (double)totalLines) * 100)); // if (progress != latestProgress) // { // OsmSharp.Logging.Log.TraceEvent("SceneSerializer", OsmSharp.Logging.TraceEventType.Information, // "Merging lines @z{3}e{4} ({1}/{2})... {0}%", progress, totalLines - lines.Count, totalLines, zoomFactor, epsilon); // latestProgress = progress; // } // // add the line. // int lengthBefore = x.Length; // Array.Resize(ref x, x.Length + found.X.Length - 1); // Array.Resize(ref y, y.Length + found.Y.Length - 1); // switch (foundPosition) // { // case MatchPosition.FirstFirst: // found.X.InsertToReverse(1, x, 0, found.X.Length - 1); // found.Y.InsertToReverse(1, y, 0, found.Y.Length - 1); // break; // case MatchPosition.FirstLast: // found.X.InsertTo(0, x, 0, found.X.Length - 1); // found.Y.InsertTo(0, y, 0, found.Y.Length - 1); // break; // case MatchPosition.LastFirst: // found.X.CopyTo(x, lengthBefore - 1); // found.Y.CopyTo(y, lengthBefore - 1); // break; // case MatchPosition.LastLast: // found.X.CopyToReverse(x, lengthBefore - 1); // found.Y.CopyToReverse(y, lengthBefore - 1); // break; // } // // select a new line. // foundPosition = this.FindMatch(linesIndex, lines, x, y, line.Value, epsilon, out found); // mergeCount++; //} // simplify first. double[][] simplified = OsmSharp.Math.Algorithms.SimplifyCurve.Simplify(new double[][] { x, y }, epsilon); // add the new points. uint?pointsId = target.AddPoints(simplified[0], simplified[1]); // add points again with appropriate styles. if (pointsId.HasValue) { foreach (var style in polygon.Value) { var scene2DStylePolygon = (style as Scene2DStylePolygon); if (scene2DStylePolygon != null) { StylePolygon stylePolygon = source.GetStylePolygon(scene2DStylePolygon.StylePolygonId); target.AddStylePolygon(pointsId.Value, stylePolygon.Layer, stylePolygon.MinZoom, stylePolygon.MaxZoom, stylePolygon.Color, stylePolygon.Width, stylePolygon.Fill); continue; } } } } }
/// <summary> /// Translates a node. /// </summary> /// <param name="scene">The scene to add primitives to.</param> /// <param name="projection">The projection used to convert the objects.</param> /// <param name="node"></param> private void TranslateNode(Scene2D scene, IProjection projection, CompleteNode node) { // build the rules. IEnumerable <MapCSSRuleProperties> rules = this.BuildRules(new MapCSSObject(node)); // interpret the results. foreach (var rule in rules) { int zIndex; if (!rule.TryGetProperty <int>("zIndex", out zIndex)) { zIndex = 0; } float minZoom = (float)projection.ToZoomFactor(rule.MinZoom); float maxZoom = (float)projection.ToZoomFactor(rule.MaxZoom); uint?pointId = null; int color; if (rule.TryGetProperty <int>("color", out color)) { float width; if (rule.TryGetProperty <float>("width", out width)) { pointId = scene.AddPoint(projection.LongitudeToX(node.Coordinate.Longitude), projection.LatitudeToY(node.Coordinate.Latitude)); scene.AddStylePoint(pointId.Value, this.CalculateSceneLayer(OffsetPoint, zIndex), minZoom, maxZoom, color, width); } else { pointId = scene.AddPoint(projection.LongitudeToX(node.Coordinate.Longitude), projection.LatitudeToY(node.Coordinate.Latitude)); scene.AddStylePoint(pointId.Value, this.CalculateSceneLayer(OffsetPoint, zIndex), minZoom, maxZoom, color, 1); } } byte[] iconImage; if (rule.TryGetProperty("iconImage", out iconImage)) { if (!pointId.HasValue) { pointId = scene.AddPoint(projection.LongitudeToX(node.Coordinate.Longitude), projection.LatitudeToY(node.Coordinate.Latitude)); } // an icon is to be drawn! ushort imageId = scene.AddImage(iconImage); scene.AddIcon(pointId.Value, this.CalculateSceneLayer(OffsetPoint, zIndex), minZoom, maxZoom, imageId); } string text; if (rule.TryGetProperty("text", out text)) { int textColor; if (!rule.TryGetProperty("textColor", out textColor)) { textColor = SimpleColor.FromKnownColor(KnownColor.Black).Value; } int haloColor; int?haloColorNullable = null; if (rule.TryGetProperty("textHaloColor", out haloColor)) { haloColorNullable = haloColor; } int haloRadius; int?haloRadiusNullable = null; if (rule.TryGetProperty("textHaloRadius", out haloRadius)) { haloRadiusNullable = haloRadius; } int fontSize; if (!rule.TryGetProperty("fontSize", out fontSize)) { fontSize = 10; } string fontFamily; if (!rule.TryGetProperty("fontFamily", out fontFamily)) { fontFamily = "Arial"; // just some default font. } // a text is to be drawn. string value; if (node.Tags.TryGetValue(text, out value)) { if (!pointId.HasValue) { pointId = scene.AddPoint(projection.LongitudeToX(node.Coordinate.Longitude), projection.LatitudeToY(node.Coordinate.Latitude)); } scene.AddText(pointId.Value, this.CalculateSceneLayer(OffsetPointText, zIndex), minZoom, maxZoom, fontSize, value, textColor, haloColorNullable, haloRadiusNullable, fontFamily); } } } }
/// <summary> /// Translates OSM objects into basic renderable primitives. /// </summary> /// <param name="scene">The scene to add primitives to.</param> /// <param name="projection">The projection used to convert the objects.</param> /// <param name="osmGeo">The osm object.</param> /// <returns></returns> public override void Translate(Scene2D scene, IProjection projection, CompleteOsmGeo osmGeo) { // set the scene backcolor. scene.BackColor = this.GetCanvasColor().Value; if (osmGeo == null) { return; } // store the object count. int countBefore = scene.Count; // interpret the osm-objects. switch (osmGeo.Type) { case CompleteOsmType.Node: this.TranslateNode(scene, projection, osmGeo as CompleteNode); break; case CompleteOsmType.Way: this.TranslateWay(scene, projection, osmGeo as CompleteWay); break; case CompleteOsmType.Relation: this.TranslateRelation(scene, projection, osmGeo as CompleteRelation); break; case CompleteOsmType.ChangeSet: break; default: throw new ArgumentOutOfRangeException(); } // interpret the osmGeo object and check if it makes up an area. GeometryCollection collection = _geometryInterpreter.Interpret(osmGeo); foreach (Geometry geometry in collection) { if (geometry is LineairRing) { // a simple lineair ring. this.TranslateLineairRing(scene, projection, geometry as LineairRing); } else if (geometry is Polygon) { // a simple polygon. this.TranslatePolygon(scene, projection, geometry as Polygon); } else if (geometry is MultiPolygon) { // a multipolygon. this.TranslateMultiPolygon(scene, projection, geometry as MultiPolygon); } } // check if any objects have been added to the scene. if (scene.Count <= countBefore) { // no objects have been added. Apply default styles if needed. if (osmGeo.Type == CompleteOsmType.Node && _mapCSSFile != null && _mapCSSFile.DefaultPoints) { // apply default points style. CompleteNode node = (osmGeo as CompleteNode); uint pointId = scene.AddPoint(projection.LongitudeToX(node.Coordinate.Longitude), projection.LatitudeToY(node.Coordinate.Latitude)); scene.AddStylePoint(pointId, this.CalculateSceneLayer(OffsetPoint, 0), float.MinValue, float.MaxValue, SimpleColor.FromKnownColor(KnownColor.Black).Value, 2); } else if (osmGeo.Type == CompleteOsmType.Way && _mapCSSFile != null && _mapCSSFile.DefaultLines) { // apply default lines style. CompleteWay way = (osmGeo as CompleteWay); // get x/y. double[] x = null, y = null; if (x == null) { // pre-calculate x/y. x = new double[way.Nodes.Count]; y = new double[way.Nodes.Count]; for (int idx = 0; idx < way.Nodes.Count; idx++) { x[idx] = projection.LongitudeToX( way.Nodes[idx].Coordinate.Longitude); y[idx] = projection.LatitudeToY( way.Nodes[idx].Coordinate.Latitude); } // simplify. if (x.Length > 2) { double[][] simplified = SimplifyCurve.Simplify(new double[][] { x, y }, 0.0001); x = simplified[0]; y = simplified[1]; } } uint?points = scene.AddPoints(x, y); if (points.HasValue) { scene.AddStyleLine(points.Value, this.CalculateSceneLayer(OffsetLine, 0), float.MinValue, float.MaxValue, SimpleColor.FromKnownColor(KnownColor.Red).Value, 1, LineJoin.Round, null); } } } }
/// <summary> /// Adds a new GPX. /// </summary> /// <param name="stream">Stream.</param> public GeoCoordinateBox AddGpx(Stream stream) { GeoCoordinateBox bounds = null; var gpxStream = new GpxGeoStreamSource(stream); foreach (var geometry in gpxStream) { if (geometry is Point) { // add the point. var point = (geometry as Point); // get x/y. var x = _projection.LongitudeToX(point.Coordinate.Longitude); var y = _projection.LatitudeToY(point.Coordinate.Latitude); // set the default color if none is given. SimpleColor blue = SimpleColor.FromKnownColor(KnownColor.Blue); SimpleColor transparantBlue = SimpleColor.FromArgb(128, blue.R, blue.G, blue.B); uint pointId = _scene.AddPoint(x, y); _scene.AddStylePoint(pointId, 0, float.MinValue, float.MaxValue, transparantBlue.Value, 8); if (bounds == null) { // create box. bounds = point.Box; } else { // add to the current box. bounds = bounds + point.Box; } } else if (geometry is LineString) { // add the lineString. var lineString = (geometry as LineString); // get x/y. var x = new double[lineString.Coordinates.Count]; var y = new double[lineString.Coordinates.Count]; for (int idx = 0; idx < lineString.Coordinates.Count; idx++) { x[idx] = _projection.LongitudeToX( lineString.Coordinates[idx].Longitude); y[idx] = _projection.LatitudeToY( lineString.Coordinates[idx].Latitude); } // set the default color if none is given. SimpleColor blue = SimpleColor.FromKnownColor(KnownColor.Blue); SimpleColor transparantBlue = SimpleColor.FromArgb(128, blue.R, blue.G, blue.B); uint?pointsId = _scene.AddPoints(x, y); if (pointsId.HasValue) { _scene.AddStyleLine(pointsId.Value, 0, float.MinValue, float.MaxValue, transparantBlue.Value, 8, Renderer.Primitives.LineJoin.Round, null); if (bounds == null) { // create box. bounds = lineString.Box; } else { // add to the current box. bounds = bounds + lineString.Box; } } } } return(bounds); }
/// <summary> /// Merges objects from the given scene for the given zoom level. /// </summary> /// <param name="target"></param> /// <param name="source"></param> /// <param name="idx"></param> private void MergeObjects(Scene2D target, Scene2D source, int idx) { Dictionary<Scene2D.ScenePoints, Scene2DStylesSet> lines = new Dictionary<Scene2D.ScenePoints, Scene2DStylesSet>(); Dictionary<PointF2D, HashSet<Scene2D.ScenePoints>> endpoints = new Dictionary<PointF2D, HashSet<Scene2D.ScenePoints>>(); Dictionary<uint, SceneObject> sceneObjects = source.GetSceneObjectsAt(idx); foreach (var sceneObject in sceneObjects) { if (sceneObject.Value.Enum == SceneObjectType.LineObject) { // the scene object is a line object. var sceneLineObject = sceneObject.Value as SceneLineObject; Scene2D.ScenePoints scenePoints = source.GetPoints(sceneLineObject.GeoId); Scene2DStylesSet stylesSet = null; if (!lines.TryGetValue(scenePoints, out stylesSet)) { // create styles set. stylesSet = new Scene2DStylesSet(); lines.Add(scenePoints, stylesSet); } stylesSet.AddStyleLine(sceneLineObject.StyleId); //var sceneLineObject = (sceneObject.Value as SceneLineObject); //Scene2D.ScenePoints scenePoints = source.GetPoints(sceneLineObject.GeoId); //StyleLine styleLine = source.GetStyleLine(sceneLineObject.StyleId); //uint? pointsId = target.AddPoints(scenePoints.X, scenePoints.Y); //if (pointsId.HasValue) //{ // target.AddStyleLine(pointsId.Value, styleLine.Layer, styleLine.MinZoom, styleLine.MaxZoom, // styleLine.Color, styleLine.Width, styleLine.LineJoin, styleLine.Dashes); //} } else if (sceneObject.Value.Enum == SceneObjectType.LineTextObject) { var sceneLineTextObject = sceneObject.Value as SceneLineTextObject; Scene2D.ScenePoints scenePoints = source.GetPoints(sceneLineTextObject.GeoId); Scene2DStylesSet stylesSet = null; if (!lines.TryGetValue(scenePoints, out stylesSet)) { // create styles set. stylesSet = new Scene2DStylesSet(); lines.Add(scenePoints, stylesSet); } stylesSet.AddStyleLineText(sceneLineTextObject.StyleId, sceneLineTextObject.TextId); //var sceneLineTextObject = (sceneObject.Value as SceneLineTextObject); //Scene2D.ScenePoints scenePoints = source.GetPoints(sceneLineTextObject.GeoId); //StyleText styleText = source.GetStyleText(sceneLineTextObject.StyleId); //string text = source.GetText(sceneLineTextObject.TextId); //uint? pointsId = target.AddPoints(scenePoints.X, scenePoints.Y); //if (pointsId.HasValue) //{ // target.AddStyleLineText(pointsId.Value, styleText.Layer, styleText.MinZoom, styleText.MaxZoom, // styleText.Color, styleText.Size, text, styleText.Font, styleText.HaloColor, styleText.HaloRadius); //} } else if (sceneObject.Value.Enum == SceneObjectType.IconObject) { throw new NotSupportedException("Icons not yet supported!"); //var sceneIconObject = (sceneObject.Value as SceneIconObject); //Scene2D.ScenePoint scenePoint = source.GetPoint(sceneIconObject.GeoId); //source.GetStyleIcon( //target.AddIcon(target.AddPoint(scenePoint.X, scenePoint.Y); } else if (sceneObject.Value.Enum == SceneObjectType.PointObject) { var scenePointObject = (sceneObject.Value as ScenePointObject); Scene2D.ScenePoint scenePoint = source.GetPoint(scenePointObject.GeoId); StylePoint stylePoint = source.GetStylePoint(scenePointObject.StyleId); target.AddStylePoint(target.AddPoint(scenePoint.X, scenePoint.Y), stylePoint.Layer, stylePoint.MinZoom, stylePoint.MaxZoom, stylePoint.Color, stylePoint.Size); } else if (sceneObject.Value.Enum == SceneObjectType.PolygonObject) { var scenePolygonObject = (sceneObject.Value as ScenePolygonObject); Scene2D.ScenePoints scenePoints = source.GetPoints(sceneObject.Value.GeoId); StylePolygon stylePolygon = source.GetStylePolygon(sceneObject.Value.StyleId); uint? pointsId = target.AddPoints(scenePoints.X, scenePoints.Y); if (pointsId.HasValue) { target.AddStylePolygon(pointsId.Value, stylePolygon.Layer, stylePolygon.MinZoom, stylePolygon.MaxZoom, stylePolygon.Color, stylePolygon.Width, stylePolygon.Fill); } } else if (sceneObject.Value.Enum == SceneObjectType.TextObject) { var sceneTextObject = (sceneObject.Value as SceneTextObject); Scene2D.ScenePoint scenePoint = source.GetPoint(sceneObject.Value.GeoId); StyleText styleText = source.GetStyleText(sceneTextObject.StyleId); string text = source.GetText(sceneTextObject.TextId); target.AddText(target.AddPoint(scenePoint.X, scenePoint.Y), styleText.Layer, styleText.MinZoom, styleText.MaxZoom, styleText.Size, text, styleText.Color, styleText.HaloColor, styleText.HaloRadius, styleText.Font); } } // loop until there are no more candidates. int totalLines = lines.Count; float latestProgress = 0; while (lines.Count > 0) { var line = lines.First(); lines.Remove(line.Key); // report progress. float progress = (float)System.Math.Round((((double)(totalLines - lines.Count) / (double)totalLines) * 100)); if (progress != latestProgress) { OsmSharp.Logging.Log.TraceEvent("SceneSerializer", OsmSharp.Logging.TraceEventType.Information, "Merging lines ({1}/{2})... {0}%", progress, totalLines - lines.Count, totalLines); latestProgress = progress; } // copy the coordinates to lists. double[] x = line.Key.X.Clone() as double[]; double[] y = line.Key.Y.Clone() as double[]; // find a matching line. int mergeCount = 1; Scene2D.ScenePoints found; MatchPosition foundPosition = this.FindMatch(lines, x, y, line.Value, out found); while (found != null) { // TODO: keep expanding and duplicating until not possible anymore. // remove the found line. lines.Remove(found); // add the line. int lengthBefore = x.Length; Array.Resize(ref x, x.Length + found.X.Length - 1); Array.Resize(ref y, y.Length + found.Y.Length - 1); switch (foundPosition) { case MatchPosition.FirstFirst: found.X.InsertToReverse(1, x, 0, found.X.Length - 1); found.Y.InsertToReverse(1, y, 0, found.Y.Length - 1); break; case MatchPosition.FirstLast: found.X.InsertTo(0, x, 0, found.X.Length - 1); found.Y.InsertTo(0, y, 0, found.Y.Length - 1); break; case MatchPosition.LastFirst: found.X.CopyTo(x, lengthBefore - 1); found.Y.CopyTo(y, lengthBefore - 1); break; case MatchPosition.LastLast: found.X.CopyToReverse(x, lengthBefore - 1); found.Y.CopyToReverse(y, lengthBefore - 1); break; } // select a new line. foundPosition = this.FindMatch(lines, x, y, line.Value, out found); mergeCount++; } // add the new points. uint? pointsId = target.AddPoints(x, y); // add points again with appropriate styles. if (pointsId.HasValue) { foreach (var style in line.Value) { var scene2DStyleLine = (style as Scene2DStyleLine); if (scene2DStyleLine != null) { StyleLine styleLine = source.GetStyleLine(scene2DStyleLine.StyleLineId); target.AddStyleLine(pointsId.Value, styleLine.Layer, styleLine.MinZoom, styleLine.MaxZoom, styleLine.Color, styleLine.Width, styleLine.LineJoin, styleLine.Dashes); continue; } var scene2DStyleLineText = (style as Scene2DStyleLineText); if (scene2DStyleLineText != null) { StyleText styleText = source.GetStyleLineText(scene2DStyleLineText.StyleLineTextId); string text = source.GetText(scene2DStyleLineText.TextId); target.AddStyleLineText(pointsId.Value, styleText.Layer, styleText.MinZoom, styleText.MaxZoom, styleText.Color, styleText.Size, text, styleText.Font, styleText.HaloColor, styleText.HaloRadius); continue; } } } } }