示例#1
0
        private static SKRect WorldToScreen(IReadOnlyViewport viewport, MRect rect)
        {
            var first  = viewport.WorldToScreen(rect.Min.X, rect.Min.Y);
            var second = viewport.WorldToScreen(rect.Max.X, rect.Max.Y);

            return(new SKRect
                   (
                       (float)Math.Min(first.X, second.X),
                       (float)Math.Min(first.Y, second.Y),
                       (float)Math.Max(first.X, second.X),
                       (float)Math.Max(first.Y, second.Y)
                   ));
        }
示例#2
0
        private static BoundingBox WorldToScreen(IReadOnlyViewport viewport, BoundingBox boundingBox)
        {
            var first  = viewport.WorldToScreen(boundingBox.Min);
            var second = viewport.WorldToScreen(boundingBox.Max);

            return(new BoundingBox
                   (
                       Math.Min(first.X, second.X),
                       Math.Min(first.Y, second.Y),
                       Math.Max(first.X, second.X),
                       Math.Max(first.Y, second.Y)
                   ));
        }
示例#3
0
        public bool Draw(SKCanvas canvas, IReadOnlyViewport viewport, ILayer layer, IFeature feature, IStyle style, ISymbolCache symbolCache)
        {
            if (!(feature.Geometry is global::Mapsui.Geometries.Point worldPoint))
            {
                return(false);
            }

            var screenPoint = viewport.WorldToScreen(worldPoint);
            var color       = new SKColor((byte)rnd.Next(0, 256), (byte)rnd.Next(0, 256), (byte)rnd.Next(0, 256), (byte)(256.0 * layer.Opacity * style.Opacity));
            var colored     = new SKPaint()
            {
                Color = color, IsAntialias = true
            };
            var black = new SKPaint()
            {
                Color = SKColors.Black, IsAntialias = true
            };

            canvas.Translate((float)screenPoint.X, (float)screenPoint.Y);
            canvas.DrawCircle(0, 0, 15, colored);
            canvas.DrawCircle(-8, -12, 8, colored);
            canvas.DrawCircle(8, -12, 8, colored);
            canvas.DrawCircle(8, -8, 2, black);
            canvas.DrawCircle(-8, -8, 2, black);
            using (var path = new SKPath())
            {
                path.ArcTo(new SKRect(-8, 2, 8, 10), 25, 135, true);
                canvas.DrawPath(path, new SKPaint()
                {
                    Style = SKPaintStyle.Stroke, Color = SKColors.Black, IsAntialias = true
                });
            }

            return(true);
        }
示例#4
0
        public bool Draw(SKCanvas canvas, IReadOnlyViewport viewport, ILayer layer, IFeature feature, IStyle istyle,
                         ISymbolCache symbolCache)
        {
            var style = ((PolylineMarkerStyle)istyle);

            var zoom = 1 / (float)viewport.Resolution;
            //
            var dest = viewport.WorldToScreen(style.start.X, style.start.Y);

            canvas.Translate((float)dest.X, (float)dest.Y);
            canvas.Scale(zoom, zoom);

            canvas.RotateDegrees((float)viewport.Rotation, 0.0f, 0.0f);

            //#TODO store paint with shader in the style
            using (SKPaint paint = new SKPaint())
            {
                paint.Color       = style.color.WithAlpha((byte)(style.Opacity * 255));
                paint.StrokeWidth = 3f * (float)viewport.Resolution;
                paint.Style       = SKPaintStyle.Stroke;
                paint.IsAntialias = true;

                canvas.DrawPath(style.path, paint);
            }

            return(true);
        }
示例#5
0
        public static void Draw(SKCanvas canvas, IReadOnlyViewport viewport, IStyle style, IFeature feature,
                                IGeometry geometry, SymbolCache symbolCache, float opacity)
        {
            var point       = geometry as Point;
            var destination = viewport.WorldToScreen(point);

            if (style is LabelStyle labelStyle)    // case 1) LabelStyle
            {
                LabelRenderer.Draw(canvas, labelStyle, feature, (float)destination.X, (float)destination.Y,
                                   opacity);
            }
            else if (style is SymbolStyle)
            {
                var symbolStyle = (SymbolStyle)style;

                if (symbolStyle.BitmapId >= 0)    // case 2) Bitmap Style
                {
                    DrawPointWithBitmapStyle(canvas, symbolStyle, destination, symbolCache, opacity);
                }
                else                              // case 3) SymbolStyle without bitmap
                {
                    DrawPointWithSymbolStyle(canvas, symbolStyle, destination, opacity, symbolStyle.SymbolType);
                }
            }
            else if (style is VectorStyle)        // case 4) VectorStyle
            {
                DrawPointWithVectorStyle(canvas, (VectorStyle)style, destination, opacity);
            }
            else
            {
                throw new Exception($"Style of type '{style.GetType()}' is not supported for points");
            }
        }
