From 8bb7dc3eb334c490f5e4cebeeac67ca25b0c2b4c Mon Sep 17 00:00:00 2001 From: ClemensFischer Date: Sun, 26 May 2024 20:32:29 +0200 Subject: [PATCH] Avalonia MapGraticule --- .../DependencyPropertyHelper.Avalonia.cs | 8 +- .../Avalonia/MapControl.Avalonia.csproj | 1 - MapControl/Avalonia/MapGraticule.Avalonia.cs | 138 +++++++++++++++ MapControl/Avalonia/MapOverlay.Avalonia.cs | 154 ----------------- MapControl/Avalonia/MapPath.Avalonia.cs | 2 +- MapControl/Avalonia/ViewTransform.Avalonia.cs | 10 +- MapControl/Shared/MapGraticule.cs | 6 +- MapControl/UWP/MapControl.UWP.csproj | 3 - MapControl/WPF/MapGraticule.WPF.cs | 47 +++++- MapControl/WPF/MapOverlay.WPF.cs | 157 ------------------ MapControl/WinUI/MapGraticule.WinUI.cs | 59 +++++-- MapControl/WinUI/MapOverlay.WinUI.cs | 154 ----------------- SampleApps/AvaloniaApp/MainWindow.axaml | 3 + 13 files changed, 247 insertions(+), 495 deletions(-) create mode 100644 MapControl/Avalonia/MapGraticule.Avalonia.cs delete mode 100644 MapControl/Avalonia/MapOverlay.Avalonia.cs delete mode 100644 MapControl/WPF/MapOverlay.WPF.cs delete mode 100644 MapControl/WinUI/MapOverlay.WinUI.cs diff --git a/MapControl/Avalonia/DependencyPropertyHelper.Avalonia.cs b/MapControl/Avalonia/DependencyPropertyHelper.Avalonia.cs index 2c29d4bb..0415053c 100644 --- a/MapControl/Avalonia/DependencyPropertyHelper.Avalonia.cs +++ b/MapControl/Avalonia/DependencyPropertyHelper.Avalonia.cs @@ -24,7 +24,7 @@ namespace MapControl if (coerce != null) { // do not coerce default value - coerceFunc = (obj, value) => value.Equals(defaultValue) ? value : coerce((TOwner)obj, value); + coerceFunc = (obj, value) => Equals(value, defaultValue) ? value : coerce((TOwner)obj, value); } var bindingMode = bindTwoWayByDefault ? Avalonia.Data.BindingMode.TwoWay : Avalonia.Data.BindingMode.OneWay; @@ -57,11 +57,17 @@ namespace MapControl public static StyledProperty AddOwner( StyledProperty property, + TValue defaultValue = default, Action changed = null) where TOwner : AvaloniaObject { var newProperty = property.AddOwner(); + if (!Equals(defaultValue, newProperty.GetMetadata(typeof(TOwner)).DefaultValue)) + { + newProperty.OverrideMetadata(new StyledPropertyMetadata(defaultValue)); + } + if (changed != null) { newProperty.Changed.AddClassHandler((o, e) => changed(o, e.OldValue.Value, e.NewValue.Value)); diff --git a/MapControl/Avalonia/MapControl.Avalonia.csproj b/MapControl/Avalonia/MapControl.Avalonia.csproj index 4665862f..4a883d5f 100644 --- a/MapControl/Avalonia/MapControl.Avalonia.csproj +++ b/MapControl/Avalonia/MapControl.Avalonia.csproj @@ -25,7 +25,6 @@ - diff --git a/MapControl/Avalonia/MapGraticule.Avalonia.cs b/MapControl/Avalonia/MapGraticule.Avalonia.cs new file mode 100644 index 00000000..805f2e12 --- /dev/null +++ b/MapControl/Avalonia/MapGraticule.Avalonia.cs @@ -0,0 +1,138 @@ +// XAML Map Control - https://github.com/ClemensFischer/XAML-Map-Control +// Copyright © 2024 Clemens Fischer +// Licensed under the Microsoft Public License (Ms-PL) + +using Avalonia.Controls; +using Avalonia.Controls.Documents; +using Avalonia.Controls.Shapes; +using Avalonia.Media; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; + +namespace MapControl +{ + public partial class MapGraticule : Control, IMapElement + { + public static readonly StyledProperty ForegroundProperty = + DependencyPropertyHelper.AddOwner(TextElement.ForegroundProperty, null, + (graticule, oldValue, newValue) => graticule.InvalidateVisual()); + + public static readonly StyledProperty FontFamilyProperty = + DependencyPropertyHelper.AddOwner(TextElement.FontFamilyProperty); + + public static readonly StyledProperty FontSizeProperty = + DependencyPropertyHelper.AddOwner(TextElement.FontSizeProperty); + + public static readonly StyledProperty StrokeThicknessProperty = + DependencyPropertyHelper.AddOwner(Shape.StrokeThicknessProperty, 0.5); + + public IBrush Foreground + { + get => GetValue(ForegroundProperty); + set => SetValue(ForegroundProperty, value); + } + + public FontFamily FontFamily + { + get => GetValue(FontFamilyProperty); + set => SetValue(FontFamilyProperty, value); + } + + public double FontSize + { + get => GetValue(FontSizeProperty); + set => SetValue(FontSizeProperty, value); + } + + public double StrokeThickness + { + get => GetValue(StrokeThicknessProperty); + set => SetValue(StrokeThicknessProperty, value); + } + + private MapBase parentMap; + + /// + /// Implements IMapElement.ParentMap. + /// + public MapBase ParentMap + { + get => parentMap; + set + { + if (parentMap != null) + { + parentMap.ViewportChanged -= OnViewportChanged; + } + + parentMap = value; + + if (parentMap != null) + { + parentMap.ViewportChanged += OnViewportChanged; + } + } + } + + private void OnViewportChanged(object sender, ViewportChangedEventArgs e) + { + InvalidateVisual(); + } + + public override void Render(DrawingContext drawingContext) + { + if (parentMap != null) + { + var pathGeometry = new PathGeometry(); + + var labels = DrawGraticule(pathGeometry.Figures); + + var pen = new Pen + { + Brush = Foreground, + Thickness = StrokeThickness, + }; + + drawingContext.DrawGeometry(null, pen, pathGeometry); + + if (labels.Count > 0) + { + var typeface = new Typeface(FontFamily, FontStyle.Normal, FontWeight.Normal, FontStretch.Normal); + + foreach (var label in labels) + { + var latText = new FormattedText(label.LatitudeText, + CultureInfo.InvariantCulture, FlowDirection.LeftToRight, typeface, FontSize, Foreground); + + var lonText = new FormattedText(label.LongitudeText, + CultureInfo.InvariantCulture, FlowDirection.LeftToRight, typeface, FontSize, Foreground); + + var x = StrokeThickness / 2d + 2d; + var y1 = -StrokeThickness / 2d - latText.Height; + var y2 = StrokeThickness / 2d; + + using var pushState = drawingContext.PushTransform( + Matrix.CreateRotation(Matrix.ToRadians(label.Rotation)) * + Matrix.CreateTranslation(label.X, label.Y)); + + drawingContext.DrawText(latText, new Point(x, y1)); + drawingContext.DrawText(lonText, new Point(x, y2)); + } + } + } + } + + private static PathFigure CreatePolylineFigure(IEnumerable points) + { + var figure = new PathFigure + { + StartPoint = points.First(), + IsFilled = false + }; + + figure.Segments.Add(new PolyLineSegment(points.Skip(1))); + return figure; + } + } +} diff --git a/MapControl/Avalonia/MapOverlay.Avalonia.cs b/MapControl/Avalonia/MapOverlay.Avalonia.cs deleted file mode 100644 index ae3d3e3e..00000000 --- a/MapControl/Avalonia/MapOverlay.Avalonia.cs +++ /dev/null @@ -1,154 +0,0 @@ -// XAML Map Control - https://github.com/ClemensFischer/XAML-Map-Control -// Copyright © 2024 Clemens Fischer -// Licensed under the Microsoft Public License (Ms-PL) - -using Avalonia.Collections; -using Avalonia.Controls.Documents; -using Avalonia.Controls.Shapes; -using Avalonia.Media; - -namespace MapControl -{ - public class MapOverlay : MapPanel - { - public static readonly StyledProperty FontFamilyProperty = - DependencyPropertyHelper.AddOwner(TextElement.FontFamilyProperty); - - public static readonly StyledProperty FontSizeProperty = - DependencyPropertyHelper.AddOwner(TextElement.FontSizeProperty); - - public static readonly StyledProperty FontStyleProperty = - DependencyPropertyHelper.AddOwner(TextElement.FontStyleProperty); - - public static readonly StyledProperty FontStretchProperty = - DependencyPropertyHelper.AddOwner(TextElement.FontStretchProperty); - - public static readonly StyledProperty FontWeightProperty = - DependencyPropertyHelper.AddOwner(TextElement.FontWeightProperty); - - public static readonly StyledProperty ForegroundProperty = - DependencyPropertyHelper.AddOwner(TextElement.ForegroundProperty); - - public static readonly StyledProperty StrokeProperty = - DependencyPropertyHelper.AddOwner(Shape.StrokeProperty); - - public static readonly StyledProperty StrokeThicknessProperty = - DependencyPropertyHelper.Register(nameof(StrokeThickness), 1d); - - public static readonly StyledProperty> StrokeDashArrayProperty = - DependencyPropertyHelper.AddOwner>(Shape.StrokeDashArrayProperty); - - public static readonly StyledProperty StrokeDashOffsetProperty = - DependencyPropertyHelper.AddOwner(Shape.StrokeDashOffsetProperty); - - public static readonly StyledProperty StrokeLineCapProperty = - DependencyPropertyHelper.AddOwner(Shape.StrokeLineCapProperty); - - public static readonly StyledProperty StrokeLineJoinProperty = - DependencyPropertyHelper.AddOwner(Shape.StrokeJoinProperty); - - public static readonly StyledProperty StrokeMiterLimitProperty = - DependencyPropertyHelper.Register(nameof(StrokeMiterLimit)); - - public FontFamily FontFamily - { - get => GetValue(FontFamilyProperty); - set => SetValue(FontFamilyProperty, value); - } - - public double FontSize - { - get => GetValue(FontSizeProperty); - set => SetValue(FontSizeProperty, value); - } - - public FontStyle FontStyle - { - get => GetValue(FontStyleProperty); - set => SetValue(FontStyleProperty, value); - } - - public FontStretch FontStretch - { - get => GetValue(FontStretchProperty); - set => SetValue(FontStretchProperty, value); - } - - public FontWeight FontWeight - { - get => GetValue(FontWeightProperty); - set => SetValue(FontWeightProperty, value); - } - - public IBrush Foreground - { - get => GetValue(ForegroundProperty); - set => SetValue(ForegroundProperty, value); - } - - public IBrush Stroke - { - get => GetValue(StrokeProperty); - set => SetValue(StrokeProperty, value); - } - - public double StrokeThickness - { - get => GetValue(StrokeThicknessProperty); - set => SetValue(StrokeThicknessProperty, value); - } - - public AvaloniaList StrokeDashArray - { - get => GetValue(StrokeDashArrayProperty); - set => SetValue(StrokeDashArrayProperty, value); - } - - public double StrokeDashOffset - { - get => GetValue(StrokeDashOffsetProperty); - set => SetValue(StrokeDashOffsetProperty, value); - } - - public PenLineCap StrokeLineCap - { - get => GetValue(StrokeLineCapProperty); - set => SetValue(StrokeLineCapProperty, value); - } - - public PenLineJoin StrokeLineJoin - { - get => GetValue(StrokeLineJoinProperty); - set => SetValue(StrokeLineJoinProperty, value); - } - - public double StrokeMiterLimit - { - get => (double)GetValue(StrokeMiterLimitProperty); - set => SetValue(StrokeMiterLimitProperty, value); - } - - public Pen CreatePen() - { - return new Pen - { - Brush = Stroke, - Thickness = StrokeThickness, - LineJoin = StrokeLineJoin, - MiterLimit = StrokeMiterLimit, - LineCap = StrokeLineCap, - DashStyle = new DashStyle(StrokeDashArray, StrokeDashOffset) - }; - } - - protected override void OnInitialized() - { - base.OnInitialized(); - - if (Stroke == null) - { - this.SetBinding(StrokeProperty, this.CreateBinding(nameof(Foreground))); - } - } - } -} diff --git a/MapControl/Avalonia/MapPath.Avalonia.cs b/MapControl/Avalonia/MapPath.Avalonia.cs index 55262031..0b74f9bf 100644 --- a/MapControl/Avalonia/MapPath.Avalonia.cs +++ b/MapControl/Avalonia/MapPath.Avalonia.cs @@ -15,7 +15,7 @@ namespace MapControl } public static readonly StyledProperty DataProperty = - DependencyPropertyHelper.AddOwner(Path.DataProperty, + DependencyPropertyHelper.AddOwner(Path.DataProperty, null, (path, oldValue, newValue) => path.UpdateData()); public Geometry Data diff --git a/MapControl/Avalonia/ViewTransform.Avalonia.cs b/MapControl/Avalonia/ViewTransform.Avalonia.cs index 6665d259..286431c0 100644 --- a/MapControl/Avalonia/ViewTransform.Avalonia.cs +++ b/MapControl/Avalonia/ViewTransform.Avalonia.cs @@ -56,7 +56,7 @@ namespace MapControl MapToViewMatrix = Matrix.CreateTranslation(-mapCenter.X, -mapCenter.Y) * Matrix.CreateScale(scale, -scale) - * Matrix.CreateRotation(Rotation * Math.PI / 180d) + * Matrix.CreateRotation(Matrix.ToRadians(Rotation)) * Matrix.CreateTranslation(viewCenter.X, viewCenter.Y); ViewToMapMatrix = MapToViewMatrix.Invert(); @@ -95,7 +95,7 @@ namespace MapControl var scale = GetMapScale(relativeScale); return Matrix.CreateScale(scale.X, scale.Y) - * Matrix.CreateRotation(Rotation * Math.PI / 180d); + * Matrix.CreateRotation(Matrix.ToRadians(Rotation)); } /// @@ -116,7 +116,7 @@ namespace MapControl var transformScale = Scale / tileMatrixScale; return Matrix.CreateScale(transformScale, transformScale) - * Matrix.CreateRotation(Rotation * Math.PI / 180d) + * Matrix.CreateRotation(Matrix.ToRadians(Rotation)) * Matrix.CreateTranslation(viewOrigin.X, viewOrigin.Y); } @@ -133,7 +133,7 @@ namespace MapControl var transform = Matrix.CreateScale(transformScale, transformScale) - * Matrix.CreateRotation(-Rotation * Math.PI / 180d); + * Matrix.CreateRotation(Matrix.ToRadians(-Rotation)); // Translate origin to tile matrix origin in pixels. // @@ -152,7 +152,7 @@ namespace MapControl double translation2X, double translation2Y) { return Matrix.CreateTranslation(translation1X, translation1Y) - * Matrix.CreateRotation(rotation * Math.PI / 180d) + * Matrix.CreateRotation(Matrix.ToRadians(rotation)) * Matrix.CreateTranslation(translation2X, translation2Y); } } diff --git a/MapControl/Shared/MapGraticule.cs b/MapControl/Shared/MapGraticule.cs index 1a198365..97edb726 100644 --- a/MapControl/Shared/MapGraticule.cs +++ b/MapControl/Shared/MapGraticule.cs @@ -15,6 +15,10 @@ using Windows.UI.Xaml.Media; #elif WINUI using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Media; +#elif AVALONIA +using Avalonia.Media; +using DependencyProperty = Avalonia.AvaloniaProperty; +using PathFigureCollection = Avalonia.Media.PathFigures; #endif namespace MapControl @@ -22,7 +26,7 @@ namespace MapControl /// /// Draws a graticule overlay. /// - public partial class MapGraticule : MapOverlay + public partial class MapGraticule { private class Label { diff --git a/MapControl/UWP/MapControl.UWP.csproj b/MapControl/UWP/MapControl.UWP.csproj index 67a50816..05a633ee 100644 --- a/MapControl/UWP/MapControl.UWP.csproj +++ b/MapControl/UWP/MapControl.UWP.csproj @@ -248,9 +248,6 @@ MapItemsControl.WinUI.cs - - MapOverlay.WinUI.cs - MapPanel.WinUI.cs diff --git a/MapControl/WPF/MapGraticule.WPF.cs b/MapControl/WPF/MapGraticule.WPF.cs index e8b78a37..7b86937d 100644 --- a/MapControl/WPF/MapGraticule.WPF.cs +++ b/MapControl/WPF/MapGraticule.WPF.cs @@ -6,31 +6,66 @@ using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Windows; +using System.Windows.Controls; using System.Windows.Media; namespace MapControl { - public partial class MapGraticule + public partial class MapGraticule : Control, IMapElement { - static MapGraticule() + public static readonly DependencyProperty StrokeThicknessProperty = + DependencyPropertyHelper.Register(nameof(StrokeThickness), 0.5); + + public double StrokeThickness { - StrokeThicknessProperty.OverrideMetadata(typeof(MapGraticule), new FrameworkPropertyMetadata(0.5)); + get => (double)GetValue(StrokeThicknessProperty); + set => SetValue(StrokeThicknessProperty, value); } - protected override void OnViewportChanged(ViewportChangedEventArgs e) + private MapBase parentMap; + + /// + /// Implements IMapElement.ParentMap. + /// + public MapBase ParentMap + { + get => parentMap; + set + { + if (parentMap != null) + { + parentMap.ViewportChanged -= OnViewportChanged; + } + + parentMap = value; + + if (parentMap != null) + { + parentMap.ViewportChanged += OnViewportChanged; + } + } + } + + private void OnViewportChanged(object sender, ViewportChangedEventArgs e) { InvalidateVisual(); } protected override void OnRender(DrawingContext drawingContext) { - if (ParentMap != null) + if (parentMap != null) { var pathGeometry = new PathGeometry(); var labels = DrawGraticule(pathGeometry.Figures); - drawingContext.DrawGeometry(null, CreatePen(), pathGeometry); + var pen = new Pen + { + Brush = Foreground, + Thickness = StrokeThickness, + }; + + drawingContext.DrawGeometry(null, pen, pathGeometry); if (labels.Count > 0) { diff --git a/MapControl/WPF/MapOverlay.WPF.cs b/MapControl/WPF/MapOverlay.WPF.cs deleted file mode 100644 index 1c1f172f..00000000 --- a/MapControl/WPF/MapOverlay.WPF.cs +++ /dev/null @@ -1,157 +0,0 @@ -// XAML Map Control - https://github.com/ClemensFischer/XAML-Map-Control -// Copyright © 2024 Clemens Fischer -// Licensed under the Microsoft Public License (Ms-PL) - -using System; -using System.Windows; -using System.Windows.Documents; -using System.Windows.Media; -using System.Windows.Shapes; - -namespace MapControl -{ - public class MapOverlay : MapPanel - { - public static readonly DependencyProperty FontFamilyProperty = - DependencyPropertyHelper.AddOwner(TextElement.FontFamilyProperty); - - public static readonly DependencyProperty FontSizeProperty = - DependencyPropertyHelper.AddOwner(TextElement.FontSizeProperty); - - public static readonly DependencyProperty FontStyleProperty = - DependencyPropertyHelper.AddOwner(TextElement.FontStyleProperty); - - public static readonly DependencyProperty FontStretchProperty = - DependencyPropertyHelper.AddOwner(TextElement.FontStretchProperty); - - public static readonly DependencyProperty FontWeightProperty = - DependencyPropertyHelper.AddOwner(TextElement.FontWeightProperty); - - public static readonly DependencyProperty ForegroundProperty = - DependencyPropertyHelper.AddOwner(TextElement.ForegroundProperty); - - public static readonly DependencyProperty StrokeProperty = - DependencyPropertyHelper.AddOwner(Shape.StrokeProperty); - - public static readonly DependencyProperty StrokeThicknessProperty = - DependencyPropertyHelper.AddOwner(Shape.StrokeThicknessProperty); - - public static readonly DependencyProperty StrokeDashArrayProperty = - DependencyPropertyHelper.AddOwner(Shape.StrokeDashArrayProperty); - - public static readonly DependencyProperty StrokeDashOffsetProperty = - DependencyPropertyHelper.AddOwner(Shape.StrokeDashOffsetProperty); - - public static readonly DependencyProperty StrokeLineCapProperty = - DependencyPropertyHelper.AddOwner(Shape.StrokeDashCapProperty); - - public static readonly DependencyProperty StrokeLineJoinProperty = - DependencyPropertyHelper.AddOwner(Shape.StrokeLineJoinProperty); - - public static readonly DependencyProperty StrokeMiterLimitProperty = - DependencyPropertyHelper.AddOwner(Shape.StrokeMiterLimitProperty); - - public FontFamily FontFamily - { - get => (FontFamily)GetValue(FontFamilyProperty); - set => SetValue(FontFamilyProperty, value); - } - - public double FontSize - { - get => (double)GetValue(FontSizeProperty); - set => SetValue(FontSizeProperty, value); - } - - public FontStyle FontStyle - { - get => (FontStyle)GetValue(FontStyleProperty); - set => SetValue(FontStyleProperty, value); - } - - public FontStretch FontStretch - { - get => (FontStretch)GetValue(FontStretchProperty); - set => SetValue(FontStretchProperty, value); - } - - public FontWeight FontWeight - { - get => (FontWeight)GetValue(FontWeightProperty); - set => SetValue(FontWeightProperty, value); - } - - public Brush Foreground - { - get => (Brush)GetValue(ForegroundProperty); - set => SetValue(ForegroundProperty, value); - } - - public Brush Stroke - { - get => (Brush)GetValue(StrokeProperty); - set => SetValue(StrokeProperty, value); - } - - public double StrokeThickness - { - get => (double)GetValue(StrokeThicknessProperty); - set => SetValue(StrokeThicknessProperty, value); - } - - public DoubleCollection StrokeDashArray - { - get => (DoubleCollection)GetValue(StrokeDashArrayProperty); - set => SetValue(StrokeDashArrayProperty, value); - } - - public double StrokeDashOffset - { - get => (double)GetValue(StrokeDashOffsetProperty); - set => SetValue(StrokeDashOffsetProperty, value); - } - - public PenLineCap StrokeLineCap - { - get => (PenLineCap)GetValue(StrokeLineCapProperty); - set => SetValue(StrokeLineCapProperty, value); - } - - public PenLineJoin StrokeLineJoin - { - get => (PenLineJoin)GetValue(StrokeLineJoinProperty); - set => SetValue(StrokeLineJoinProperty, value); - } - - public double StrokeMiterLimit - { - get => (double)GetValue(StrokeMiterLimitProperty); - set => SetValue(StrokeMiterLimitProperty, value); - } - - public Pen CreatePen() - { - return new Pen - { - Brush = Stroke, - Thickness = StrokeThickness, - LineJoin = StrokeLineJoin, - MiterLimit = StrokeMiterLimit, - StartLineCap = StrokeLineCap, - EndLineCap = StrokeLineCap, - DashCap = StrokeLineCap, - DashStyle = new DashStyle(StrokeDashArray, StrokeDashOffset) - }; - } - - protected override void OnInitialized(EventArgs e) - { - base.OnInitialized(e); - - if (Stroke == null) - { - SetBinding(StrokeProperty, this.CreateBinding(nameof(Foreground))); - } - } - } -} diff --git a/MapControl/WinUI/MapGraticule.WinUI.cs b/MapControl/WinUI/MapGraticule.WinUI.cs index 87aea3d6..f44bac48 100644 --- a/MapControl/WinUI/MapGraticule.WinUI.cs +++ b/MapControl/WinUI/MapGraticule.WinUI.cs @@ -6,10 +6,12 @@ using Windows.Foundation; using System.Collections.Generic; using System.Linq; #if UWP +using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Media; using Windows.UI.Xaml.Shapes; #else +using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Controls; using Microsoft.UI.Xaml.Media; using Microsoft.UI.Xaml.Shapes; @@ -17,13 +19,54 @@ using Microsoft.UI.Xaml.Shapes; namespace MapControl { - public partial class MapGraticule + public partial class MapGraticule : MapPanel { + public static readonly DependencyProperty ForegroundProperty = + DependencyPropertyHelper.Register(nameof(Foreground)); + + public static readonly DependencyProperty FontFamilyProperty = + DependencyPropertyHelper.Register(nameof(FontFamily)); + + public static readonly DependencyProperty FontSizeProperty = + DependencyPropertyHelper.Register(nameof(FontSize), 12d); + + public static readonly DependencyProperty StrokeThicknessProperty = + DependencyPropertyHelper.Register(nameof(StrokeThickness), 0.5); + private readonly Path path = new Path { Data = new PathGeometry() }; - public MapGraticule() + public Brush Foreground { - StrokeThickness = 0.5; + get => (Brush)GetValue(ForegroundProperty); + set => SetValue(ForegroundProperty, value); + } + + public FontFamily FontFamily + { + get => (FontFamily)GetValue(FontFamilyProperty); + set => SetValue(FontFamilyProperty, value); + } + + public double FontSize + { + get => (double)GetValue(FontSizeProperty); + set => SetValue(FontSizeProperty, value); + } + + public double StrokeThickness + { + get => (double)GetValue(StrokeThicknessProperty); + set => SetValue(StrokeThicknessProperty, value); + } + + protected override void SetParentMap(MapBase map) + { + if (map != null && Foreground == null) + { + SetBinding(ForegroundProperty, map.CreateBinding(nameof(Foreground))); + } + + base.SetParentMap(map); } protected override void OnViewportChanged(ViewportChangedEventArgs e) @@ -32,13 +75,8 @@ namespace MapControl if (Children.Count == 0) { - path.SetBinding(Shape.StrokeProperty, this.CreateBinding(nameof(Stroke))); + path.SetBinding(Shape.StrokeProperty, this.CreateBinding(nameof(Foreground))); path.SetBinding(Shape.StrokeThicknessProperty, this.CreateBinding(nameof(StrokeThickness))); - path.SetBinding(Shape.StrokeStartLineCapProperty, this.CreateBinding(nameof(StrokeLineCap))); - path.SetBinding(Shape.StrokeEndLineCapProperty, this.CreateBinding(nameof(StrokeLineCap))); - path.SetBinding(Shape.StrokeDashCapProperty, this.CreateBinding(nameof(StrokeLineCap))); - path.SetBinding(Shape.StrokeDashArrayProperty, this.CreateBinding(nameof(StrokeDashArray))); - path.SetBinding(Shape.StrokeDashOffsetProperty, this.CreateBinding(nameof(StrokeDashOffset))); Children.Add(path); } @@ -57,9 +95,6 @@ namespace MapControl { textBlock = new TextBlock { RenderTransform = new MatrixTransform() }; textBlock.SetBinding(TextBlock.FontSizeProperty, this.CreateBinding(nameof(FontSize))); - textBlock.SetBinding(TextBlock.FontStyleProperty, this.CreateBinding(nameof(FontStyle))); - textBlock.SetBinding(TextBlock.FontStretchProperty, this.CreateBinding(nameof(FontStretch))); - textBlock.SetBinding(TextBlock.FontWeightProperty, this.CreateBinding(nameof(FontWeight))); textBlock.SetBinding(TextBlock.ForegroundProperty, this.CreateBinding(nameof(Foreground))); if (FontFamily != null) diff --git a/MapControl/WinUI/MapOverlay.WinUI.cs b/MapControl/WinUI/MapOverlay.WinUI.cs deleted file mode 100644 index 79c99172..00000000 --- a/MapControl/WinUI/MapOverlay.WinUI.cs +++ /dev/null @@ -1,154 +0,0 @@ -// XAML Map Control - https://github.com/ClemensFischer/XAML-Map-Control -// Copyright © 2024 Clemens Fischer -// Licensed under the Microsoft Public License (Ms-PL) - -using Windows.UI.Text; -#if UWP -using Windows.UI.Xaml; -using Windows.UI.Xaml.Media; -#else -using Microsoft.UI.Text; -using Microsoft.UI.Xaml; -using Microsoft.UI.Xaml.Media; -#endif - -namespace MapControl -{ - public class MapOverlay : MapPanel - { - public static readonly DependencyProperty FontFamilyProperty = - DependencyPropertyHelper.Register(nameof(FontFamily)); - - public static readonly DependencyProperty FontSizeProperty = - DependencyPropertyHelper.Register(nameof(FontSize), 12d); - - public static readonly DependencyProperty FontStyleProperty = - DependencyPropertyHelper.Register(nameof(FontStyle), FontStyle.Normal); - - public static readonly DependencyProperty FontStretchProperty = - DependencyPropertyHelper.Register(nameof(FontStretch), FontStretch.Normal); - - public static readonly DependencyProperty FontWeightProperty = - DependencyPropertyHelper.Register(nameof(FontWeight), FontWeights.Normal); - - public static readonly DependencyProperty ForegroundProperty = - DependencyPropertyHelper.Register(nameof(Foreground)); - - public static readonly DependencyProperty StrokeProperty = - DependencyPropertyHelper.Register(nameof(Stroke)); - - public static readonly DependencyProperty StrokeThicknessProperty = - DependencyPropertyHelper.Register(nameof(StrokeThickness), 1d); - - public static readonly DependencyProperty StrokeDashArrayProperty = - DependencyPropertyHelper.Register(nameof(StrokeDashArray)); - - public static readonly DependencyProperty StrokeDashOffsetProperty = - DependencyPropertyHelper.Register(nameof(StrokeDashOffset)); - - public static readonly DependencyProperty StrokeLineCapProperty = - DependencyPropertyHelper.Register(nameof(StrokeLineCap), PenLineCap.Flat); - - public static readonly DependencyProperty StrokeLineJoinProperty = - DependencyPropertyHelper.Register(nameof(StrokeLineJoin), PenLineJoin.Miter); - - public static readonly DependencyProperty StrokeMiterLimitProperty = - DependencyPropertyHelper.Register(nameof(StrokeMiterLimit), 1d); - - public FontFamily FontFamily - { - get => (FontFamily)GetValue(FontFamilyProperty); - set => SetValue(FontFamilyProperty, value); - } - - public double FontSize - { - get => (double)GetValue(FontSizeProperty); - set => SetValue(FontSizeProperty, value); - } - - public FontStyle FontStyle - { - get => (FontStyle)GetValue(FontStyleProperty); - set => SetValue(FontStyleProperty, value); - } - - public FontStretch FontStretch - { - get => (FontStretch)GetValue(FontStretchProperty); - set => SetValue(FontStretchProperty, value); - } - - public FontWeight FontWeight - { - get => (FontWeight)GetValue(FontWeightProperty); - set => SetValue(FontWeightProperty, value); - } - - public Brush Foreground - { - get => (Brush)GetValue(ForegroundProperty); - set => SetValue(ForegroundProperty, value); - } - - public Brush Stroke - { - get => (Brush)GetValue(StrokeProperty); - set => SetValue(StrokeProperty, value); - } - - public double StrokeThickness - { - get => (double)GetValue(StrokeThicknessProperty); - set => SetValue(StrokeThicknessProperty, value); - } - - public DoubleCollection StrokeDashArray - { - get => (DoubleCollection)GetValue(StrokeDashArrayProperty); - set => SetValue(StrokeDashArrayProperty, value); - } - - public double StrokeDashOffset - { - get => (double)GetValue(StrokeDashOffsetProperty); - set => SetValue(StrokeDashOffsetProperty, value); - } - - public PenLineCap StrokeLineCap - { - get => (PenLineCap)GetValue(StrokeLineCapProperty); - set => SetValue(StrokeLineCapProperty, value); - } - - public PenLineJoin StrokeLineJoin - { - get => (PenLineJoin)GetValue(StrokeLineJoinProperty); - set => SetValue(StrokeLineJoinProperty, value); - } - - public double StrokeMiterLimit - { - get => (double)GetValue(StrokeMiterLimitProperty); - set => SetValue(StrokeMiterLimitProperty, value); - } - - protected override void SetParentMap(MapBase map) - { - if (map != null) - { - if (Foreground == null) - { - SetBinding(ForegroundProperty, map.CreateBinding(nameof(Foreground))); - } - - if (Stroke == null) - { - SetBinding(StrokeProperty, this.CreateBinding(nameof(Foreground))); - } - } - - base.SetParentMap(map); - } - } -} diff --git a/SampleApps/AvaloniaApp/MainWindow.axaml b/SampleApps/AvaloniaApp/MainWindow.axaml index 86ec5163..a29a7c7a 100644 --- a/SampleApps/AvaloniaApp/MainWindow.axaml +++ b/SampleApps/AvaloniaApp/MainWindow.axaml @@ -102,6 +102,9 @@ Description="© [terrestris GmbH & Co. KG](http://ows.terrestris.de/) © [OpenStreetMap contributors](http://www.openstreetmap.org/copyright)"/> + + +