mirror of
https://github.com/ClemensFischer/XAML-Map-Control.git
synced 2025-12-06 07:12:04 +01:00
Fixed MapItem.MapTransform implementation
This commit is contained in:
parent
d7593cbe8c
commit
fd13503613
|
|
@ -236,6 +236,18 @@ namespace MapControl
|
|||
return ViewTransform.Scale * MapProjection.GetRelativeScale(location);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a transform Matrix for scaling and rotating objects that are anchored
|
||||
/// at a Location from map coordinates (i.e. meters) to view coordinates.
|
||||
/// </summary>
|
||||
public Matrix GetMapTransform(Location location)
|
||||
{
|
||||
var scale = GetScale(location);
|
||||
var matrix = new Matrix(scale.X, 0d, 0d, scale.Y, 0d, 0d);
|
||||
matrix.Rotate(ViewTransform.Rotation);
|
||||
return matrix;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Transforms a Location in geographic coordinates to a Point in view coordinates.
|
||||
/// </summary>
|
||||
|
|
|
|||
105
MapControl/Shared/MapItem.cs
Normal file
105
MapControl/Shared/MapItem.cs
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
// XAML Map Control - https://github.com/ClemensFischer/XAML-Map-Control
|
||||
// Copyright © 2023 Clemens Fischer
|
||||
// Licensed under the Microsoft Public License (Ms-PL)
|
||||
|
||||
#if WINUI
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using Microsoft.UI.Xaml.Media;
|
||||
#elif UWP
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using Windows.UI.Xaml.Media;
|
||||
#else
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Media;
|
||||
#endif
|
||||
|
||||
namespace MapControl
|
||||
{
|
||||
/// <summary>
|
||||
/// Container class for an item in a MapItemsControl.
|
||||
/// </summary>
|
||||
public partial class MapItem : ListBoxItem, IMapElement
|
||||
{
|
||||
private MapBase parentMap;
|
||||
private MatrixTransform mapTransform;
|
||||
|
||||
/// <summary>
|
||||
/// Gets/sets MapPanel.AutoCollapse.
|
||||
/// </summary>
|
||||
public bool AutoCollapse
|
||||
{
|
||||
get => (bool)GetValue(AutoCollapseProperty);
|
||||
set => SetValue(AutoCollapseProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets/sets MapPanel.Location.
|
||||
/// </summary>
|
||||
public Location Location
|
||||
{
|
||||
get => (Location)GetValue(LocationProperty);
|
||||
set => SetValue(LocationProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Implements IMapElement.ParentMap.
|
||||
/// </summary>
|
||||
public MapBase ParentMap
|
||||
{
|
||||
get => parentMap;
|
||||
set
|
||||
{
|
||||
if (parentMap != null)
|
||||
{
|
||||
parentMap.ViewportChanged -= OnViewportChanged;
|
||||
}
|
||||
|
||||
parentMap = value;
|
||||
|
||||
if (parentMap != null && mapTransform != null)
|
||||
{
|
||||
// Attach ViewportChanged handler only if MapTransform is actually used.
|
||||
//
|
||||
parentMap.ViewportChanged += OnViewportChanged;
|
||||
UpdateMapTransform(Location);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a Transform for scaling and rotating geometries
|
||||
/// in map coordinates (meters) to view coordinates (pixels).
|
||||
/// </summary>
|
||||
public Transform MapTransform
|
||||
{
|
||||
get
|
||||
{
|
||||
if (mapTransform == null)
|
||||
{
|
||||
mapTransform = new MatrixTransform();
|
||||
|
||||
if (parentMap != null)
|
||||
{
|
||||
parentMap.ViewportChanged += OnViewportChanged;
|
||||
UpdateMapTransform(Location);
|
||||
}
|
||||
}
|
||||
|
||||
return mapTransform;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnViewportChanged(object sender, ViewportChangedEventArgs e)
|
||||
{
|
||||
UpdateMapTransform(Location);
|
||||
}
|
||||
|
||||
private void UpdateMapTransform(Location location)
|
||||
{
|
||||
if (mapTransform != null && parentMap != null && location != null)
|
||||
{
|
||||
mapTransform.Matrix = parentMap.GetMapTransform(location);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -8,77 +8,19 @@ using Windows.Foundation;
|
|||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using Microsoft.UI.Xaml.Data;
|
||||
using Microsoft.UI.Xaml.Media;
|
||||
#elif UWP
|
||||
using Windows.Foundation;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using Windows.UI.Xaml.Data;
|
||||
using Windows.UI.Xaml.Media;
|
||||
#else
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Media;
|
||||
#endif
|
||||
|
||||
namespace MapControl
|
||||
{
|
||||
/// <summary>
|
||||
/// Container class for an item in a MapItemsControl.
|
||||
/// </summary>
|
||||
public partial class MapItem : ListBoxItem
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets/sets MapPanel.AutoCollapse.
|
||||
/// </summary>
|
||||
public bool AutoCollapse
|
||||
{
|
||||
get => (bool)GetValue(AutoCollapseProperty);
|
||||
set => SetValue(AutoCollapseProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets/sets MapPanel.Location.
|
||||
/// </summary>
|
||||
public Location Location
|
||||
{
|
||||
get => (Location)GetValue(LocationProperty);
|
||||
set => SetValue(LocationProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a Transform for scaling and rotating geometries
|
||||
/// in map coordinates (meters) to view coordinates (pixels).
|
||||
/// </summary>
|
||||
public Transform MapTransform => mapTransform ?? (mapTransform = new MatrixTransform());
|
||||
|
||||
private MatrixTransform mapTransform;
|
||||
|
||||
protected override Size ArrangeOverride(Size bounds)
|
||||
{
|
||||
var size = base.ArrangeOverride(bounds);
|
||||
|
||||
// If the MapTransform property is used, update its Matrix property
|
||||
// (after calling base.ArrangeOverride to avoid rendering issues).
|
||||
//
|
||||
if (mapTransform != null)
|
||||
{
|
||||
var parentMap = (VisualTreeHelper.GetParent(this) as MapPanel)?.ParentMap;
|
||||
|
||||
if (parentMap != null && Location != null)
|
||||
{
|
||||
var scale = parentMap.GetScale(Location);
|
||||
var matrix = new Matrix(scale.X, 0d, 0d, scale.Y, 0d, 0d);
|
||||
matrix.Rotate(parentMap.ViewTransform.Rotation);
|
||||
mapTransform.Matrix = matrix;
|
||||
}
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Manages a collection of selectable items on a Map.
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -46,6 +46,9 @@ namespace MapControl
|
|||
|
||||
private MapBase parentMap;
|
||||
|
||||
/// <summary>
|
||||
/// Implements IMapElement.ParentMap.
|
||||
/// </summary>
|
||||
public MapBase ParentMap
|
||||
{
|
||||
get => parentMap;
|
||||
|
|
|
|||
|
|
@ -40,6 +40,9 @@ namespace MapControl
|
|||
set => SetValue(LocationProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Implements IMapElement.ParentMap.
|
||||
/// </summary>
|
||||
public MapBase ParentMap
|
||||
{
|
||||
get => parentMap;
|
||||
|
|
@ -72,9 +75,7 @@ namespace MapControl
|
|||
|
||||
if (parentMap != null && Location != null && Data != null)
|
||||
{
|
||||
var scale = parentMap.GetScale(Location);
|
||||
var matrix = new Matrix(scale.X, 0d, 0d, scale.Y, 0d, 0d);
|
||||
matrix.Rotate(parentMap.ViewTransform.Rotation);
|
||||
var matrix = parentMap.GetMapTransform(Location);
|
||||
|
||||
if (Data.Transform is MatrixTransform transform)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -165,6 +165,9 @@ namespace MapControl
|
|||
private set => SetValue(LoadingProgressProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Implements IMapElement.ParentMap.
|
||||
/// </summary>
|
||||
public MapBase ParentMap
|
||||
{
|
||||
get => parentMap;
|
||||
|
|
|
|||
|
|
@ -113,6 +113,9 @@
|
|||
<Compile Include="..\Shared\MapImageLayer.cs">
|
||||
<Link>MapImageLayer.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Shared\MapItem.cs">
|
||||
<Link>MapItem.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Shared\MapItemsControl.cs">
|
||||
<Link>MapItemsControl.cs</Link>
|
||||
</Compile>
|
||||
|
|
@ -248,6 +251,9 @@
|
|||
<Compile Include="..\WinUI\MapGraticule.WinUI.cs">
|
||||
<Link>MapGraticule.WinUI.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\WinUI\MapItem.WinUI.cs">
|
||||
<Link>MapItem.WinUI.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\WinUI\MapItemsControl.WinUI.cs">
|
||||
<Link>MapItemsControl.WinUI.cs</Link>
|
||||
</Compile>
|
||||
|
|
|
|||
31
MapControl/WPF/MapItem.WPF.cs
Normal file
31
MapControl/WPF/MapItem.WPF.cs
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
// XAML Map Control - https://github.com/ClemensFischer/XAML-Map-Control
|
||||
// Copyright © 2023 Clemens Fischer
|
||||
// Licensed under the Microsoft Public License (Ms-PL)
|
||||
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace MapControl
|
||||
{
|
||||
public partial class MapItem
|
||||
{
|
||||
public static readonly DependencyProperty AutoCollapseProperty = MapPanel.AutoCollapseProperty.AddOwner(
|
||||
typeof(MapItem));
|
||||
|
||||
public static readonly DependencyProperty LocationProperty = MapPanel.LocationProperty.AddOwner(
|
||||
typeof(MapItem), new FrameworkPropertyMetadata(null,
|
||||
(o, e) => ((MapItem)o).UpdateMapTransform((Location)e.NewValue)));
|
||||
|
||||
static MapItem()
|
||||
{
|
||||
DefaultStyleKeyProperty.OverrideMetadata(typeof(MapItem), new FrameworkPropertyMetadata(typeof(MapItem)));
|
||||
}
|
||||
|
||||
protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
|
||||
{
|
||||
(ItemsControl.ItemsControlFromItemContainer(this) as MapItemsControl)?.OnItemClicked(
|
||||
this, Keyboard.Modifiers.HasFlag(ModifierKeys.Control), Keyboard.Modifiers.HasFlag(ModifierKeys.Shift));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4,29 +4,10 @@
|
|||
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace MapControl
|
||||
{
|
||||
public partial class MapItem
|
||||
{
|
||||
public static readonly DependencyProperty AutoCollapseProperty = MapPanel.AutoCollapseProperty.AddOwner(typeof(MapItem));
|
||||
|
||||
public static readonly DependencyProperty LocationProperty = MapPanel.LocationProperty.AddOwner(typeof(MapItem));
|
||||
|
||||
static MapItem()
|
||||
{
|
||||
DefaultStyleKeyProperty.OverrideMetadata(typeof(MapItem), new FrameworkPropertyMetadata(typeof(MapItem)));
|
||||
}
|
||||
|
||||
protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
|
||||
{
|
||||
(ItemsControl.ItemsControlFromItemContainer(this) as MapItemsControl)?.OnItemClicked(
|
||||
this, Keyboard.Modifiers.HasFlag(ModifierKeys.Control), Keyboard.Modifiers.HasFlag(ModifierKeys.Shift));
|
||||
}
|
||||
}
|
||||
|
||||
public partial class MapItemsControl
|
||||
{
|
||||
static MapItemsControl()
|
||||
|
|
|
|||
65
MapControl/WinUI/MapItem.WinUI.cs
Normal file
65
MapControl/WinUI/MapItem.WinUI.cs
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
// XAML Map Control - https://github.com/ClemensFischer/XAML-Map-Control
|
||||
// Copyright © 2023 Clemens Fischer
|
||||
// Licensed under the Microsoft Public License (Ms-PL)
|
||||
|
||||
using Windows.System;
|
||||
#if WINUI
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using Microsoft.UI.Xaml.Input;
|
||||
#else
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using Windows.UI.Xaml.Input;
|
||||
#endif
|
||||
|
||||
namespace MapControl
|
||||
{
|
||||
public partial class MapItem
|
||||
{
|
||||
public static readonly DependencyProperty AutoCollapseProperty = DependencyProperty.Register(
|
||||
nameof(AutoCollapse), typeof(bool), typeof(MapItem), new PropertyMetadata(false,
|
||||
(o, e) => MapPanel.SetAutoCollapse((MapItem)o, (bool)e.NewValue)));
|
||||
|
||||
public static readonly DependencyProperty LocationProperty = DependencyProperty.Register(
|
||||
nameof(Location), typeof(Location), typeof(MapItem), new PropertyMetadata(null,
|
||||
(o, e) => ((MapItem)o).LocationPropertyChanged((Location)e.NewValue)));
|
||||
|
||||
private void LocationPropertyChanged(Location location)
|
||||
{
|
||||
MapPanel.SetLocation(this, location);
|
||||
UpdateMapTransform(location);
|
||||
}
|
||||
|
||||
public MapItem()
|
||||
{
|
||||
DefaultStyleKey = typeof(MapItem);
|
||||
MapPanel.InitMapElement(this);
|
||||
}
|
||||
|
||||
protected override void OnPointerPressed(PointerRoutedEventArgs e)
|
||||
{
|
||||
(ItemsControl.ItemsControlFromItemContainer(this) as MapItemsControl)?.OnItemClicked(
|
||||
this, e.KeyModifiers.HasFlag(VirtualKeyModifiers.Control), e.KeyModifiers.HasFlag(VirtualKeyModifiers.Shift));
|
||||
}
|
||||
|
||||
protected override void OnApplyTemplate()
|
||||
{
|
||||
base.OnApplyTemplate();
|
||||
|
||||
var parentMap = MapPanel.GetParentMap(this);
|
||||
|
||||
if (parentMap != null)
|
||||
{
|
||||
// If this.Background is not explicitly set, bind it to parentMap.Background
|
||||
this.SetBindingOnUnsetProperty(BackgroundProperty, parentMap, Panel.BackgroundProperty, nameof(Background));
|
||||
|
||||
// If this.Foreground is not explicitly set, bind it to parentMap.Foreground
|
||||
this.SetBindingOnUnsetProperty(ForegroundProperty, parentMap, MapBase.ForegroundProperty, nameof(Foreground));
|
||||
|
||||
// If this.BorderBrush is not explicitly set, bind it to parentMap.Foreground
|
||||
this.SetBindingOnUnsetProperty(BorderBrushProperty, parentMap, MapBase.ForegroundProperty, nameof(Foreground));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,61 +2,14 @@
|
|||
// Copyright © 2023 Clemens Fischer
|
||||
// Licensed under the Microsoft Public License (Ms-PL)
|
||||
|
||||
using Windows.System;
|
||||
#if WINUI
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using Microsoft.UI.Xaml.Input;
|
||||
#else
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using Windows.UI.Xaml.Input;
|
||||
#endif
|
||||
|
||||
namespace MapControl
|
||||
{
|
||||
public partial class MapItem
|
||||
{
|
||||
public static readonly DependencyProperty AutoCollapseProperty = DependencyProperty.Register(
|
||||
nameof(AutoCollapse), typeof(bool), typeof(MapItem),
|
||||
new PropertyMetadata(false, (o, e) => MapPanel.SetAutoCollapse((MapItem)o, (bool)e.NewValue)));
|
||||
|
||||
public static readonly DependencyProperty LocationProperty = DependencyProperty.Register(
|
||||
nameof(Location), typeof(Location), typeof(MapItem),
|
||||
new PropertyMetadata(null, (o, e) => MapPanel.SetLocation((MapItem)o, (Location)e.NewValue)));
|
||||
|
||||
public MapItem()
|
||||
{
|
||||
DefaultStyleKey = typeof(MapItem);
|
||||
MapPanel.InitMapElement(this);
|
||||
}
|
||||
|
||||
protected override void OnPointerPressed(PointerRoutedEventArgs e)
|
||||
{
|
||||
(ItemsControl.ItemsControlFromItemContainer(this) as MapItemsControl)?.OnItemClicked(
|
||||
this, e.KeyModifiers.HasFlag(VirtualKeyModifiers.Control), e.KeyModifiers.HasFlag(VirtualKeyModifiers.Shift));
|
||||
}
|
||||
|
||||
protected override void OnApplyTemplate()
|
||||
{
|
||||
base.OnApplyTemplate();
|
||||
|
||||
var parentMap = MapPanel.GetParentMap(this);
|
||||
|
||||
if (parentMap != null)
|
||||
{
|
||||
// If this.Background is not explicitly set, bind it to parentMap.Background
|
||||
this.SetBindingOnUnsetProperty(BackgroundProperty, parentMap, Panel.BackgroundProperty, nameof(Background));
|
||||
|
||||
// If this.Foreground is not explicitly set, bind it to parentMap.Foreground
|
||||
this.SetBindingOnUnsetProperty(ForegroundProperty, parentMap, MapBase.ForegroundProperty, nameof(Foreground));
|
||||
|
||||
// If this.BorderBrush is not explicitly set, bind it to parentMap.Foreground
|
||||
this.SetBindingOnUnsetProperty(BorderBrushProperty, parentMap, MapBase.ForegroundProperty, nameof(Foreground));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public partial class MapItemsControl
|
||||
{
|
||||
public MapItemsControl()
|
||||
|
|
|
|||
Loading…
Reference in a new issue