示例#6
0
        public static void Draw(SKCanvas canvas, IReadOnlyViewport viewport, IStyle style, IFeature feature, IGeometry geometry,
                                float opacity)
        {
            if (style is LabelStyle labelStyle)
            {
                var worldCenter = geometry.BoundingBox.Centroid;
                var center      = viewport.WorldToScreen(worldCenter);
                LabelRenderer.Draw(canvas, labelStyle, feature, center, opacity);
            }
            else
            {
                var lineString = ((LineString)geometry).Vertices;

                float lineWidth = 1;
                var   lineColor = new Color();

                var     vectorStyle      = style as VectorStyle;
                var     strokeCap        = PenStrokeCap.Butt;
                var     strokeJoin       = StrokeJoin.Miter;
                var     strokeMiterLimit = 4f;
                var     strokeStyle      = PenStyle.Solid;
                float[] dashArray        = null;
                float   dashOffset       = 0;

                if (vectorStyle != null)
                {
                    lineWidth        = (float)vectorStyle.Line.Width;
                    lineColor        = vectorStyle.Line.Color;
                    strokeCap        = vectorStyle.Line.PenStrokeCap;
                    strokeJoin       = vectorStyle.Line.StrokeJoin;
                    strokeMiterLimit = vectorStyle.Line.StrokeMiterLimit;
                    strokeStyle      = vectorStyle.Line.PenStyle;
                    dashArray        = vectorStyle.Line.DashArray;
                    dashOffset       = vectorStyle.Line.DashOffset;
                }

                using (var path = lineString.ToSkiaPath(viewport, canvas.LocalClipBounds))
                    using (var paint = new SKPaint {
                        IsAntialias = true
                    })
                    {
                        paint.IsStroke    = true;
                        paint.StrokeWidth = lineWidth;
                        paint.Color       = lineColor.ToSkia(opacity);
                        paint.StrokeCap   = strokeCap.ToSkia();
                        paint.StrokeJoin  = strokeJoin.ToSkia();
                        paint.StrokeMiter = strokeMiterLimit;
                        if (strokeStyle != PenStyle.Solid)
                        {
                            paint.PathEffect = strokeStyle.ToSkia(lineWidth, dashArray, dashOffset);
                        }
                        else
                        {
                            paint.PathEffect = null;
                        }
                        canvas.DrawPath(path, paint);
                    }
            }
        }
示例#7
0
        public static void Draw(SKCanvas canvas, IReadOnlyViewport viewport, IStyle style, IFeature feature,
                                LineString lineString, float opacity)
        {
            if (style is LabelStyle labelStyle)
            {
                if (feature.Extent == null)
                {
                    return;
                }

                var center = viewport.WorldToScreen(feature.Extent.Centroid);
                LabelRenderer.Draw(canvas, labelStyle, feature, center.X, center.Y, opacity);
            }
            else
            {
                float lineWidth = 1;
                var   lineColor = new Color();

                var vectorStyle      = style as VectorStyle;
                var strokeCap        = PenStrokeCap.Butt;
                var strokeJoin       = StrokeJoin.Miter;
                var strokeMiterLimit = 4f;
                var strokeStyle      = PenStyle.Solid;
                float[]? dashArray = null;
                float dashOffset = 0;

                if (vectorStyle is not null && vectorStyle.Line != null)
                {
                    lineWidth        = (float)vectorStyle.Line.Width;
                    lineColor        = vectorStyle.Line.Color;
                    strokeCap        = vectorStyle.Line.PenStrokeCap;
                    strokeJoin       = vectorStyle.Line.StrokeJoin;
                    strokeMiterLimit = vectorStyle.Line.StrokeMiterLimit;
                    strokeStyle      = vectorStyle.Line.PenStyle;
                    dashArray        = vectorStyle.Line.DashArray;
                    dashOffset       = vectorStyle.Line.DashOffset;
                }

                using var path    = lineString.ToSkiaPath(viewport, canvas.LocalClipBounds);
                using var paint   = new SKPaint { IsAntialias = true };
                paint.IsStroke    = true;
                paint.StrokeWidth = lineWidth;
                paint.Color       = lineColor.ToSkia(opacity);
                paint.StrokeCap   = strokeCap.ToSkia();
                paint.StrokeJoin  = strokeJoin.ToSkia();
                paint.StrokeMiter = strokeMiterLimit;
                paint.PathEffect  = strokeStyle != PenStyle.Solid
                    ? strokeStyle.ToSkia(lineWidth, dashArray, dashOffset)
                    : null;
                canvas.DrawPath(path, paint);
            }
        }
