From 25d4d7f4175289cc5bbfdae6dfaf66f08870f1c5 Mon Sep 17 00:00:00 2001 From: ClemensFischer Date: Sat, 25 May 2024 18:58:51 +0200 Subject: [PATCH] Avalonia MapPath --- .../DependencyPropertyHelper.Avalonia.cs | 12 ++- MapControl/Avalonia/MapBase.Avalonia.cs | 2 +- .../Avalonia/MapControl.Avalonia.csproj | 1 - MapControl/Avalonia/MapPath.Avalonia.cs | 101 ++++++++++++++++++ MapControl/Shared/MapImageLayer.cs | 3 +- MapControl/Shared/MapPath.cs | 3 + MapControl/Shared/MapTileLayerBase.cs | 3 +- MapControl/Shared/Tile.cs | 6 +- 8 files changed, 120 insertions(+), 11 deletions(-) create mode 100644 MapControl/Avalonia/MapPath.Avalonia.cs diff --git a/MapControl/Avalonia/DependencyPropertyHelper.Avalonia.cs b/MapControl/Avalonia/DependencyPropertyHelper.Avalonia.cs index a41ebe03..2c29d4bb 100644 --- a/MapControl/Avalonia/DependencyPropertyHelper.Avalonia.cs +++ b/MapControl/Avalonia/DependencyPropertyHelper.Avalonia.cs @@ -56,10 +56,18 @@ namespace MapControl } public static StyledProperty AddOwner( - StyledProperty property) + StyledProperty property, + Action changed = null) where TOwner : AvaloniaObject { - return property.AddOwner(); + var newProperty = property.AddOwner(); + + if (changed != null) + { + newProperty.Changed.AddClassHandler((o, e) => changed(o, e.OldValue.Value, e.NewValue.Value)); + } + + return newProperty; } public static StyledProperty AddOwner( diff --git a/MapControl/Avalonia/MapBase.Avalonia.cs b/MapControl/Avalonia/MapBase.Avalonia.cs index 0701ab72..5a758090 100644 --- a/MapControl/Avalonia/MapBase.Avalonia.cs +++ b/MapControl/Avalonia/MapBase.Avalonia.cs @@ -112,7 +112,7 @@ namespace MapControl /// public double ViewScale { - get => (double)GetValue(ViewScaleProperty); + get => GetValue(ViewScaleProperty); private set => RaisePropertyChanged(ViewScaleProperty, double.NaN, value); } diff --git a/MapControl/Avalonia/MapControl.Avalonia.csproj b/MapControl/Avalonia/MapControl.Avalonia.csproj index bfe0e043..ee1087eb 100644 --- a/MapControl/Avalonia/MapControl.Avalonia.csproj +++ b/MapControl/Avalonia/MapControl.Avalonia.csproj @@ -28,7 +28,6 @@ - diff --git a/MapControl/Avalonia/MapPath.Avalonia.cs b/MapControl/Avalonia/MapPath.Avalonia.cs new file mode 100644 index 00000000..df8cceeb --- /dev/null +++ b/MapControl/Avalonia/MapPath.Avalonia.cs @@ -0,0 +1,101 @@ +// 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.Shapes; +using Avalonia.Media; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Linq; + +namespace MapControl +{ + public partial class MapPath : Shape + { + public MapPath() + { + Stretch = Stretch.None; + } + + public static readonly StyledProperty DataProperty = + DependencyPropertyHelper.AddOwner(Path.DataProperty, + (path, oldValue, newValue) => path.DataPropertyChanged(oldValue, newValue)); + + public Geometry Data + { + get => GetValue(DataProperty); + set => SetValue(DataProperty, value); + } + + protected override Geometry CreateDefiningGeometry() => Data; + + private void DataPropertyChanged(Geometry oldData, Geometry newData) + { + // Check if data is actually a new Geometry. + // + if (newData != null && !ReferenceEquals(newData, oldData)) + { + UpdateData(); + } + } + + private void SetMapTransform(Matrix matrix) + { + if (Data.Transform is MatrixTransform transform) + { + transform.Matrix = matrix; + } + else + { + Data.Transform = new MatrixTransform(matrix); + } + } + + #region Methods used only by derived classes MapPolyline, MapPolygon and MapMultiPolygon + + protected void DataCollectionPropertyChanged(IEnumerable oldValue, IEnumerable newValue) + { + if (oldValue is INotifyCollectionChanged oldCollection) + { + oldCollection.CollectionChanged -= DataCollectionChanged; + } + + if (newValue is INotifyCollectionChanged newCollection) + { + newCollection.CollectionChanged += DataCollectionChanged; + } + + UpdateData(); + } + + protected void DataCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) + { + UpdateData(); + } + + protected void AddPolylinePoints(PathFigures pathFigures, IEnumerable locations, double longitudeOffset, bool closed) + { + if (locations.Count() >= 2) + { + var points = locations + .Select(location => LocationToView(location, longitudeOffset)) + .Where(point => point.HasValue) + .Select(point => point.Value); + + var figure = new PathFigure + { + StartPoint = points.First(), + IsClosed = closed, + IsFilled = true + }; + + figure.Segments.Add(new PolyLineSegment(points.Skip(1))); + pathFigures.Add(figure); + } + } + + #endregion + } +} diff --git a/MapControl/Shared/MapImageLayer.cs b/MapControl/Shared/MapImageLayer.cs index 11114b68..5a8276e0 100644 --- a/MapControl/Shared/MapImageLayer.cs +++ b/MapControl/Shared/MapImageLayer.cs @@ -65,6 +65,8 @@ namespace MapControl public MapImageLayer() { + IsHitTestVisible = false; + loadingProgress = new Progress(p => SetValue(LoadingProgressProperty, p)); updateTimer = this.CreateTimer(UpdateInterval); @@ -145,7 +147,6 @@ namespace MapControl { Opacity = 0d, Stretch = Stretch.Fill, - IsHitTestVisible = false // avoid touch capture issues }); } } diff --git a/MapControl/Shared/MapPath.cs b/MapControl/Shared/MapPath.cs index 1f8f5732..5700016a 100644 --- a/MapControl/Shared/MapPath.cs +++ b/MapControl/Shared/MapPath.cs @@ -13,6 +13,9 @@ using Windows.UI.Xaml.Media; #elif WINUI using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Media; +#elif AVALONIA +using DependencyProperty = Avalonia.AvaloniaProperty; +using PathFigureCollection = Avalonia.Media.PathFigures; #endif namespace MapControl diff --git a/MapControl/Shared/MapTileLayerBase.cs b/MapControl/Shared/MapTileLayerBase.cs index 74445a5b..69ec0878 100644 --- a/MapControl/Shared/MapTileLayerBase.cs +++ b/MapControl/Shared/MapTileLayerBase.cs @@ -66,7 +66,7 @@ namespace MapControl protected MapTileLayerBase() { - MapPanel.SetRenderTransform(this, new MatrixTransform()); + IsHitTestVisible = false; loadingProgress = new Progress(p => SetValue(LoadingProgressProperty, p)); @@ -76,6 +76,7 @@ namespace MapControl #if UWP || WINUI MapPanel.InitMapElement(this); #endif + MapPanel.SetRenderTransform(this, new MatrixTransform()); } public ITileImageLoader TileImageLoader diff --git a/MapControl/Shared/Tile.cs b/MapControl/Shared/Tile.cs index df712e71..ef80501e 100644 --- a/MapControl/Shared/Tile.cs +++ b/MapControl/Shared/Tile.cs @@ -36,11 +36,7 @@ namespace MapControl public int Column { get; } public int Row => Y; - public Image Image { get; } = new Image - { - Stretch = Stretch.Fill, - IsHitTestVisible = false // avoid touch capture issues - }; + public Image Image { get; } = new Image { Stretch = Stretch.Fill }; public bool IsPending { get; set; } = true;