mirror of
https://github.com/ClemensFischer/XAML-Map-Control.git
synced 2025-12-06 07:12:04 +01:00
Moved Matrix creation to ViewTransform
This commit is contained in:
parent
a1b8ed1ce8
commit
9cb4a9be7e
|
|
@ -7,7 +7,6 @@ using Avalonia.Animation;
|
|||
using Avalonia.Animation.Easings;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Styling;
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
|
|
@ -36,7 +35,7 @@ namespace MapControl
|
|||
public static readonly StyledProperty<double> MaxZoomLevelProperty =
|
||||
DependencyPropertyHelper.Register<MapBase, double>(nameof(MaxZoomLevel), 20d, false,
|
||||
(map, oldValue, newValue) => map.MaxZoomLevelPropertyChanged(newValue),
|
||||
(map, value) => map.CoerceMinZoomLevelProperty(value));
|
||||
(map, value) => map.CoerceMaxZoomLevelProperty(value));
|
||||
|
||||
public static readonly StyledProperty<double> ZoomLevelProperty =
|
||||
DependencyPropertyHelper.Register<MapBase, double>(nameof(ZoomLevel), 1d, true,
|
||||
|
|
@ -106,24 +105,8 @@ namespace MapControl
|
|||
/// </summary>
|
||||
public double ViewScale
|
||||
{
|
||||
get => ViewTransform.Scale;
|
||||
}
|
||||
|
||||
private void SetViewScale(double viewScale)
|
||||
{
|
||||
RaisePropertyChanged(ViewScaleProperty, double.NaN, viewScale);
|
||||
}
|
||||
|
||||
/// <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);
|
||||
|
||||
return Matrix.CreateScale(scale.X, scale.Y)
|
||||
* Matrix.CreateRotation(ViewTransform.Rotation * Math.PI / 180d);
|
||||
get => (double)GetValue(ViewScaleProperty);
|
||||
private set => RaisePropertyChanged(ViewScaleProperty, double.NaN, value);
|
||||
}
|
||||
|
||||
private void CenterPropertyChanged(Location center)
|
||||
|
|
|
|||
|
|
@ -43,6 +43,25 @@ namespace MapControl
|
|||
/// </summary>
|
||||
public Matrix ViewToMapMatrix { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a ViewTransform from a map center point in projected coordinates,
|
||||
/// a view conter point, a scaling factor from projected coordinates to view coordinates
|
||||
/// and a rotation angle in degrees.
|
||||
/// </summary>
|
||||
public void SetTransform(Point mapCenter, Point viewCenter, double scale, double rotation)
|
||||
{
|
||||
Scale = scale;
|
||||
Rotation = ((rotation % 360d) + 360d) % 360d;
|
||||
|
||||
MapToViewMatrix
|
||||
= Matrix.CreateTranslation(-mapCenter.X, -mapCenter.Y)
|
||||
* Matrix.CreateScale(scale, -scale)
|
||||
* Matrix.CreateRotation(Rotation * Math.PI / 180d)
|
||||
* Matrix.CreateTranslation(viewCenter.X, viewCenter.Y);
|
||||
|
||||
ViewToMapMatrix = MapToViewMatrix.Invert();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Transforms a Point from projected map coordinates to view coordinates.
|
||||
/// </summary>
|
||||
|
|
@ -59,20 +78,29 @@ namespace MapControl
|
|||
return ViewToMapMatrix.Transform(point);
|
||||
}
|
||||
|
||||
public void SetTransform(Point mapCenter, Point viewCenter, double scale, double rotation)
|
||||
/// <summary>
|
||||
/// Transform relative to absolute map scale. Returns horizontal and vertical
|
||||
/// scaling factors from meters to view coordinates.
|
||||
/// </summary>
|
||||
public Point GetMapScale(Point relativeScale)
|
||||
{
|
||||
Scale = scale;
|
||||
Rotation = ((rotation % 360d) + 360d) % 360d;
|
||||
|
||||
MapToViewMatrix
|
||||
= Matrix.CreateTranslation(-mapCenter.X, -mapCenter.Y)
|
||||
* Matrix.CreateScale(scale, -scale)
|
||||
* Matrix.CreateRotation(Rotation * Math.PI / 180d)
|
||||
* Matrix.CreateTranslation(viewCenter.X, viewCenter.Y);
|
||||
|
||||
ViewToMapMatrix = MapToViewMatrix.Invert();
|
||||
return new Point(Scale * relativeScale.X, Scale * relativeScale.Y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a transform Matrix from meters to view coordinates for a relative map scale.
|
||||
/// </summary>
|
||||
public Matrix GetMapTransform(Point relativeScale)
|
||||
{
|
||||
var scale = GetMapScale(relativeScale);
|
||||
|
||||
return Matrix.CreateScale(scale.X, scale.Y)
|
||||
* Matrix.CreateRotation(Rotation * Math.PI / 180d);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the transform Matrix for the RenderTranform of a MapTileLayer.
|
||||
/// </summary>
|
||||
public Matrix GetTileLayerTransform(double tileMatrixScale, Point tileMatrixTopLeft, Point tileMatrixOrigin)
|
||||
{
|
||||
// Tile matrix origin in map coordinates.
|
||||
|
|
@ -92,6 +120,9 @@ namespace MapControl
|
|||
* Matrix.CreateTranslation(viewOrigin.X, viewOrigin.Y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the index bounds of a tile matrix.
|
||||
/// </summary>
|
||||
public Rect GetTileMatrixBounds(double tileMatrixScale, Point tileMatrixTopLeft, Size viewSize)
|
||||
{
|
||||
// View origin in map coordinates.
|
||||
|
|
@ -114,5 +145,15 @@ namespace MapControl
|
|||
//
|
||||
return new Rect(0d, 0d, viewSize.Width, viewSize.Height).TransformToAABB(transform);
|
||||
}
|
||||
|
||||
internal static Matrix CreateTransformMatrix(
|
||||
double translation1X, double translation1Y,
|
||||
double rotation,
|
||||
double translation2X, double translation2Y)
|
||||
{
|
||||
return Matrix.CreateTranslation(translation1X, translation1Y)
|
||||
* Matrix.CreateRotation(rotation * Math.PI / 180d)
|
||||
* Matrix.CreateTranslation(translation2X, translation2Y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -198,14 +198,21 @@ namespace MapControl
|
|||
public ViewTransform ViewTransform { get; } = new ViewTransform();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the map scale as the horizontal and vertical scaling factors from geographic
|
||||
/// coordinates to view coordinates at the specified location, as pixels per meter.
|
||||
/// Gets the map scale as horizontal and vertical scaling factors from meters to
|
||||
/// view coordinates at the specified location.
|
||||
/// </summary>
|
||||
public Point GetScale(Location location)
|
||||
{
|
||||
var relativeScale = MapProjection.GetRelativeScale(location);
|
||||
return ViewTransform.GetMapScale(MapProjection.GetRelativeScale(location));
|
||||
}
|
||||
|
||||
return new Point(ViewTransform.Scale * relativeScale.X, ViewTransform.Scale * relativeScale.Y);
|
||||
/// <summary>
|
||||
/// Gets a transform Matrix from meters to view coordinates for scaling and rotating
|
||||
/// objects that are anchored at a Location.
|
||||
/// </summary>
|
||||
public Matrix GetMapTransform(Location location)
|
||||
{
|
||||
return ViewTransform.GetMapTransform(MapProjection.GetRelativeScale(location));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -554,7 +561,7 @@ namespace MapControl
|
|||
}
|
||||
}
|
||||
|
||||
SetViewScale(ViewTransform.Scale);
|
||||
ViewScale = ViewTransform.Scale;
|
||||
|
||||
// Check if view center has moved across 180° longitude.
|
||||
//
|
||||
|
|
|
|||
|
|
@ -54,21 +54,10 @@ namespace MapControl
|
|||
public Matrix ViewToMapMatrix { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Transforms a Point from projected map coordinates to view coordinates.
|
||||
/// Initializes a ViewTransform from a map center point in projected coordinates,
|
||||
/// a view conter point, a scaling factor from projected coordinates to view coordinates
|
||||
/// and a rotation angle in degrees.
|
||||
/// </summary>
|
||||
public Point MapToView(Point point)
|
||||
{
|
||||
return MapToViewMatrix.Transform(point);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Transforms a Point from view coordinates to projected map coordinates.
|
||||
/// </summary>
|
||||
public Point ViewToMap(Point point)
|
||||
{
|
||||
return ViewToMapMatrix.Transform(point);
|
||||
}
|
||||
|
||||
public void SetTransform(Point mapCenter, Point viewCenter, double scale, double rotation)
|
||||
{
|
||||
Scale = scale;
|
||||
|
|
@ -85,6 +74,46 @@ namespace MapControl
|
|||
ViewToMapMatrix = transform;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Transforms a Point from projected map coordinates to view coordinates.
|
||||
/// </summary>
|
||||
public Point MapToView(Point point)
|
||||
{
|
||||
return MapToViewMatrix.Transform(point);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Transforms a Point from view coordinates to projected map coordinates.
|
||||
/// </summary>
|
||||
public Point ViewToMap(Point point)
|
||||
{
|
||||
return ViewToMapMatrix.Transform(point);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets scaling factors from meters to view coordinates for a relative map scale.
|
||||
/// </summary>
|
||||
public Point GetMapScale(Point relativeScale)
|
||||
{
|
||||
return new Point(Scale * relativeScale.X, Scale * relativeScale.Y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a transform Matrix from meters to view coordinates for a relative map scale.
|
||||
/// </summary>
|
||||
public Matrix GetMapTransform(Point relativeScale)
|
||||
{
|
||||
var scale = GetMapScale(relativeScale);
|
||||
|
||||
var transform = new Matrix(scale.X, 0d, 0d, scale.Y, 0d, 0d);
|
||||
transform.Rotate(Rotation);
|
||||
|
||||
return transform;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the transform Matrix for the RenderTranform of a MapTileLayer.
|
||||
/// </summary>
|
||||
public Matrix GetTileLayerTransform(double tileMatrixScale, Point tileMatrixTopLeft, Point tileMatrixOrigin)
|
||||
{
|
||||
// Tile matrix origin in map coordinates.
|
||||
|
|
@ -106,6 +135,9 @@ namespace MapControl
|
|||
return transform;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the index bounds of a tile matrix.
|
||||
/// </summary>
|
||||
public Rect GetTileMatrixBounds(double tileMatrixScale, Point tileMatrixTopLeft, Size viewSize)
|
||||
{
|
||||
// View origin in map coordinates.
|
||||
|
|
@ -128,5 +160,17 @@ namespace MapControl
|
|||
return new MatrixTransform { Matrix = transform }
|
||||
.TransformBounds(new Rect(0d, 0d, viewSize.Width, viewSize.Height));
|
||||
}
|
||||
|
||||
internal static Matrix CreateTransformMatrix(
|
||||
double translation1X, double translation1Y,
|
||||
double rotation,
|
||||
double translation2X, double translation2Y)
|
||||
{
|
||||
var transform = new Matrix(1d, 0d, 0d, 1d, translation1X, translation1Y);
|
||||
transform.Rotate(rotation);
|
||||
transform.Translate(translation2X, translation2Y);
|
||||
|
||||
return transform;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,18 +9,13 @@ using System.Linq;
|
|||
using System.Threading.Tasks;
|
||||
using System.Xml.Linq;
|
||||
#if AVALONIA
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Media;
|
||||
using Avalonia.Threading;
|
||||
using DependencyProperty = Avalonia.AvaloniaProperty;
|
||||
using FrameworkElement = Avalonia.Controls.Control;
|
||||
using ImageSource = Avalonia.Media.IImage;
|
||||
#elif WINUI
|
||||
using Windows.Foundation;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Media;
|
||||
#elif UWP
|
||||
using Windows.Foundation;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Media;
|
||||
#else
|
||||
|
|
@ -284,16 +279,12 @@ namespace MapControl
|
|||
}
|
||||
|
||||
var viewRect = GetViewRect(rect.Value);
|
||||
#if AVALONIA
|
||||
var transform
|
||||
= Matrix.CreateTranslation(-viewSize.Width / 2d, -viewSize.Height / 2d)
|
||||
* Matrix.CreateRotation(-viewRect.Rotation * Math.PI / 180d)
|
||||
* Matrix.CreateTranslation(viewRect.Rect.Width / 2d, viewRect.Rect.Height / 2d);
|
||||
#else
|
||||
var transform = new Matrix(1d, 0d, 0d, 1d, -viewSize.Width / 2d, -viewSize.Height / 2d);
|
||||
transform.Rotate(-viewRect.Rotation);
|
||||
transform.Translate(viewRect.Rect.Width / 2d, viewRect.Rect.Height / 2d);
|
||||
#endif
|
||||
|
||||
var transform = ViewTransform.CreateTransformMatrix(
|
||||
-viewSize.Width / 2d, -viewSize.Height / 2d,
|
||||
-viewRect.Rotation,
|
||||
viewRect.Rect.Width / 2d, viewRect.Rect.Height / 2d);
|
||||
|
||||
var imagePos = transform.Transform(position);
|
||||
|
||||
var queryParameters = new Dictionary<string, string>
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
// Licensed under the Microsoft Public License (Ms-PL)
|
||||
|
||||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Animation;
|
||||
|
||||
namespace MapControl
|
||||
|
|
@ -32,7 +31,7 @@ namespace MapControl
|
|||
public static readonly DependencyProperty MaxZoomLevelProperty =
|
||||
DependencyPropertyHelper.Register<MapBase, double>(nameof(MaxZoomLevel), 20d, false,
|
||||
(map, oldValue, newValue) => map.MaxZoomLevelPropertyChanged(newValue),
|
||||
(map, value) => map.CoerceMinZoomLevelProperty(value));
|
||||
(map, value) => map.CoerceMaxZoomLevelProperty(value));
|
||||
|
||||
public static readonly DependencyProperty ZoomLevelProperty =
|
||||
DependencyPropertyHelper.Register<MapBase, double>(nameof(ZoomLevel), 1d, true,
|
||||
|
|
@ -83,20 +82,10 @@ namespace MapControl
|
|||
/// Gets the scaling factor from projected map coordinates to view coordinates,
|
||||
/// as pixels per meter.
|
||||
/// </summary>
|
||||
public double ViewScale => (double)GetValue(ViewScaleProperty);
|
||||
|
||||
/// <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)
|
||||
public double ViewScale
|
||||
{
|
||||
var scale = GetScale(location);
|
||||
|
||||
var transform = new Matrix(scale.X, 0d, 0d, scale.Y, 0d, 0d);
|
||||
transform.Rotate(ViewTransform.Rotation);
|
||||
|
||||
return transform;
|
||||
get => (double)GetValue(ViewScaleProperty);
|
||||
private set => SetValue(ViewScalePropertyKey, value);
|
||||
}
|
||||
|
||||
protected override void OnRenderSizeChanged(SizeChangedInfo sizeInfo)
|
||||
|
|
@ -107,11 +96,6 @@ namespace MapControl
|
|||
UpdateTransform();
|
||||
}
|
||||
|
||||
private void SetViewScale(double scale)
|
||||
{
|
||||
SetValue(ViewScalePropertyKey, scale);
|
||||
}
|
||||
|
||||
private void CenterPropertyChanged(Location center)
|
||||
{
|
||||
if (!internalPropertyChange)
|
||||
|
|
|
|||
|
|
@ -92,20 +92,10 @@ namespace MapControl
|
|||
/// Gets the scaling factor from projected map coordinates to view coordinates,
|
||||
/// as pixels per meter.
|
||||
/// </summary>
|
||||
public double ViewScale => (double)GetValue(ViewScaleProperty);
|
||||
|
||||
/// <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)
|
||||
public double ViewScale
|
||||
{
|
||||
var scale = GetScale(location);
|
||||
|
||||
var transform = new Matrix(scale.X, 0d, 0d, scale.Y, 0d, 0d);
|
||||
transform.Rotate(ViewTransform.Rotation);
|
||||
|
||||
return transform;
|
||||
get => (double)GetValue(ViewScaleProperty);
|
||||
private set => SetValue(ViewScaleProperty, value);
|
||||
}
|
||||
|
||||
private void OnSizeChanged(object sender, SizeChangedEventArgs e)
|
||||
|
|
@ -119,11 +109,6 @@ namespace MapControl
|
|||
UpdateTransform();
|
||||
}
|
||||
|
||||
private void SetViewScale(double scale)
|
||||
{
|
||||
SetValue(ViewScaleProperty, scale);
|
||||
}
|
||||
|
||||
private void CenterPropertyChanged(Location value)
|
||||
{
|
||||
if (!internalPropertyChange)
|
||||
|
|
|
|||
Loading…
Reference in a new issue