Added BoundingBox.Rotation

This commit is contained in:
ClemensFischer 2024-09-05 21:27:04 +02:00
parent df661106b6
commit af3a45064d
3 changed files with 43 additions and 56 deletions

View file

@ -21,12 +21,13 @@ namespace MapControl
{ {
} }
public BoundingBox(double latitude1, double longitude1, double latitude2, double longitude2) public BoundingBox(double latitude1, double longitude1, double latitude2, double longitude2, double rotation = 0d)
{ {
South = Math.Min(Math.Max(Math.Min(latitude1, latitude2), -90d), 90d); South = Math.Min(Math.Max(Math.Min(latitude1, latitude2), -90d), 90d);
North = Math.Min(Math.Max(Math.Max(latitude1, latitude2), -90d), 90d); North = Math.Min(Math.Max(Math.Max(latitude1, latitude2), -90d), 90d);
West = Math.Min(longitude1, longitude2); West = Math.Min(longitude1, longitude2);
East = Math.Max(longitude1, longitude2); East = Math.Max(longitude1, longitude2);
Rotation = rotation;
} }
public BoundingBox(Location location1, Location location2) public BoundingBox(Location location1, Location location2)
@ -38,6 +39,7 @@ namespace MapControl
public double North { get; } public double North { get; }
public double West { get; } public double West { get; }
public double East { get; } public double East { get; }
public double Rotation { get; }
public virtual double Width => East - West; public virtual double Width => East - West;
public virtual double Height => North - South; public virtual double Height => North - South;
@ -56,16 +58,21 @@ namespace MapControl
values = boundingBox.Split(new char[] { ',' }); values = boundingBox.Split(new char[] { ',' });
} }
if (values?.Length != 4) if (values == null || values.Length != 4 && values.Length != 5)
{ {
throw new FormatException("BoundingBox string must contain a comma-separated sequence of four floating point numbers."); throw new FormatException("BoundingBox string must contain a comma-separated sequence of four or five floating point numbers.");
} }
var rotation = values.Length == 5
? double.Parse(values[4], NumberStyles.Float, CultureInfo.InvariantCulture)
: 0d;
return new BoundingBox( return new BoundingBox(
double.Parse(values[0], NumberStyles.Float, CultureInfo.InvariantCulture), double.Parse(values[0], NumberStyles.Float, CultureInfo.InvariantCulture),
double.Parse(values[1], NumberStyles.Float, CultureInfo.InvariantCulture), double.Parse(values[1], NumberStyles.Float, CultureInfo.InvariantCulture),
double.Parse(values[2], NumberStyles.Float, CultureInfo.InvariantCulture), double.Parse(values[2], NumberStyles.Float, CultureInfo.InvariantCulture),
double.Parse(values[3], NumberStyles.Float, CultureInfo.InvariantCulture)); double.Parse(values[3], NumberStyles.Float, CultureInfo.InvariantCulture),
rotation);
} }
} }
} }

View file