示例#8
0
        private void DrawArrows(SKSurface skSurface, IReadOnlyViewport viewport, Route route, int scale)
        {
            const string resourceId = "FamilieWandelPad.RouteImager.Arrow_Up.png";
            var          assembly   = GetType().GetTypeInfo().Assembly;

            SKBitmap resourceBitmap;

            using (var stream = assembly.GetManifestResourceStream(resourceId))
            {
                resourceBitmap = SKBitmap.Decode(stream);
                resourceBitmap = resourceBitmap.Resize(new SKSizeI(25, 25), SKFilterQuality.High);
            }

            var arrowSteps = Distance.FromMeters(50);

            for (var index = 0; index < route.Waypoints.Count; index++)
            {
                var waypoint     = route.Waypoints[index];
                var nextWaypoint = route.Waypoints[(index + 1) % route.Waypoints.Count];

                var a    = new Vector2((float)waypoint.Latitude, (float)waypoint.Longitude);
                var b    = new Vector2((float)nextWaypoint.Latitude, (float)nextWaypoint.Longitude);
                var aToB = b - a; //Vector from A to B

                var steps = Math.Max(
                    Distance.FromMiles(waypoint.Distance(nextWaypoint)).Meters / arrowSteps.Meters, 2
                    );

                for (var step = 1; step < steps; step++)
                {
                    var arrow = a + aToB * (float)(step / steps);

                    var screenPoint = viewport.WorldToScreen(
                        SphericalMercator.FromLonLat(arrow.Y, arrow.X)
                        );

                    skSurface.Canvas.Save();
                    skSurface.Canvas.RotateDegrees((float)waypoint.DegreeBearing(nextWaypoint), (float)screenPoint.X,
                                                   (float)screenPoint.Y);

                    skSurface.Canvas.DrawBitmap(
                        resourceBitmap,
                        (float)screenPoint.X - resourceBitmap.Width / 2f,
                        (float)screenPoint.Y - resourceBitmap.Height / 2f
                        );

                    skSurface.Canvas.Restore();
                    // skSurface.Canvas.DrawCircle((float) screenPoint.X, (float) screenPoint.Y, 10, new SKPaint() {Color = SKColors.Blue});
                }
            }
        }
示例#9
0
        public static UIElement RenderLabel(Geometries.Point position, LabelStyle labelStyle, IReadOnlyViewport viewport,
                                            string labelText)
        {
            var screenPosition  = viewport.WorldToScreen(position);
            var windowsPosition = screenPosition.ToXaml();

            // Set some defaults which should be configurable someday
            const double witdhMargin  = 3.0;
            const double heightMargin = 0.0;

            var textblock = new TextBlock
            {
                Text       = labelText,
                Foreground = new SolidColorBrush(labelStyle.ForeColor.ToXaml()),
                FontFamily = new FontFamily(labelStyle.Font.FontFamily),
                FontSize   = labelStyle.Font.Size,
                Margin     = new Thickness(witdhMargin, heightMargin, witdhMargin, heightMargin),
            };

            // TODO: Halo is not supported by WPF, but we CAN do an outer glow-like effect...
            if (labelStyle.Halo != null)
            {
                System.Windows.Media.Effects.DropShadowEffect haloEffect = new System.Windows.Media.Effects.DropShadowEffect();
                haloEffect.ShadowDepth = 0;
                haloEffect.Color       = labelStyle.Halo.Color.ToXaml();
                haloEffect.Opacity     = haloEffect.Color.A / 255.0;
                haloEffect.BlurRadius  = labelStyle.Halo.Width * 2;
                textblock.Effect       = haloEffect;
            }

            var border = new Border
            {
                // TODO: We have no SymbolCache, so we get problems, if there is a bitmap as background
                Background   = labelStyle.BackColor.ToXaml(rotate: (float)viewport.Rotation),
                CornerRadius = new CornerRadius(4),
                Child        = textblock,
                Opacity      = labelStyle.Opacity,
            };

            DetermineTextWidthAndHeightWpf(out var textWidth, out var textHeight, labelStyle, labelText);

            var offsetX = labelStyle.Offset.IsRelative ? textWidth * labelStyle.Offset.X : labelStyle.Offset.X;
            var offsetY = labelStyle.Offset.IsRelative ? textHeight * labelStyle.Offset.Y : labelStyle.Offset.Y;

            border.SetValue(Canvas.LeftProperty, windowsPosition.X + offsetX
                            - (textWidth + 2 * witdhMargin) * (short)labelStyle.HorizontalAlignment * 0.5f);
            border.SetValue(Canvas.TopProperty, windowsPosition.Y + offsetY
                            - (textHeight + 2 * heightMargin) * (short)labelStyle.VerticalAlignment * 0.5f);

            return(border);
        }
