Added Avalonia MapOverlay and MapScale

This commit is contained in:
ClemensFischer 2024-05-24 18:24:44 +02:00
parent 192ecbf4df
commit 35c0076336
11 changed files with 210 additions and 123 deletions

View file

@ -17,35 +17,13 @@ namespace MapControl
{
internal static class BindingHelper
{
/// <summary>
/// Returns a Binding to the specified dependency property of a FrameworkElement.
/// If the source property is itself already bound, the method returns the existing Binding,
/// otherwise it creates one with sourceElement as Source and sourcePropertyName as Path.
/// </summary>
public static Binding GetOrCreateBinding(
this FrameworkElement sourceElement, DependencyProperty sourceProperty, string sourcePropertyName)
public static Binding CreateBinding(this FrameworkElement source, string property)
{
var sourceBinding = sourceElement.GetBindingExpression(sourceProperty);
return sourceBinding != null
? sourceBinding.ParentBinding
: new Binding { Source = sourceElement, Path = new PropertyPath(sourcePropertyName) };
}
/// <summary>
/// Sets a Binding on the specified dependency property of targetElement, if the target property does
/// not yet have a value or a Binding assigned to it. The potentially assigned Binding is created by
/// GetOrCreateBinding(sourceElement, sourceProperty, sourcePropertyName).
/// </summary>
public static void SetBindingOnUnsetProperty(
this FrameworkElement targetElement, DependencyProperty targetProperty,
FrameworkElement sourceElement, DependencyProperty sourceProperty, string sourcePropertyName)
{
if (targetElement.GetValue(targetProperty) == null &&
targetElement.GetBindingExpression(targetProperty) == null)
return new Binding
{
targetElement.SetBinding(targetProperty, GetOrCreateBinding(sourceElement, sourceProperty, sourcePropertyName));
}
Source = source,
Path = new PropertyPath(property)
};
}
}
}

View file

@ -11,6 +11,9 @@ using Windows.UI.Xaml.Media;
#elif WINUI
using Microsoft.UI.Xaml.Media;
using Windows.UI.Text;
#elif AVALONIA
using Avalonia.Media;
using DoubleCollection = System.Collections.Generic.IEnumerable<double>;
#endif
namespace MapControl
@ -80,22 +83,10 @@ namespace MapControl
set => SetValue(StrokeDashOffsetProperty, value);
}
public PenLineCap StrokeDashCap
public PenLineCap StrokeLineCap
{
get => (PenLineCap)GetValue(StrokeDashCapProperty);
set => SetValue(StrokeDashCapProperty, value);
}
public PenLineCap StrokeStartLineCap
{
get => (PenLineCap)GetValue(StrokeStartLineCapProperty);
set => SetValue(StrokeStartLineCapProperty, value);
}
public PenLineCap StrokeEndLineCap
{
get => (PenLineCap)GetValue(StrokeEndLineCapProperty);
set => SetValue(StrokeEndLineCapProperty, value);
get => (PenLineCap)GetValue(StrokeLineCapProperty);
set => SetValue(StrokeLineCapProperty, value);
}
public PenLineJoin StrokeLineJoin

View file

@ -7,20 +7,32 @@ using System.Globalization;
#if WPF
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Media;
using System.Windows.Shapes;
#elif UWP
using Windows.Foundation;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Shapes;
#elif WINUI
using Windows.Foundation;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Data;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Media;
using Microsoft.UI.Xaml.Shapes;
#elif AVALONIA
using Avalonia.Data;
using Avalonia.Controls;
using Avalonia.Controls.Shapes;
using Avalonia.Media;
using DependencyProperty = Avalonia.AvaloniaProperty;
using HorizontalAlignment = Avalonia.Layout.HorizontalAlignment;
using VerticalAlignment = Avalonia.Layout.VerticalAlignment;
using PointCollection = System.Collections.Generic.List<Avalonia.Point>;
#endif
namespace MapControl
@ -53,11 +65,10 @@ namespace MapControl
{
base.SetParentMap(map);
line.SetBinding(Shape.StrokeProperty, this.GetOrCreateBinding(StrokeProperty, nameof(Stroke)));
line.SetBinding(Shape.StrokeThicknessProperty, this.GetOrCreateBinding(StrokeThicknessProperty, nameof(StrokeThickness)));
line.SetBinding(Shape.StrokeProperty, this.CreateBinding(nameof(Stroke)));
line.SetBinding(Shape.StrokeThicknessProperty, this.CreateBinding(nameof(StrokeThickness)));
#if UWP || WINUI
label.SetBinding(TextBlock.ForegroundProperty, this.GetOrCreateBinding(ForegroundProperty, nameof(Foreground)));
label.SetBinding(TextBlock.ForegroundProperty, this.CreateBinding(nameof(Foreground)));
#endif
}
@ -69,42 +80,44 @@ namespace MapControl
protected override Size MeasureOverride(Size availableSize)
{
var size = new Size();
double scale;
if (ParentMap != null && (scale = ParentMap.GetScale(ParentMap.Center).X) > 0d)
if (ParentMap == null || (scale = ParentMap.GetScale(ParentMap.Center).X) <= 0d)
{
var length = MinWidth / scale;
var magnitude = Math.Pow(10d, Math.Floor(Math.Log10(length)));
return new Size();
}
length = length / magnitude < 2d ? 2d * magnitude
: length / magnitude < 5d ? 5d * magnitude
: 10d * magnitude;
var length = MinWidth / scale;
var magnitude = Math.Pow(10d, Math.Floor(Math.Log10(length)));
size.Width = length * scale + StrokeThickness + Padding.Left + Padding.Right;
size.Height = 1.25 * FontSize + StrokeThickness + Padding.Top + Padding.Bottom;
length = length / magnitude < 2d ? 2d * magnitude
: length / magnitude < 5d ? 5d * magnitude
: 10d * magnitude;
var x1 = Padding.Left + StrokeThickness / 2d;
var x2 = size.Width - Padding.Right - StrokeThickness / 2d;
var y1 = size.Height / 2d;
var y2 = size.Height - Padding.Bottom - StrokeThickness / 2d;
var size = new Size(
length * scale + StrokeThickness + Padding.Left + Padding.Right,
1.25 * FontSize + StrokeThickness + Padding.Top + Padding.Bottom);
line.Points = new PointCollection
var x1 = Padding.Left + StrokeThickness / 2d;
var x2 = size.Width - Padding.Right - StrokeThickness / 2d;
var y1 = size.Height / 2d;
var y2 = size.Height - Padding.Bottom - StrokeThickness / 2d;
line.Points = new PointCollection
{
new Point(x1, y1),
new Point(x1, y2),
new Point(x2, y2),
new Point(x2, y1)
};
line.Measure(size);
line.Measure(size);
label.Text = length >= 1000d
? string.Format(CultureInfo.InvariantCulture, "{0:F0} km", length / 1000d)
: string.Format(CultureInfo.InvariantCulture, "{0:F0} m", length);
label.Width = size.Width;
label.Height = size.Height;
label.Measure(size);
}
label.Text = length >= 1000d
? string.Format(CultureInfo.InvariantCulture, "{0:F0} km", length / 1000d)
: string.Format(CultureInfo.InvariantCulture, "{0:F0} m", length);
label.Width = size.Width;
label.Height = size.Height;
label.Measure(size);
return size;
}