XAML-Map-Control/MapControl/Shared/MapScale.cs

137 lines
4.2 KiB
C#
Raw Normal View History

2025-02-27 18:46:32 +01:00
using System;
2021-07-05 00:04:07 +02:00
using System.Globalization;
2024-05-22 11:25:32 +02:00
#if WPF
using System.Windows;
using System.Windows.Controls;
2024-05-26 21:25:36 +02:00
using System.Windows.Data;
2024-05-22 11:25:32 +02:00
using System.Windows.Media;
using System.Windows.Shapes;
2021-11-17 23:17:11 +01:00
#elif UWP
2017-08-23 23:33:27 +02:00
using Windows.Foundation;
using Windows.UI.Xaml;
2024-05-26 21:25:36 +02:00
using Windows.UI.Xaml.Data;
2017-08-23 23:33:27 +02:00
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Shapes;
2024-05-22 11:25:32 +02:00
#elif WINUI
using Windows.Foundation;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
2024-05-26 21:25:36 +02:00
using Microsoft.UI.Xaml.Data;
2024-05-22 11:25:32 +02:00
using Microsoft.UI.Xaml.Media;
using Microsoft.UI.Xaml.Shapes;
2024-08-30 16:37:40 +02:00
#elif AVALONIA
2025-08-19 19:43:02 +02:00
using Avalonia;
using Avalonia.Controls;
2024-08-30 16:37:40 +02:00
using Avalonia.Controls.Shapes;
2025-08-19 19:43:02 +02:00
using Avalonia.Data;
using Avalonia.Layout;
using PointCollection = System.Collections.Generic.List<Avalonia.Point>;
2017-08-23 23:33:27 +02:00
#endif
namespace MapControl
{
/// <summary>
/// Draws a map scale overlay.
/// </summary>
2025-09-15 17:46:31 +02:00
public partial class MapScale : MapPanel
2017-08-23 23:33:27 +02:00
{
2024-05-23 18:08:14 +02:00
public static readonly DependencyProperty PaddingProperty =
DependencyPropertyHelper.Register<MapScale, Thickness>(nameof(Padding), new Thickness(4));
2017-08-23 23:33:27 +02:00
2024-05-26 15:55:36 +02:00
public static readonly DependencyProperty StrokeThicknessProperty =
DependencyPropertyHelper.Register<MapScale, double>(nameof(StrokeThickness), 1d);
public Thickness Padding
{
get => (Thickness)GetValue(PaddingProperty);
set => SetValue(PaddingProperty, value);
}
public double StrokeThickness
{
get => (double)GetValue(StrokeThicknessProperty);
set => SetValue(StrokeThicknessProperty, value);
}
private readonly Polyline line = new Polyline();
private readonly TextBlock label = new TextBlock
{
2024-05-26 15:55:36 +02:00
HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Center
};
2017-08-23 23:33:27 +02:00
public MapScale()
{
MinWidth = 100d;
2021-12-01 20:39:42 +01:00
Children.Add(line);
Children.Add(label);
}
protected override void SetParentMap(MapBase map)
{
base.SetParentMap(map);
2024-05-26 21:25:36 +02:00
line.SetBinding(Shape.StrokeThicknessProperty,
new Binding { Source = this, Path = new PropertyPath(nameof(StrokeThickness)) });
2024-05-27 11:05:22 +02:00
2025-06-06 11:39:26 +02:00
line.SetBinding(Shape.StrokeProperty,
new Binding { Source = map, Path = new PropertyPath(nameof(MapBase.Foreground)) });
2024-05-22 11:25:32 +02:00
#if UWP || WINUI
2024-05-26 21:25:36 +02:00
label.SetBinding(TextBlock.ForegroundProperty,
new Binding { Source = map, Path = new PropertyPath(nameof(MapBase.Foreground)) });
#endif
2017-08-23 23:33:27 +02:00
}
protected override Size MeasureOverride(Size availableSize)
{
2022-11-19 17:54:37 +01:00
double scale;
2017-08-23 23:33:27 +02:00
2024-05-24 18:24:44 +02:00
if (ParentMap == null || (scale = ParentMap.GetScale(ParentMap.Center).X) <= 0d)
2017-08-23 23:33:27 +02:00
{
2024-05-24 18:24:44 +02:00
return new Size();
}
2017-08-23 23:33:27 +02:00
2024-05-24 18:24:44 +02:00
var length = MinWidth / scale;
var magnitude = Math.Pow(10d, Math.Floor(Math.Log10(length)));
2017-08-23 23:33:27 +02:00
2024-05-24 18:24:44 +02:00
length = length / magnitude < 2d ? 2d * magnitude
: length / magnitude < 5d ? 5d * magnitude
: 10d * magnitude;
2017-08-23 23:33:27 +02:00
2024-05-24 18:24:44 +02:00
var size = new Size(
length * scale + StrokeThickness + Padding.Left + Padding.Right,
2024-05-26 15:55:36 +02:00
1.5 * label.FontSize + 2 * StrokeThickness + Padding.Top + Padding.Bottom);
2017-08-23 23:33:27 +02:00
2024-05-24 18:24:44 +02:00
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
2024-05-26 15:55:36 +02:00
{
new Point(x1, y1),
new Point(x1, y2),
new Point(x2, y2),
new Point(x2, y1)
};
2024-05-24 18:24:44 +02:00
label.Text = length >= 1000d
? string.Format(CultureInfo.InvariantCulture, "{0:F0} km", length / 1000d)
: string.Format(CultureInfo.InvariantCulture, "{0:F0} m", length);
2024-05-26 15:55:36 +02:00
line.Measure(size);
2024-05-24 18:24:44 +02:00
label.Measure(size);
2017-08-23 23:33:27 +02:00
return size;
}
protected override void OnViewportChanged(ViewportChangedEventArgs e)
{
InvalidateMeasure();
}
}
}