示例#10
0
        private static void UpdateRenderTransform(UIElement renderedGeometry, IReadOnlyViewport viewport)
        {
            var matrix = XamlMedia.Matrix.Identity;

            if (viewport.IsRotated)
            {
                var center = viewport.WorldToScreen(viewport.Center);
                MatrixHelper.RotateAt(ref matrix, viewport.Rotation, center.X, center.Y);
            }

            renderedGeometry.RenderTransform = new XamlMedia.MatrixTransform {
                Matrix = matrix
            };
        }
示例#11
0
        private static XamlMedia.Geometry ConvertSymbol(Point point, SymbolStyle style, IReadOnlyViewport viewport)
        {
            Point p = viewport.WorldToScreen(point);

            var rect = new XamlMedia.RectangleGeometry();

            if (style.BitmapId >= 0)
            {
                var bitmapImage = ((Stream)BitmapRegistry.Instance.Get(style.BitmapId)).ToBitmapImage();
                var width       = bitmapImage.PixelWidth * style.SymbolScale;
                var height      = bitmapImage.PixelHeight * style.SymbolScale;
                rect.Rect = new Rect(p.X - width * 0.5, p.Y - height * 0.5, width, height);
            }

            return(rect);
        }
示例#12
0
        private static void DrawPOIs(SKSurface skSurface, IReadOnlyViewport viewport, Route route, float scale)
        {
            var pois = route.Waypoints
                       .OfType <PointOfInterest>()
                       .OrderBy(p => p.OrderIndex)
                       .ToList();

            var poiStroke = new SKPaint
            {
                Style         = SKPaintStyle.Stroke,
                IsAntialias   = true,
                FilterQuality = SKFilterQuality.High,
                Color         = Color.Black.ToSkia(),
                StrokeWidth   = 10f * scale
            };
            var poiFill = new SKPaint
            {
                Style = SKPaintStyle.Fill,
                Color = Color.White.ToSkia()
            };
            var textPaint = new SKPaint
            {
                Color    = SKColors.Black,
                TextSize = 32f * scale
            };

            foreach (var pointOfInterest in pois)
            {
                var screenPoint = viewport.WorldToScreen(
                    SphericalMercator.FromLonLat(pointOfInterest.Longitude, pointOfInterest.Latitude)
                    );
                var x = (float)screenPoint.X;
                var y = (float)screenPoint.Y;

                var text       = $"{pois.IndexOf(pointOfInterest)}";
                var textBounds = new SKRect();

                textPaint.MeasureText(text, ref textBounds);

                skSurface.Canvas.DrawCircle(x, y, 30f * scale, poiFill);
                skSurface.Canvas.DrawCircle(x, y, 30f * scale, poiStroke);
                skSurface.Canvas.DrawText(text, x - textBounds.MidX, y - textBounds.MidY, textPaint);
            }
        }
