diff --git a/MapControl/Shared/MapPanel.cs b/MapControl/Shared/MapPanel.cs index b9387c1f..01329536 100644 --- a/MapControl/Shared/MapPanel.cs +++ b/MapControl/Shared/MapPanel.cs @@ -287,15 +287,16 @@ namespace MapControl private void ArrangeElement(FrameworkElement element, BoundingBox boundingBox) { Rect? mapRect; - var rotation = 0d; + Matrix transform; if (boundingBox is LatLonBox latLonBox) { - (mapRect, rotation) = parentMap.MapProjection.LatLonBoxToMap(latLonBox); + (mapRect, transform) = parentMap.MapProjection.LatLonBoxToMap(latLonBox); } else { mapRect = parentMap.MapProjection.BoundingBoxToMap(boundingBox); + transform = new Matrix(1d, 0d, 0d, 1d, 0d, 0d); } if (mapRect.HasValue) @@ -306,17 +307,19 @@ namespace MapControl element.Height = viewRect.Height; element.Arrange(viewRect); - // LatLonBoxToMap rotation is counterclockwise, RotateTransform is clockwise. - // - rotation = (parentMap.ViewTransform.Rotation - rotation) % 360d; + transform.Rotate(parentMap.ViewTransform.Rotation); - if (element.RenderTransform is RotateTransform rotateTransform) + if (element.RenderTransform is MatrixTransform matrixTransform +#if WPF + && !matrixTransform.IsFrozen +#endif + ) { - rotateTransform.Angle = rotation; + matrixTransform.Matrix = transform; } - else if (rotation != 0d) + else { - element.SetRenderTransform(new RotateTransform { Angle = rotation }, true); + element.SetRenderTransform(new MatrixTransform { Matrix = transform }, true); } } } diff --git a/MapControl/Shared/MapProjection.cs b/MapControl/Shared/MapProjection.cs index 0b695f8b..91ae5c17 100644 --- a/MapControl/Shared/MapProjection.cs +++ b/MapControl/Shared/MapProjection.cs @@ -165,10 +165,10 @@ namespace MapControl /// Transforms a LatLonBox in geographic coordinates to a rotated Rect in projected map coordinates. /// Returns (null, 0d) when the LatLonBox can not be transformed. /// - public (Rect?, double) LatLonBoxToMap(LatLonBox latLonBox) + public (Rect?, Matrix) LatLonBoxToMap(LatLonBox latLonBox) { Rect? rect = null; - var rotation = 0d; + Matrix transform; var sw = LocationToMap(latLonBox.South, latLonBox.West); var se = LocationToMap(latLonBox.South, latLonBox.East); var nw = LocationToMap(latLonBox.North, latLonBox.West); @@ -192,12 +192,17 @@ namespace MapControl rect = new Rect(x, y, width, height); - // Additional rotation from the slope of the line segment west-east. + // Skew matrix with skewX = Atan(-dx2 / dy2) and skewY = Atan(-dy1 / dx1). // - rotation = (latLonBox.Rotation + Math.Atan2(dy1, dx1) * 180d / Math.PI) % 360d; + transform = new Matrix(1d, -dy1 / dx1, -dx2 / dy2, 1d, 0d, 0d); + transform.Rotate(-latLonBox.Rotation); + } + else + { + transform = new Matrix(1d, 0d, 0d, 1d, 0d, 0d); } - return (rect, rotation); + return (rect, transform); } public override string ToString()