Version 4.6.0: Own Point and Matrix to work around rounding errors in UWP

This commit is contained in:
ClemensFischer 2018-03-06 22:22:58 +01:00
parent 30a5b6d53f
commit a3542bf106
30 changed files with 295 additions and 269 deletions

View file

@ -3,9 +3,7 @@
// Licensed under the Microsoft Public License (Ms-PL)
using System;
#if WINDOWS_UWP
using Windows.Foundation;
#else
#if !WINDOWS_UWP
using System.Windows;
#endif

View file

@ -3,9 +3,7 @@
// Licensed under the Microsoft Public License (Ms-PL)
using System;
#if WINDOWS_UWP
using Windows.Foundation;
#else
#if !WINDOWS_UWP
using System.Windows;
#endif

View file

@ -3,9 +3,7 @@
// Licensed under the Microsoft Public License (Ms-PL)
using System;
#if WINDOWS_UWP
using Windows.Foundation;
#else
#if !WINDOWS_UWP
using System.Windows;
#endif

View file

@ -4,7 +4,6 @@
using System;
#if WINDOWS_UWP
using Windows.Foundation;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Media.Animation;

View file

@ -261,7 +261,7 @@ namespace MapControl
var center = new Point(rect.X + rect.Width / 2d, rect.Y + rect.Height / 2d);
rotation = parentMap.Heading;
viewportPosition = projection.ViewportTransform.Transform(center);
viewportPosition = projection.ViewportTransformMatrix.Transform(center);
if (parentMap.MapProjection.IsContinuous &&
(viewportPosition.X < 0d || viewportPosition.X > parentMap.RenderSize.Width ||

View file

@ -25,6 +25,8 @@ namespace MapControl
public const double Wgs84EquatorialRadius = 6378137d;
public const double MetersPerDegree = Wgs84EquatorialRadius * Math.PI / 180d;
private Matrix inverseViewportTransformMatrix;
/// <summary>
/// Gets or sets the WMS 1.3.0 CRS Identifier.
/// </summary>
@ -56,6 +58,11 @@ namespace MapControl
/// </summary>
public double MaxLatitude { get; protected set; } = 90d;
/// <summary>
/// Gets the transformation matrix from cartesian map coordinates to viewport coordinates (pixels).
/// </summary>
public Matrix ViewportTransformMatrix { get; private set; }
/// <summary>
/// Gets the transformation from cartesian map coordinates to viewport coordinates (pixels).
/// </summary>
@ -112,7 +119,7 @@ namespace MapControl
/// </summary>
public Point LocationToViewportPoint(Location location)
{
return ViewportTransform.Transform(LocationToPoint(location));
return ViewportTransformMatrix.Transform(LocationToPoint(location));
}
/// <summary>
@ -120,7 +127,7 @@ namespace MapControl
/// </summary>
public Location ViewportPointToLocation(Point point)
{
return PointToLocation(ViewportTransform.Inverse.Transform(point));
return PointToLocation(inverseViewportTransformMatrix.Transform(point));
}
/// <summary>
@ -128,7 +135,9 @@ namespace MapControl
/// </summary>
public BoundingBox ViewportRectToBoundingBox(Rect rect)
{
return RectToBoundingBox(ViewportTransform.Inverse.TransformBounds(rect));
var transform = new MatrixTransform { Matrix = inverseViewportTransformMatrix };
return RectToBoundingBox(transform.TransformBounds(rect));
}
/// <summary>
@ -139,9 +148,14 @@ namespace MapControl
ViewportScale = Math.Pow(2d, zoomLevel) * PixelPerDegree / TrueScale;
var center = LocationToPoint(mapCenter);
ViewportTransform.Matrix = MatrixEx.TranslateScaleRotateTranslate(
var transformMatrix = CreateTransformMatrix(
-center.X, -center.Y, ViewportScale, -ViewportScale, heading, viewportCenter.X, viewportCenter.Y);
ViewportTransformMatrix = transformMatrix;
ViewportTransform.Matrix = transformMatrix;
transformMatrix.Invert();
inverseViewportTransformMatrix = transformMatrix;
}
/// <summary>
@ -173,5 +187,17 @@ namespace MapControl
return string.Format(CultureInfo.InvariantCulture, format, CrsId,
rect.X, rect.Y, (rect.X + rect.Width), (rect.Y + rect.Height), width, height);
}
public static Matrix CreateTransformMatrix(
double translation1X, double translation1Y,
double scaleX, double scaleY, double rotationAngle,
double translation2X, double translation2Y)
{
var matrix = new Matrix(1d, 0d, 0d, 1d, translation1X, translation1Y);
matrix.Scale(scaleX, scaleY);
matrix.Rotate(rotationAngle);
matrix.Translate(translation2X, translation2Y);
return matrix;
}
}
}

View file

@ -3,7 +3,6 @@
// Licensed under the Microsoft Public License (Ms-PL)
#if WINDOWS_UWP
using Windows.Foundation;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Media;
#else
@ -98,7 +97,7 @@ namespace MapControl
protected Point LocationToViewportPoint(Location location)
{
return parentMap.MapProjection.ViewportTransform.Transform(LocationToPoint(location));
return parentMap.MapProjection.ViewportTransformMatrix.Transform(LocationToPoint(location));
}
protected double GetLongitudeOffset()

View file

@ -312,7 +312,7 @@ namespace MapControl
var transform = new MatrixTransform
{
Matrix = MatrixEx.TranslateScaleRotateTranslate(-viewCenterX, -viewCenterY, scale, scale, -parentMap.Heading, tileCenterX, tileCenterY)
Matrix = MapProjection.CreateTransformMatrix(-viewCenterX, -viewCenterY, scale, scale, -parentMap.Heading, tileCenterX, tileCenterY)
};
var bounds = transform.TransformBounds(new Rect(0d, 0d, parentMap.RenderSize.Width, parentMap.RenderSize.Height));
@ -333,7 +333,7 @@ namespace MapControl
var viewCenterX = parentMap.RenderSize.Width / 2d;
var viewCenterY = parentMap.RenderSize.Height / 2d;
((MatrixTransform)RenderTransform).Matrix = MatrixEx.TranslateScaleRotateTranslate(
((MatrixTransform)RenderTransform).Matrix = MapProjection.CreateTransformMatrix(
-tileOriginX, -tileOriginY, scale, scale, parentMap.Heading, viewCenterX, viewCenterY);
}

View file

@ -3,9 +3,7 @@
// Licensed under the Microsoft Public License (Ms-PL)
using System;
#if WINDOWS_UWP
using Windows.Foundation;
#else
#if !WINDOWS_UWP
using System.Windows;
#endif

View file

@ -3,9 +3,7 @@
// Licensed under the Microsoft Public License (Ms-PL)
using System;
#if WINDOWS_UWP
using Windows.Foundation;
#else
#if !WINDOWS_UWP
using System.Windows;
#endif

View file

@ -3,9 +3,7 @@
// Licensed under the Microsoft Public License (Ms-PL)
using System;
#if WINDOWS_UWP
using Windows.Foundation;
#else
#if !WINDOWS_UWP
using System.Windows;
#endif

View file

@ -3,9 +3,7 @@
// Licensed under the Microsoft Public License (Ms-PL)
using System;
#if WINDOWS_UWP
using Windows.Foundation;
#else
#if !WINDOWS_UWP
using System.Windows;
#endif