示例#13
0
        public static void Draw(SKCanvas canvas, IReadOnlyViewport viewport, IStyle style, IFeature feature,
                                IGeometry geometry, SymbolCache symbolCache, float opacity)
        {
            var point       = geometry as Point;
            var destination = viewport.WorldToScreen(point);

            if (style is CalloutStyle calloutStyle)
            {
                CalloutStyleRenderer.Draw(canvas, viewport, symbolCache, opacity, destination, calloutStyle);
            }
            else if (style is LabelStyle labelStyle)
            {
                LabelRenderer.Draw(canvas, labelStyle, feature, destination, opacity);
            }
            else if (style is SymbolStyle symbolStyle)
            {
                if (symbolStyle.BitmapId >= 0)
                {
                    // todo: Remove this call. ImageStyle should be used instead of SymbolStyle with BitmapId
                    ImageStyleRenderer.Draw(canvas, symbolStyle, destination, symbolCache, opacity, viewport.Rotation);
                }
                else
                {
                    SymbolStyleRenderer.Draw(canvas, symbolStyle, destination, opacity, symbolStyle.SymbolType, viewport.Rotation);
                }
            }
            else if (style is ImageStyle imageStyle)
            {
                ImageStyleRenderer.Draw(canvas, imageStyle, destination, symbolCache, opacity, viewport.Rotation);
            }
            else if (style is VectorStyle vectorStyle)
            {
                // Use the SymbolStyleRenderer and specify Ellipse
                SymbolStyleRenderer.Draw(canvas, vectorStyle, destination, opacity, SymbolType.Ellipse);
            }
            else
            {
                throw new Exception($"Style of type '{style.GetType()}' is not supported for points");
            }
        }
示例#14
0
        public bool Draw(SKCanvas canvas, IReadOnlyViewport viewport, ILayer layer, IFeature feature, IStyle istyle,
                         ISymbolCache symbolCache)
        {
            var style = ((VelocityIndicatorStyle)istyle);

            var position = feature.Geometry as Point;
            var dest     = viewport.WorldToScreen(position);

            var zoom = 1 / (float)viewport.Resolution;

            canvas.Translate((float)dest.X, (float)dest.Y);
            //canvas.Scale(zoom, zoom);

            canvas.RotateDegrees((float)viewport.Rotation, 0.0f, 0.0f);

            //#TODO store paint with shader as static
            using (SKPaint paint = new SKPaint
            {
                Style = SKPaintStyle.StrokeAndFill,
                Color = SKColors.Red,
                StrokeWidth = 4
            })
            {
                //if (style.rotation == 0) //Weird artifacting on 0 rotation, no idea why. Seems Skia bug.
                //    style.rotation = 180;
                //
                //SKMatrix shaderTransform =
                //    SKMatrix.CreateScale((float)viewport.Resolution, (float)viewport.Resolution);
                //if (style.rotation != 0)
                //    shaderTransform = SKMatrix.Concat(shaderTransform, SKMatrix.CreateRotationDegrees(-style.rotation));


                canvas.DrawLine(new SKPoint(0, 0), new SKPoint(-style.velocity.X, style.velocity.Y), paint);
            }



            return(true);
        }
    public bool Draw(Canvas canvas, IReadOnlyViewport viewport, ILayer layer, IFeature feature, IStyle style, ISymbolCache symbolCache)
    {
        if (!(feature.Geometry is global::Mapsui.Geometries.Point worldPoint))
        {
            return(false);
        }

        var screenPoint = viewport.WorldToScreen(worldPoint);

        var color = new XamlMedia.Color()
        {
            R = (byte)rnd.Next(0, 256), G = (byte)rnd.Next(0, 256), B = (byte)rnd.Next(0, 256), A = (byte)(256.0 * layer.Opacity * style.Opacity)
        };

        var path = new XamlShapes.Path
        {
            Fill            = new XamlMedia.SolidColorBrush(color),
            Stroke          = new XamlMedia.SolidColorBrush(XamlColors.Transparent),
            StrokeThickness = 0,
        };

        path.Data = new XamlMedia.EllipseGeometry
        {
            Center  = new XamlPoint(0, 0),
            RadiusX = 20 * 0.5,
            RadiusY = 20 * 0.5
        };

        var matrix = XamlMedia.Matrix.Identity;

        MatrixHelper.InvertY(ref matrix);
        MatrixHelper.Translate(ref matrix, screenPoint.X, screenPoint.Y);

        canvas.Children.Add(path);

        return(true);
    }
