LatLonBoxToMap with rotated skew matrix

This commit is contained in:
ClemensFischer 2026-01-26 22:17:46 +01:00
parent ffd1c1c6cd
commit dbc4c142f7
2 changed files with 22 additions and 14 deletions

View file

@ -287,15 +287,16 @@ namespace MapControl
private void ArrangeElement(FrameworkElement element, BoundingBox boundingBox) private void ArrangeElement(FrameworkElement element, BoundingBox boundingBox)
{ {
Rect? mapRect; Rect? mapRect;
var rotation = 0d; Matrix transform;
if (boundingBox is LatLonBox latLonBox) if (boundingBox is LatLonBox latLonBox)
{ {
(mapRect, rotation) = parentMap.MapProjection.LatLonBoxToMap(latLonBox); (mapRect, transform) = parentMap.MapProjection.LatLonBoxToMap(latLonBox);
} }
else else
{ {
mapRect = parentMap.MapProjection.BoundingBoxToMap(boundingBox); mapRect = parentMap.MapProjection.BoundingBoxToMap(boundingBox);
transform = new Matrix(1d, 0d, 0d, 1d, 0d, 0d);
} }
if (mapRect.HasValue) if (mapRect.HasValue)
@ -306,17 +307,19 @@ namespace MapControl
element.Height = viewRect.Height; element.Height = viewRect.Height;
element.Arrange(viewRect); element.Arrange(viewRect);
// LatLonBoxToMap rotation is counterclockwise, RotateTransform is clockwise. transform.Rotate(parentMap.ViewTransform.Rotation);
//
rotation = (parentMap.ViewTransform.Rotation - rotation) % 360d;
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);
} }
} }
} }

View file

@ -165,10 +165,10 @@ namespace MapControl
/// Transforms a LatLonBox in geographic coordinates to a rotated Rect in projected map coordinates. /// Transforms a LatLonBox in geographic coordinates to a rotated Rect in projected map coordinates.
/// Returns (null, 0d) when the LatLonBox can not be transformed. /// Returns (null, 0d) when the LatLonBox can not be transformed.
/// </summary> /// </summary>
public (Rect?, double) LatLonBoxToMap(LatLonBox latLonBox) public (Rect?, Matrix) LatLonBoxToMap(LatLonBox latLonBox)
{ {
Rect? rect = null; Rect? rect = null;
var rotation = 0d; Matrix transform;
var sw = LocationToMap(latLonBox.South, latLonBox.West); var sw = LocationToMap(latLonBox.South, latLonBox.West);
var se = LocationToMap(latLonBox.South, latLonBox.East); var se = LocationToMap(latLonBox.South, latLonBox.East);
var nw = LocationToMap(latLonBox.North, latLonBox.West); var nw = LocationToMap(latLonBox.North, latLonBox.West);
@ -192,12 +192,17 @@ namespace MapControl
rect = new Rect(x, y, width, height); 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() public override string ToString()