/// <summary> /// Draws a polygon on the target. The coordinates given are scene coordinates. /// </summary> /// <param name="target"></param> /// <param name="x">The x coordinate.</param> /// <param name="y">The y coordinate.</param> /// <param name="color">Color.</param> /// <param name="width">Width.</param> /// <param name="fill">If set to <c>true</c> fill.</param> protected override void DrawPolygon(Target2DWrapper <CGContextWrapper> target, double[] x, double[] y, int color, double width, bool fill) { float widthInPixels = this.ToPixels(width) * _scaleFactor; SimpleColor simpleColor = SimpleColor.FromArgb(color); target.Target.CGContext.SetLineWidth(widthInPixels); target.Target.CGContext.SetFillColor(simpleColor.R / 256.0f, simpleColor.G / 256.0f, simpleColor.B / 256.0f, simpleColor.A / 256.0f); target.Target.CGContext.SetStrokeColor(simpleColor.R / 256.0f, simpleColor.G / 256.0f, simpleColor.B / 256.0f, simpleColor.A / 256.0f); // transform the points all at once. double[][] transformed = this.TransformAll(x, y); // build the path. target.Target.CGContext.BeginPath(); PointF[] points = new PointF[x.Length]; for (int idx = 0; idx < x.Length; idx++) { points[idx] = new PointF((float)transformed[idx][0], (float)transformed[idx][1]); } target.Target.CGContext.AddLines(points); target.Target.CGContext.ClosePath(); target.Target.CGContext.FillPath(); }
/// <summary> /// Adds a new OsmSharpRoute. /// </summary> /// <param name="route">Stream.</param> /// <param name="argb">Stream.</param> public void AddRoute(OsmSharpRoute route, int argb) { if (route.Entries != null && route.Entries.Length > 0) { // there are entries. // get x/y. var x = new double[route.Entries.Length]; var y = new double[route.Entries.Length]; for (int idx = 0; idx < route.Entries.Length; idx++) { x[idx] = _projection.LongitudeToX( route.Entries[idx].Longitude); y[idx] = _projection.LatitudeToY( route.Entries[idx].Latitude); } // set the default color if none is given. SimpleColor blue = new SimpleColor() { Value = argb }; SimpleColor color = SimpleColor.FromArgb(argb); this.Scene.AddLine(float.MinValue, float.MaxValue, x, y, color.Value, 4); } }
/// <summary> /// Adds a new OsmSharpRoute. /// </summary> /// <param name="route">Stream.</param> /// <param name="argb">Stream.</param> /// <param name="width"></param> public void AddRoute(Route route, int argb, double width) { if (route != null && route.Segments != null && route.Segments.Length > 0) { // there are entries. // get x/y. var x = new double[route.Segments.Length]; var y = new double[route.Segments.Length]; for (int idx = 0; idx < route.Segments.Length; idx++) { x[idx] = _projection.LongitudeToX( route.Segments[idx].Longitude); y[idx] = _projection.LatitudeToY( route.Segments[idx].Latitude); } // set the default color if none is given. var color = SimpleColor.FromArgb(argb); var pointsId = _scene.AddPoints(x, y); if (pointsId.HasValue) { _scene.AddStyleLine(pointsId.Value, 0, float.MinValue, float.MaxValue, color.Value, (float)width, Renderer.Primitives.LineJoin.Round, null); } } this.RaiseLayerChanged(); }
/// <summary> /// Draws a line on the target. The coordinates given are scene coordinates. /// </summary> /// <param name="target"></param> /// <param name="x">The x coordinate.</param> /// <param name="y">The y coordinate.</param> /// <param name="color">Color.</param> /// <param name="width">Width.</param> /// <param name="lineJoin"></param> /// <param name="dashes"></param> protected override void DrawLine(Target2DWrapper <CGContextWrapper> target, double[] x, double[] y, int color, double width, LineJoin lineJoin, int[] dashes) { float widthInPixels = this.ToPixels(width) * _scaleFactor; SimpleColor simpleColor = SimpleColor.FromArgb(color); target.Target.CGContext.SetLineJoin(CGLineJoin.Round); target.Target.CGContext.SetLineWidth(widthInPixels); target.Target.CGContext.SetStrokeColor(simpleColor.R / 256.0f, simpleColor.G / 256.0f, simpleColor.B / 256.0f, simpleColor.A / 256.0f); target.Target.CGContext.SetLineDash(0, new float[0]); if (dashes != null && dashes.Length > 1) { float[] intervals = new float[dashes.Length]; for (int idx = 0; idx < dashes.Length; idx++) { intervals[idx] = dashes[idx]; } target.Target.CGContext.SetLineDash(0.0f, intervals); } // transform the points all at once. double[][] transformed = this.TransformAll(x, y); // construct path. target.Target.CGContext.BeginPath(); PointF[] points = new PointF[x.Length]; for (int idx = 0; idx < x.Length; idx++) { points[idx] = new PointF((float)transformed[idx][0], (float)transformed[idx][1]); } target.Target.CGContext.AddLines(points); target.Target.CGContext.DrawPath(CGPathDrawingMode.Stroke); }
/// <summary> /// Draws a polygon on the target. The coordinates given are scene coordinates. /// </summary> /// <param name="target"></param> /// <param name="x">The x coordinate.</param> /// <param name="y">The y coordinate.</param> /// <param name="color">Color.</param> /// <param name="width">Width.</param> /// <param name="fill">If set to <c>true</c> fill.</param> protected override void DrawPolygon(Target2DWrapper <CGContextWrapper> target, double[] x, double[] y, int color, double width, bool fill) { float widthInPixels = this.ToPixels(width); SimpleColor simpleColor = SimpleColor.FromArgb(color); target.Target.CGContext.SetLineWidth(widthInPixels); target.Target.CGContext.SetFillColor(simpleColor.R / 256.0f, simpleColor.G / 256.0f, simpleColor.B / 256.0f, simpleColor.A / 256.0f); target.Target.CGContext.SetStrokeColor(simpleColor.R / 256.0f, simpleColor.G / 256.0f, simpleColor.B / 256.0f, simpleColor.A / 256.0f); //target.Target.SetLineDash (0, new float[0]); target.Target.CGContext.BeginPath(); PointF[] points = new PointF[x.Length]; for (int idx = 0; idx < x.Length; idx++) { double[] transformed = this.Tranform(x[idx], y[idx]); points[idx] = new PointF((float)transformed[0], (float)transformed[1]); } target.Target.CGContext.AddLines(points); target.Target.CGContext.ClosePath(); //target.Target.DrawPath (CGPathDrawingMode.Stroke); target.Target.CGContext.FillPath(); //target.Target.E }
/// <summary> /// Adds a new OsmSharpRoute. /// </summary> /// <param name="route">Stream.</param> public void AddRoute(Route route) { // set the default color if none is given. var blue = SimpleColor.FromKnownColor(KnownColor.Blue); var transparantBlue = SimpleColor.FromArgb(128, blue.R, blue.G, blue.B); this.AddRoute(route, transparantBlue.Value); }
/// <summary> /// Draws the backcolor. /// </summary> /// <param name="target"></param> /// <param name="backColor"></param> protected override void DrawBackColor(Target2DWrapper <CGContextWrapper> target, int backColor) { SimpleColor backColorSimple = SimpleColor.FromArgb(backColor); target.Target.CGContext.SetFillColor(backColorSimple.R / 256.0f, backColorSimple.G / 256.0f, backColorSimple.B / 256.0f, backColorSimple.A / 256.0f); target.Target.CGContext.FillRect(new RectangleF(0, 0, target.Width * _scaleFactor, target.Height * _scaleFactor)); }
/// <summary> /// Draws the backcolor. /// </summary> /// <param name="target"></param> /// <param name="backColor"></param> protected override void DrawBackColor(Target2DWrapper <CGContextWrapper> target, int backColor) { var backColorSimple = SimpleColor.FromArgb(backColor); target.Target.CGContext.SetFillColor(backColorSimple.R / 256.0f, backColorSimple.G / 256.0f, backColorSimple.B / 256.0f, backColorSimple.A / 256.0f); _rectangle.X = 0; _rectangle.Y = 0; _rectangle.Width = target.Width * _scaleFactor; _rectangle.Height = target.Height * _scaleFactor; target.Target.CGContext.FillRect(_rectangle); }
/// <summary> /// Draws a point on the target. The coordinates given are scene coordinates. /// </summary> /// <param name="target"></param> /// <param name="x">The x coordinate.</param> /// <param name="y">The y coordinate.</param> /// <param name="color">Color.</param> /// <param name="size">Size.</param> protected override void DrawPoint(Target2DWrapper <CGContextWrapper> target, double x, double y, int color, double size) { var transformed = this.Transform(x, y); var colorSimple = SimpleColor.FromArgb(color); var radius = (float)(this.ToPixels(size) * _scaleFactor) / 2.0f;; target.Target.CGContext.SetFillColor(colorSimple.R / 256.0f, colorSimple.G / 256.0f, colorSimple.B / 256.0f, colorSimple.A / 256.0f); _rectangle.X = (float)transformed[0] - radius; _rectangle.Y = (float)transformed[1] - radius; _rectangle.Width = radius * 2; _rectangle.Height = radius * 2; target.Target.CGContext.FillEllipseInRect(_rectangle); }
/// <summary> /// Creates a new style scene manager. /// </summary> /// <param name="scene">The scene to manage.</param> /// <param name="interpreter">The intepreter converting OSM-objects into scene-objects.</param> public StyleSceneManager(Scene2D scene, StyleInterpreter interpreter) { _scene = scene; _interpreter = interpreter; _interpretedNodes = new LongIndex(); _interpretedWays = new LongIndex(); _interpretedRelations = new LongIndex(); SimpleColor?color = _interpreter.GetCanvasColor(); this.Scene.BackColor = color.HasValue ? color.Value.Value : SimpleColor.FromArgb(0, 255, 255, 255).Value; }
/// <summary> /// Adds a new OsmSharpRoute. /// </summary> /// <param name="route">Stream.</param> /// <param name="argb">Stream.</param> /// <param name="width"></param> public void AddRoute(Route route, int argb, double width) { if (route != null && route.Segments != null && route.Segments.Length > 0) { // there are entries. // get x/y. var x = new double[route.Segments.Length]; var y = new double[route.Segments.Length]; for (int idx = 0; idx < route.Segments.Length; idx++) { x[idx] = _projection.LongitudeToX( route.Segments[idx].Longitude); y[idx] = _projection.LatitudeToY( route.Segments[idx].Latitude); // update envelope. if (_envelope == null) { // create initial envelope. _envelope = new GeoCoordinateBox( new GeoCoordinate(route.Segments[idx].Latitude, route.Segments[idx].Longitude), new GeoCoordinate(route.Segments[idx].Latitude, route.Segments[idx].Longitude)); } // also include the current point. _envelope.ExpandWith(new GeoCoordinate(route.Segments[idx].Latitude, route.Segments[idx].Longitude)); } // set the default color if none is given. var color = SimpleColor.FromArgb(argb); var pointsId = _scene.AddPoints(x, y); if (pointsId.HasValue) { _scene.AddStyleLine(pointsId.Value, 0, float.MinValue, float.MaxValue, color.Value, (float)width, Renderer.Primitives.LineJoin.Round, null); } } this.RaiseLayerChanged(); }
public void TestSimpleColorArgbProperties() { SimpleColor simpleColor = SimpleColor.FromArgb(10, 20, 30, 40); Assert.AreEqual(10, simpleColor.A); Assert.AreEqual(20, simpleColor.R); Assert.AreEqual(30, simpleColor.G); Assert.AreEqual(40, simpleColor.B); simpleColor = SimpleColor.FromArgb(255, 255, 255, 255); Assert.AreEqual(255, simpleColor.A); Assert.AreEqual(255, simpleColor.R); Assert.AreEqual(255, simpleColor.G); Assert.AreEqual(255, simpleColor.B); simpleColor = SimpleColor.FromArgb(0, 0, 0, 0); Assert.AreEqual(0, simpleColor.A); Assert.AreEqual(0, simpleColor.R); Assert.AreEqual(0, simpleColor.G); Assert.AreEqual(0, simpleColor.B); }
private void DrawUserIcon(GeoCoordinate coord, double accuracy) { // If there no coordiantes, we have nothing to do if (coord == null) { return; } if (layerAccuracy == null) { // Create layer for accuracy layerAccuracy = new LayerPrimitives(map.Projection); // Add new accuracy layer map.AddLayer(layerAccuracy); } if (layerUser == null) { // Create layer for user icon layerUser = new LayerPrimitives(map.Projection); // Add layer for user icon map.AddLayer(layerUser); } var repaintUserIcon = coord.Latitude != lastKnownPosition?.Latitude || coord.Longitude != lastKnownPosition?.Longitude; var repaintAccuracy = true; // Stop painting layerAccuracy.Pause(); layerUser.Pause(); if (repaintAccuracy) { layerAccuracy.Clear(); } if (repaintUserIcon) { layerUser.Clear(); } if (IsShowingUserInCenter) { mapView.MapCenter = coord; } if (repaintAccuracy) { var size = 2.2f + mapView.Density * (float)accuracy; layerAccuracy.AddPoint(coord, size > 40 ? 40 : size, SimpleColor.FromArgb(32, 0, 0, 255).Value); } if (repaintUserIcon) { layerUser.AddPoint(coord, mapView.Density * 2.2f, SimpleColor.FromKnownColor(KnownColor.Blue).Value); layerUser.AddPoint(coord, mapView.Density * 1.8f, SimpleColor.FromKnownColor(KnownColor.White).Value); layerUser.AddPoint(coord, mapView.Density * 1.2f, SimpleColor.FromKnownColor(KnownColor.Blue).Value); } layerAccuracy.Resume(); layerUser.Resume(); }
/// <summary> /// Initializes a new instance of the <see cref="OsmSharp.UI.Renderer.Scene2DSimple"/> class. /// </summary> public Scene2DSimple() { _primitives = new SortedDictionary <int, List <IScene2DPrimitive> >(); this.BackColor = SimpleColor.FromArgb(0, 255, 255, 255).Value; // fully transparent. }
private void UserPositionChanged(object sender, PositionEventArgs e) { if (layerUser != null && IsShowingUser) { var center = new GeoCoordinate(e.Position.Latitude, e.Position.Longitude); layerUser.Clear(); layerAccuracy.Clear(); if (IsShowingUserInCenter) { mapView.MapCenter = center; } layerAccuracy.AddPoint(center, 2.2f + mapView.Density * (float)e.Position.Accuracy, SimpleColor.FromArgb(32, 0, 0, 255).Value); layerUser.AddPoint(center, mapView.Density * 2.2f, SimpleColor.FromKnownColor(KnownColor.Blue).Value); layerUser.AddPoint(center, mapView.Density * 1.8f, SimpleColor.FromKnownColor(KnownColor.White).Value); layerUser.AddPoint(center, mapView.Density * 1.2f, SimpleColor.FromKnownColor(KnownColor.Blue).Value); } }
private void DrawLineTextSegment(Target2DWrapper <CGContextWrapper> target, double[] xTransformed, double[] yTransformed, ushort[] glyphs, int color, int?haloColor, int?haloRadius, double middlePosition, float[] characterWidths, double textLength, float charachterHeight, CTFont font) { // see if text is 'upside down' double averageAngle = 0; double first = middlePosition - (textLength / 2.0); PointF2D current = Polyline2D.PositionAtPosition(xTransformed, yTransformed, first); for (int idx = 0; idx < glyphs.Length; idx++) { double nextPosition = middlePosition - (textLength / 2.0) + ((textLength / (glyphs.Length)) * (idx + 1)); PointF2D next = Polyline2D.PositionAtPosition(xTransformed, yTransformed, nextPosition); // translate to the final position, the center of the line segment between 'current' and 'next'. //PointF2D position = current + ((next - current) / 2.0); // calculate the angle. VectorF2D vector = next - current; VectorF2D horizontal = new VectorF2D(1, 0); double angleDegrees = ((Degree)horizontal.Angle(vector)).Value; averageAngle = averageAngle + angleDegrees; current = next; } averageAngle = averageAngle / glyphs.Length; // revers if 'upside down' double[] xText = xTransformed; double[] yText = yTransformed; if (averageAngle > 90 && averageAngle < 180 + 90) { xText = xTransformed.Reverse().ToArray(); yText = yTransformed.Reverse().ToArray(); } first = middlePosition - (textLength / 2.0); current = Polyline2D.PositionAtPosition(xText, yText, first); double nextPosition2 = first; for (int idx = 0; idx < glyphs.Length; idx++) { nextPosition2 = nextPosition2 + characterWidths[idx]; PointF2D next = Polyline2D.PositionAtPosition(xText, yText, nextPosition2); //ushort currentChar = glyphs [idx]; PointF2D position = current; target.Target.CGContext.SaveState(); // translate to the final position, the center of the line segment between 'current' and 'next'. // double[] transformed = this.Tranform(position[0], position[1]); // target.Target.CGContext.TranslateCTM ( // (float)transformed [0], // (float)transformed [1]); target.Target.CGContext.TranslateCTM((float)position[0], (float)position[1]); // calculate the angle. VectorF2D vector = next - current; VectorF2D horizontal = new VectorF2D(1, 0); double angleDegrees = (horizontal.Angle(vector)).Value; // rotate the character. target.Target.CGContext.RotateCTM((float)angleDegrees); // rotate the text to point down no matter what the map tilt is. //target.Target.CGContext.RotateCTM ((float)_view.Angle.Value); // translate the character so the center of its base is over the origin. target.Target.CGContext.TranslateCTM(0, charachterHeight / 3.0f); // rotate 'upside down' target.Target.CGContext.ConcatCTM(new CGAffineTransform(1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f)); target.Target.CGContext.BeginPath(); CGPath path = font.GetPathForGlyph(glyphs[idx]); if (haloRadius.HasValue && haloColor.HasValue) { // also draw the halo. using (CGPath haloPath = path.CopyByStrokingPath( haloRadius.Value * 2, CGLineCap.Round, CGLineJoin.Round, 0)) { SimpleColor haloSimpleColor = SimpleColor.FromArgb(haloColor.Value); target.Target.CGContext.SetFillColor(haloSimpleColor.R / 256.0f, haloSimpleColor.G / 256.0f, haloSimpleColor.B / 256.0f, haloSimpleColor.A / 256.0f); target.Target.CGContext.BeginPath(); target.Target.CGContext.AddPath(haloPath); target.Target.CGContext.DrawPath(CGPathDrawingMode.Fill); } } // set the fill color as the regular text-color. SimpleColor simpleColor = SimpleColor.FromArgb(color); target.Target.CGContext.SetFillColor(simpleColor.R / 256.0f, simpleColor.G / 256.0f, simpleColor.B / 256.0f, simpleColor.A / 256.0f); // draw the text paths. target.Target.CGContext.BeginPath(); target.Target.CGContext.AddPath(path); target.Target.CGContext.DrawPath(CGPathDrawingMode.Fill); // target.Target.CGContext.AddPath (path); // if (haloRadius.HasValue && haloColor.HasValue) { // also draw the halo. // target.Target.CGContext.DrawPath (CGPathDrawingMode.FillStroke); // } else { // target.Target.CGContext.DrawPath (CGPathDrawingMode.Fill); // } //target.Target.CGContext.ClosePath (); target.Target.CGContext.RestoreState(); current = next; } }
/// <summary> /// Draws text. /// </summary> /// <param name="target"></param> /// <param name="x"></param> /// <param name="y"></param> /// <param name="text"></param> /// <param name="size"></param> /// <param name="color">Color.</param> protected override void DrawText(Target2DWrapper <CGContextWrapper> target, double x, double y, string text, int color, double size, int?haloColor, int?haloRadius, string fontName) { double[] transformed = this.Transform(x, y); float xPixels = (float)transformed[0]; float yPixels = (float)transformed[1]; float textSize = this.ToPixels(size) * _scaleFactor; // get the glyhps/paths from the font. CTFont font = this.GetFont(fontName, textSize); CTStringAttributes stringAttributes = new CTStringAttributes { ForegroundColorFromContext = true, Font = font }; NSAttributedString attributedString = new NSAttributedString(text, stringAttributes); CTLine line = new CTLine(attributedString); CTRun[] runs = line.GetGlyphRuns(); // set the correct tranformations to draw the resulting paths. target.Target.CGContext.SaveState(); target.Target.CGContext.TranslateCTM(xPixels, yPixels); target.Target.CGContext.ConcatCTM(new CGAffineTransform(1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f)); foreach (CTRun run in runs) { ushort[] glyphs = run.GetGlyphs(); PointF[] positions = run.GetPositions(); float previousOffset = 0; for (int idx = 0; idx < glyphs.Length; idx++) { CGPath path = font.GetPathForGlyph(glyphs[idx]); target.Target.CGContext.TranslateCTM(positions[idx].X - previousOffset, 0); previousOffset = positions[idx].X; if (haloRadius.HasValue && haloColor.HasValue) { // also draw the halo. using (CGPath haloPath = path.CopyByStrokingPath( haloRadius.Value * 2, CGLineCap.Round, CGLineJoin.Round, 0)) { SimpleColor haloSimpleColor = SimpleColor.FromArgb(haloColor.Value); target.Target.CGContext.SetFillColor(haloSimpleColor.R / 256.0f, haloSimpleColor.G / 256.0f, haloSimpleColor.B / 256.0f, haloSimpleColor.A / 256.0f); target.Target.CGContext.BeginPath(); target.Target.CGContext.AddPath(haloPath); target.Target.CGContext.DrawPath(CGPathDrawingMode.Fill); } } // set the fill color as the regular text-color. SimpleColor simpleColor = SimpleColor.FromArgb(color); target.Target.CGContext.SetFillColor(simpleColor.R / 256.0f, simpleColor.G / 256.0f, simpleColor.B / 256.0f, simpleColor.A / 256.0f); // draw the text paths. target.Target.CGContext.BeginPath(); target.Target.CGContext.AddPath(path); target.Target.CGContext.DrawPath(CGPathDrawingMode.Fill); } } target.Target.CGContext.RestoreState(); }
/// <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> /// Draws text along a given line. /// </summary> /// <param name="target"></param> /// <param name="x"></param> /// <param name="y"></param> /// <param name="color"></param> /// <param name="size"></param> /// <param name="text">Text.</param> protected override void DrawLineText(Target2DWrapper <CGContextWrapper> target, double[] x, double[] y, string text, int color, double size, int?haloColor, int?haloRadius, string fontName) { double[] transformed = this.Tranform(x[0], y[0]); float xPixels = (float)transformed[0]; float yPixels = (float)transformed[1]; float textSize = this.ToPixels(size); // set the fill color as the regular text-color. SimpleColor simpleColor = SimpleColor.FromArgb(color); target.Target.CGContext.InterpolationQuality = CGInterpolationQuality.High; target.Target.CGContext.SetAllowsFontSubpixelQuantization(true); target.Target.CGContext.SetAllowsFontSmoothing(true); target.Target.CGContext.SetFillColor(simpleColor.R / 256.0f, simpleColor.G / 256.0f, simpleColor.B / 256.0f, simpleColor.A / 256.0f); if (haloColor.HasValue) // set the stroke color as the halo color. { SimpleColor haloSimpleColor = SimpleColor.FromArgb(haloColor.Value); target.Target.CGContext.SetStrokeColor(haloSimpleColor.R / 256.0f, haloSimpleColor.G / 256.0f, haloSimpleColor.B / 256.0f, haloSimpleColor.A / 256.0f); } if (haloRadius.HasValue) // set the halo radius as line width. { target.Target.CGContext.SetLineWidth(haloRadius.Value); } // get the glyhps/paths from the font. if (string.IsNullOrWhiteSpace(fontName)) { fontName = "Arial"; } CTFont font = new CTFont(fontName, textSize); CTStringAttributes stringAttributes = new CTStringAttributes { ForegroundColorFromContext = true, Font = font }; NSAttributedString attributedString = new NSAttributedString(text, stringAttributes); CTLine line = new CTLine(attributedString); RectangleF textBounds = line.GetBounds(CTLineBoundsOptions.UseOpticalBounds); CTRun[] runs = line.GetGlyphRuns(); var lineLength = Polyline2D.Length(x, y); // set the correct tranformations to draw the resulting paths. target.Target.CGContext.SaveState(); //target.Target.CGContext.TranslateCTM (xPixels, yPixels); //target.Target.CGContext.ConcatCTM (new CGAffineTransform (1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f)); foreach (CTRun run in runs) { ushort[] glyphs = run.GetGlyphs(); PointF[] positions = run.GetPositions(); float[] characterWidths = new float[glyphs.Length]; float previous = 0; float textLength = (float)this.FromPixels(_target, _view, positions [positions.Length - 1].X); if (lineLength > textLength * 1.2f) { for (int idx = 0; idx < characterWidths.Length - 1; idx++) { characterWidths [idx] = (float)this.FromPixels(_target, _view, positions [idx + 1].X - previous); previous = positions [idx + 1].X; } characterWidths [characterWidths.Length - 1] = characterWidths[characterWidths.Length - 2]; float characterHeight = textBounds.Height; this.DrawLineTextSegment(target, x, y, glyphs, color, haloColor, haloRadius, lineLength / 2f, characterWidths, textLength, characterHeight, font); } } target.Target.CGContext.RestoreState(); }
/// <summary> /// Translates a lineair ring. /// </summary> /// <param name="scene">The scene to add primitives to.</param> /// <param name="projection">The projection used to convert the objects.</param> /// <param name="lineairRing"></param> private void TranslateLineairRing(Scene2D scene, IProjection projection, LineairRing lineairRing) { // build the rules. List <MapCSSRuleProperties> rules = this.BuildRules(new MapCSSObject(lineairRing)); // validate what's there. if (rules.Count == 0) { return; } // get x/y. double[] x = null, y = null; if (lineairRing.Coordinates != null && lineairRing.Coordinates.Count > 0) { // pre-calculate x/y. x = new double[lineairRing.Coordinates.Count]; y = new double[lineairRing.Coordinates.Count]; for (int idx = 0; idx < lineairRing.Coordinates.Count; idx++) { x[idx] = projection.LongitudeToX( lineairRing.Coordinates[idx].Longitude); y[idx] = projection.LatitudeToY( lineairRing.Coordinates[idx].Latitude); } // simplify. if (x.Length > 2) { double[][] simplified = SimplifyCurve.Simplify(new double[][] { x, y }, 0.0001); x = simplified[0]; y = simplified[1]; } } // add the z-index. foreach (var rule in rules) { float minZoom = (float)projection.ToZoomFactor(rule.MinZoom); float maxZoom = (float)projection.ToZoomFactor(rule.MaxZoom); int zIndex; if (!rule.TryGetProperty <int>("zIndex", out zIndex)) { zIndex = 0; } // interpret the results. if (x != null) { // there is a valid interpretation of this way. int color; int fillColor; if (rule.TryGetProperty("fillColor", out fillColor)) { // render as an area. float fillOpacity; if (rule.TryGetProperty("fillOpacity", out fillOpacity)) { SimpleColor simpleFillColor = new SimpleColor() { Value = fillColor }; fillColor = SimpleColor.FromArgb((int)(255 * fillOpacity), simpleFillColor.R, simpleFillColor.G, simpleFillColor.B).Value; } uint?pointsId = scene.AddPoints(x, y); if (pointsId.HasValue) { scene.AddStylePolygon(pointsId.Value, this.CalculateSceneLayer(OffsetArea, zIndex), minZoom, maxZoom, fillColor, 1, true); if (rule.TryGetProperty("color", out color)) { scene.AddStylePolygon(pointsId.Value, this.CalculateSceneLayer(OffsetCasing, zIndex), minZoom, maxZoom, color, 1, false); } } } } } }
/// <summary> /// Builds the scene. /// </summary> /// <param name="map"></param> /// <param name="zoomFactor"></param> /// <param name="center"></param> /// <param name="view"></param> private void BuildScene(Map map, float zoomFactor, GeoCoordinate center, View2D view) { // get the indexed object at this zoom. HashSet <ArcId> interpretedObjects; if (!_interpretedObjects.TryGetValue((int)zoomFactor, out interpretedObjects)) { interpretedObjects = new HashSet <ArcId> (); _interpretedObjects.Add((int)zoomFactor, interpretedObjects); } // build the boundingbox. var viewBox = view.OuterBox; var box = new GeoCoordinateBox(map.Projection.ToGeoCoordinates(viewBox.Min [0], viewBox.Min [1]), map.Projection.ToGeoCoordinates(viewBox.Max [0], viewBox.Max [1])); foreach (var requestedBox in _requestedBoxes) { if (requestedBox.IsInside(box)) { return; } } _requestedBoxes.Add(box); // set the scene backcolor. SimpleColor?color = _styleInterpreter.GetCanvasColor(); this.Scene.BackColor = color.HasValue ? color.Value.Value : SimpleColor.FromArgb(0, 255, 255, 255).Value; // get data. foreach (var arc in _dataSource.GetArcs(box)) { // translate each object into scene object. var arcId = new ArcId() { Vertex1 = arc.Key, Vertex2 = arc.Value.Key }; if (!interpretedObjects.Contains(arcId)) { interpretedObjects.Add(arcId); // create nodes. float latitude, longitude; _dataSource.GetVertex(arcId.Vertex1, out latitude, out longitude); var node1 = CompleteNode.Create(arcId.Vertex1); node1.Coordinate = new GeoCoordinate(latitude, longitude); _dataSource.GetVertex(arcId.Vertex2, out latitude, out longitude); var node2 = CompleteNode.Create(arcId.Vertex2); node2.Coordinate = new GeoCoordinate(latitude, longitude); // create way. var way = CompleteWay.Create(-1); if (arc.Value.Value.Forward) { way.Nodes.Add(node1); way.Nodes.Add(node2); } else { way.Nodes.Add(node2); way.Nodes.Add(node1); } way.Tags.AddOrReplace(_dataSource.TagsIndex.Get(arc.Value.Value.Tags)); _styleInterpreter.Translate(this.Scene, map.Projection, way); interpretedObjects.Add(arcId); } } }