示例#16
0
        public static void Draw(SKCanvas canvas, IReadOnlyViewport viewport, IStyle style, IFeature feature, IGeometry geometry,
                                float opacity, SymbolCache symbolCache = null)
        {
            if (style is LabelStyle labelStyle)
            {
                var worldCenter = geometry.BoundingBox.Centroid;
                var center      = viewport.WorldToScreen(worldCenter);
                LabelRenderer.Draw(canvas, labelStyle, feature, (float)center.X, (float)center.Y, opacity);
            }
            else if (style is StyleCollection styleCollection)
            {
                foreach (var s in styleCollection)
                {
                    Draw(canvas, viewport, s, feature, geometry, opacity, symbolCache);
                }
            }
            else if (style is VectorStyle vectorStyle)
            {
                var polygon = (Polygon)geometry;

                float   lineWidth        = 1;
                var     lineColor        = Color.Black;       // default
                var     fillColor        = Color.Gray;        // default
                var     strokeCap        = PenStrokeCap.Butt; // default
                var     strokeJoin       = StrokeJoin.Miter;  // default
                var     strokeMiterLimit = 4f;                // default
                var     strokeStyle      = PenStyle.Solid;    // default
                float[] dashArray        = null;              // default

                if (vectorStyle.Outline != null)
                {
                    lineWidth        = (float)vectorStyle.Outline.Width;
                    lineColor        = vectorStyle.Outline.Color;
                    strokeCap        = vectorStyle.Outline.PenStrokeCap;
                    strokeJoin       = vectorStyle.Outline.StrokeJoin;
                    strokeMiterLimit = vectorStyle.Outline.StrokeMiterLimit;
                    strokeStyle      = vectorStyle.Outline.PenStyle;
                    dashArray        = vectorStyle.Outline.DashArray;
                }

                if (vectorStyle.Fill != null)
                {
                    fillColor = vectorStyle.Fill?.Color;
                }

                using (var path = polygon.ToSkiaPath(viewport, canvas.LocalClipBounds, lineWidth))
                    using (var paintFill = new SKPaint {
                        IsAntialias = true
                    })
                    {
                        // Is there a FillStyle?
                        if (vectorStyle.Fill?.FillStyle == FillStyle.Solid)
                        {
                            paintFill.StrokeWidth = 0;
                            paintFill.Style       = SKPaintStyle.Fill;
                            paintFill.PathEffect  = null;
                            paintFill.Shader      = null;
                            paintFill.Color       = fillColor.ToSkia(opacity);
                            canvas.DrawPath(path, paintFill);
                        }
                        else
                        {
                            paintFill.StrokeWidth = 1;
                            paintFill.Style       = SKPaintStyle.Stroke;
                            paintFill.Shader      = null;
                            paintFill.Color       = fillColor.ToSkia(opacity);
                            var scale    = 10.0f;
                            var fillPath = new SKPath();
                            var matrix   = SKMatrix.MakeScale(scale, scale);

                            switch (vectorStyle.Fill?.FillStyle)
                            {
                            case FillStyle.Cross:
                                fillPath.MoveTo(scale * 0.8f, scale * 0.8f);
                                fillPath.LineTo(0, 0);
                                fillPath.MoveTo(0, scale * 0.8f);
                                fillPath.LineTo(scale * 0.8f, 0);
                                paintFill.PathEffect = SKPathEffect.Create2DPath(matrix, fillPath);
                                break;

                            case FillStyle.DiagonalCross:
                                fillPath.MoveTo(scale, scale);
                                fillPath.LineTo(0, 0);
                                fillPath.MoveTo(0, scale);
                                fillPath.LineTo(scale, 0);
                                paintFill.PathEffect = SKPathEffect.Create2DPath(matrix, fillPath);
                                break;

                            case FillStyle.BackwardDiagonal:
                                fillPath.MoveTo(0, scale);
                                fillPath.LineTo(scale, 0);
                                paintFill.PathEffect = SKPathEffect.Create2DPath(matrix, fillPath);
                                break;

                            case FillStyle.ForwardDiagonal:
                                fillPath.MoveTo(scale, scale);
                                fillPath.LineTo(0, 0);
                                paintFill.PathEffect = SKPathEffect.Create2DPath(matrix, fillPath);
                                break;

                            case FillStyle.Dotted:
                                paintFill.Style = SKPaintStyle.StrokeAndFill;
                                fillPath.AddCircle(scale * 0.5f, scale * 0.5f, scale * 0.35f);
                                paintFill.PathEffect = SKPathEffect.Create2DPath(matrix, fillPath);
                                break;

                            case FillStyle.Horizontal:
                                fillPath.MoveTo(0, scale * 0.5f);
                                fillPath.LineTo(scale, scale * 0.5f);
                                paintFill.PathEffect = SKPathEffect.Create2DPath(matrix, fillPath);
                                break;

                            case FillStyle.Vertical:
                                fillPath.MoveTo(scale * 0.5f, 0);
                                fillPath.LineTo(scale * 0.5f, scale);
                                paintFill.PathEffect = SKPathEffect.Create2DPath(matrix, fillPath);
                                break;

                            case FillStyle.Bitmap:
                                paintFill.Style = SKPaintStyle.Fill;
                                var image = GetImage(symbolCache, vectorStyle.Fill.BitmapId);
                                if (image != null)
                                {
                                    paintFill.Shader = image.ToShader(SKShaderTileMode.Repeat, SKShaderTileMode.Repeat);
                                }
                                break;

                            case FillStyle.BitmapRotated:
                                paintFill.Style = SKPaintStyle.Fill;
                                image           = GetImage(symbolCache, vectorStyle.Fill.BitmapId);
                                if (image != null)
                                {
                                    paintFill.Shader = image.ToShader(SKShaderTileMode.Repeat,
                                                                      SKShaderTileMode.Repeat,
                                                                      SKMatrix.MakeRotation((float)(viewport.Rotation * System.Math.PI / 180.0f), image.Width >> 1, image.Height >> 1));
                                }
                                break;

                            default:
                                paintFill.PathEffect = null;
                                break;
                            }

                            // Do this, because if not, path isn't filled complete
                            using (new SKAutoCanvasRestore(canvas))
                            {
                                canvas.ClipPath(path);
                                var bounds = path.Bounds;
                                // Make sure, that the brush starts with the correct position
                                var inflate = ((int)path.Bounds.Width * 0.3f / scale) * scale;
                                bounds.Inflate(inflate, inflate);
                                // Draw rect with bigger size, which is clipped by path
                                canvas.DrawRect(bounds, paintFill);
                            }
                        }

                        if (vectorStyle.Outline != null)
                        {
                            using (var paintStroke = new SKPaint {
                                IsAntialias = true
                            })
                            {
                                paintStroke.Style       = SKPaintStyle.Stroke;
                                paintStroke.StrokeWidth = lineWidth;
                                paintStroke.Color       = lineColor.ToSkia(opacity);
                                paintStroke.StrokeCap   = strokeCap.ToSkia();
                                paintStroke.StrokeJoin  = strokeJoin.ToSkia();
                                paintStroke.StrokeMiter = strokeMiterLimit;
                                if (strokeStyle != PenStyle.Solid)
                                {
                                    paintStroke.PathEffect = strokeStyle.ToSkia(lineWidth, dashArray);
                                }
                                else
                                {
                                    paintStroke.PathEffect = null;
                                }
                                canvas.DrawPath(path, paintStroke);
                            }
                        }
                    }
            }
        }
        public bool Draw(SKCanvas canvas, IReadOnlyViewport viewport, ILayer layer, IFeature feature, IStyle istyle,
                         ISymbolCache symbolCache)
        {
            var style = ((TiledBitmapStyle)istyle);

            if (style.image == null)
            {
                return(false);
            }

            var position = feature.Geometry.BoundingBox.Centroid;
            var dest     = viewport.WorldToScreen(position);


            var zoom = 1 / (float)viewport.Resolution;

            canvas.Translate((float)dest.X, (float)dest.Y);
            canvas.Scale(zoom, zoom);

            canvas.RotateDegrees((float)viewport.Rotation, 0.0f, 0.0f);
            if (style.rotation != 0)
            {
                canvas.RotateDegrees(style.rotation, 0.0f, 0.0f);
            }

            //#TODO store paint with shader in the style
            using (SKPaint paint = new SKPaint())
            {
                if (style.rotation == 0) //Weird artifacting on 0 rotation, no idea why. Seems Skia bug.
                {
                    style.rotation = 180;
                }

                SKMatrix shaderTransform =
                    SKMatrix.CreateScale((float)viewport.Resolution, (float)viewport.Resolution);
                if (style.rotation != 0)
                {
                    shaderTransform = SKMatrix.Concat(shaderTransform, SKMatrix.CreateRotationDegrees(-style.rotation));
                }



                paint.Shader      = SKShader.CreateImage(style.image, SKShaderTileMode.Repeat, SKShaderTileMode.Repeat, shaderTransform);
                paint.ColorFilter = style.colorFilter;

                //style.image.Encode().SaveTo(File.Create($"P:/{style.image.UniqueId}.png"));

                if (style.ellipse)
                {
                    canvas.DrawOval(0, 0, style.rect.Right, style.rect.Bottom, paint);
                }
                else
                {
                    canvas.DrawRect(style.rect, paint);
                }

                if (style.border)
                {
                    var borderPaint = new SKPaint
                    {
                        Style = SKPaintStyle.Stroke,
                        Color = style.color
                    };


                    if (style.ellipse)
                    {
                        canvas.DrawOval(0, 0, style.rect.Right, style.rect.Bottom, borderPaint);
                    }
                    else
                    {
                        canvas.DrawRect(style.rect, borderPaint);
                    }
                }
            }



            return(true);
        }