@ -29,27 +29,16 @@ namespace MapControl
{ {
public class GroundOverlay : MapPanel public class GroundOverlay : MapPanel
{ {
class LatLonBox : BoundingBox
{
public LatLonBox(double south, double west, double north, double east, double rotation)
: base(south, west, north, east)
{
Rotation = rotation;
}
public double Rotation { get; }
}
class ImageOverlay class ImageOverlay
{ {
public ImageOverlay(LatLonBox latLonBox, string imagePath, int zIndex) public ImageOverlay(BoundingBox boundingBox, string imagePath, int zIndex)
{ {
LatLonBox = latLonBox; BoundingBox = boundingBox;
ImagePath = imagePath; ImagePath = imagePath;
ZIndex = zIndex; ZIndex = zIndex;
} }
public LatLonBox LatLonBox { get; } public BoundingBox BoundingBox { get; }
public string ImagePath { get; } public string ImagePath { get; }
public int ZIndex { get; } public int ZIndex { get; }
public ImageSource ImageSource { get; set; } public ImageSource ImageSource { get; set; }
@ -102,26 +91,15 @@ namespace MapControl
{ {
foreach (var imageOverlay in imageOverlays.Where(i => i.ImageSource != null)) foreach (var imageOverlay in imageOverlays.Where(i => i.ImageSource != null))
{ {
FrameworkElement overlay = new Image var image = new Image
{ {
Source = imageOverlay.ImageSource, Source = imageOverlay.ImageSource,
Stretch = Stretch.Fill Stretch = Stretch.Fill
}; };
if (imageOverlay.LatLonBox.Rotation != 0d) image.SetValue(Canvas.ZIndexProperty, imageOverlay.ZIndex);
{ SetBoundingBox(image, imageOverlay.BoundingBox);
SetRenderTransform(overlay, new RotateTransform { Angle = -imageOverlay.LatLonBox.Rotation }, 0.5, 0.5); Children.Add(image);
// Additional Panel for map rotation, see MapPanel.ArrangeElement(FrameworkElement, ViewRect).
//
var panel = new Grid();
panel.Children.Add(overlay);
overlay = panel;
}
SetBoundingBox(overlay, imageOverlay.LatLonBox);
overlay.SetValue(Canvas.ZIndexProperty, imageOverlay.ZIndex);
Children.Add(overlay);
} }
} }
@ -198,8 +176,8 @@ namespace MapControl
{ {
foreach (var groundOverlayElement in folderElement.Elements(ns + "GroundOverlay")) foreach (var groundOverlayElement in folderElement.Elements(ns + "GroundOverlay"))
{ {
var latLonBoxElement = groundOverlayElement.Element(ns + "LatLonBox"); var boundingBoxElement = groundOverlayElement.Element(ns + "LatLonBox");
var latLonBox = latLonBoxElement != null ? ReadLatLonBox(latLonBoxElement) : null; var boundingBox = boundingBoxElement != null ? ReadBoundingBox(boundingBoxElement) : null;
var imagePathElement = groundOverlayElement.Element(ns + "Icon"); var imagePathElement = groundOverlayElement.Element(ns + "Icon");
var imagePath = imagePathElement?.Element(ns + "href")?.Value; var imagePath = imagePathElement?.Element(ns + "href")?.Value;
@ -207,15 +185,15 @@ namespace MapControl
var drawOrder = groundOverlayElement.Element(ns + "drawOrder")?.Value; var drawOrder = groundOverlayElement.Element(ns + "drawOrder")?.Value;
var zIndex = drawOrder != null ? int.Parse(drawOrder) : 0; var zIndex = drawOrder != null ? int.Parse(drawOrder) : 0;
if (latLonBox != null && imagePath != null) if (boundingBox != null && imagePath != null)
{ {
yield return new ImageOverlay(latLonBox, imagePath, zIndex); yield return new ImageOverlay(boundingBox, imagePath, zIndex);
} }
} }
} }
} }
private static LatLonBox ReadLatLonBox(XElement latLonBoxElement) private static BoundingBox ReadBoundingBox(XElement latLonBoxElement)
{ {
var ns = latLonBoxElement.Name.Namespace; var ns = latLonBoxElement.Name.Namespace;
var north = double.NaN; var north = double.NaN;
@ -261,7 +239,7 @@ namespace MapControl
throw new FormatException("Invalid LatLonBox"); throw new FormatException("Invalid LatLonBox");
} }
return new LatLonBox(south, west, north, east, rotation); return new BoundingBox(south, west, north, east, rotation);
} }
} }
} }

View file

@ -277,12 +277,7 @@ namespace MapControl
if (boundingBox != null) if (boundingBox != null)
{ {
var rect = GetViewRect(boundingBox); ArrangeElement(element, boundingBox);
if (rect.HasValue)
{
ArrangeElement(element, rect.Value, parentMap.ViewTransform.Rotation);
}
} }
else else
{ {
@ -291,12 +286,18 @@ namespace MapControl
} }
} }
private static void ArrangeElement(FrameworkElement element, Rect rect, double rotation) private void ArrangeElement(FrameworkElement element, BoundingBox boundingBox)
{ {
element.Width = rect.Width; var rect = GetViewRect(boundingBox);
element.Height = rect.Height;
element.Arrange(rect); if (rect.HasValue)
{
element.Width = rect.Value.Width;
element.Height = rect.Value.Height;
element.Arrange(rect.Value);
var rotation = parentMap.ViewTransform.Rotation - boundingBox.Rotation;
if (element.RenderTransform is RotateTransform rotateTransform) if (element.RenderTransform is RotateTransform rotateTransform)
{ {
@ -307,6 +308,7 @@ namespace MapControl
SetRenderTransform(element, new RotateTransform { Angle = rotation }, 0.5, 0.5); SetRenderTransform(element, new RotateTransform { Angle = rotation }, 0.5, 0.5);
} }
} }
}
private static void ArrangeElement(FrameworkElement element, Point position) private static void ArrangeElement(FrameworkElement element, Point position)
{ {