示例#18
0
        public bool Draw(SKCanvas canvas, IReadOnlyViewport viewport, ILayer layer, IFeature feature, IStyle istyle,
                         ISymbolCache symbolCache)
        {
            var style = ((MarkerIconStyle)istyle);

            if (style.markerIcon == null)
            {
                return(false);
            }

            var position = feature.Geometry as Point;
            var dest     = viewport.WorldToScreen(position);


            var zoom = 1 / (float)viewport.Resolution;

            canvas.Translate((float)dest.X, (float)dest.Y);
            canvas.Scale(0.7f, 0.7f);

            canvas.RotateDegrees((float)viewport.Rotation, 0.0f, 0.0f);

            SKPoint textOffset = new SKPoint(style.finalSize.Width, style.finalSize.Height / 2);

            if (!string.IsNullOrEmpty(style.text))
            {
                if (zoom > 1.5f)
                {
                    zoom = 1.5f;
                }
                if (zoom < 0.5f)
                {
                    zoom = 0.5f;
                }


                renderPaint.TextSize = 32 * zoom;
                SKRect bounds = new SKRect();
                //renderPaint.GetFontMetrics(out var fontMet);
                //renderPaint.MeasureText(style.text, ref bounds);
                var textHeight = (style.finalSize.Height / 2);
                //if (zoom < 1.5f)
                //{
                //    textHeight += bounds.Height/2;
                //}

                textOffset = new SKPoint(style.finalSize.Width, textHeight);
            }


            if (style.shadow)
            {
                var targetRect   = style.finalRect;
                var shadowOffset = style.ShadowOffset;

                targetRect.Offset(shadowOffset);
                renderPaint.Color       = new SKColor(0, 0, 0, (byte)(style.Opacity * 0.8f * 255));
                renderPaint.ColorFilter = SkiaSharp.SKColorFilter.CreateLighting(renderPaint.Color, new SKColor(0, 0, 0));

                if (style.SymbolRotation != 0)
                {
                    canvas.RotateDegrees(style.SymbolRotation, 0.0f, 0.0f);
                }
                canvas.DrawImage(style.markerIcon, targetRect, renderPaint);
                if (style.SymbolRotation != 0)
                {
                    canvas.RotateDegrees(-style.SymbolRotation, 0.0f, 0.0f);                            //No rotation for text
                }
                //canvas.DrawRect(targetRect, renderPaint);

                if (!string.IsNullOrEmpty(style.text) && zoom > 1)
                {
                    canvas.DrawText(style.text, textOffset + style.ShadowOffset, renderPaint);
                }
            }



            renderPaint.Color       = SKColor.Empty.WithAlpha((byte)(style.Opacity * 255));
            renderPaint.ColorFilter = style.colorFilter;
            if (style.SymbolRotation != 0)
            {
                canvas.RotateDegrees(style.SymbolRotation, 0.0f, 0.0f);
            }
            canvas.DrawImage(style.markerIcon, style.finalRect, renderPaint);
            if (!string.IsNullOrEmpty(style.text))
            {
                if (style.SymbolRotation != 0)
                {
                    canvas.RotateDegrees(-style.SymbolRotation, 0.0f, 0.0f);                            //No rotation for text
                }
                renderPaint.Color       = style.color.WithAlpha((byte)(style.Opacity * 255));
                renderPaint.ColorFilter = null;
                canvas.DrawText(style.text, textOffset, renderPaint);
            }


            return(true);
        }