MapPanel, MapPath location coercion

This commit is contained in:
ClemensFischer 2024-08-29 23:56:29 +02:00
parent fb81fff901
commit 27729bf06c
5 changed files with 57 additions and 46 deletions

View file

@ -34,27 +34,15 @@ namespace MapControl
{
}
public double South { get; private set; }
public double North { get; private set; }
public double West { get; private set; }
public double East { get; private set; }
public double South { get; }
public double North { get; }
public double West { get; }
public double East { get; }
public virtual double Width => East - West;
public virtual double Height => North - South;
public virtual Location Center
{
get => new Location((South + North) / 2d, (West + East) / 2d);
set
{
var latOffset = value.Latitude - (South + North) / 2d;
var lonOffset = value.Longitude - (West + East) / 2d;
South += latOffset;
North += latOffset;
West += lonOffset;
East += lonOffset;
}
}
public virtual Location Center => new Location((South + North) / 2d, (West + East) / 2d);
/// <summary>
/// Creates a BoundingBox instance from a string containing a comma-separated sequence of four floating point numbers.

View file

@ -15,7 +15,7 @@ namespace MapControl
Height = Math.Max(height, 0d);
}
public override Location Center { get; set; }
public override Location Center { get; }
public override double Width { get; }
public override double Height { get; }
}

View file

@ -372,6 +372,10 @@ namespace MapControl
}
}
internal bool InsideViewport(Point point) =>
point.X >= 0d && point.X <= ActualWidth &&
point.Y >= 0d && point.Y <= ActualHeight;
internal double CoerceLongitude(double longitude)
{
var offset = longitude - Center.Longitude;

View file

@ -189,32 +189,25 @@ namespace MapControl
protected Point? GetViewPosition(Location location)
{
if (parentMap.MapProjection.Type <= MapProjectionType.NormalCylindrical)
{
var longitude = parentMap.CoerceLongitude(location.Longitude);
var position = parentMap.LocationToView(location);
if (longitude != location.Longitude)
if (parentMap.MapProjection.Type <= MapProjectionType.NormalCylindrical &&
position.HasValue && !parentMap.InsideViewport(position.Value))
{
var coercedPosition = parentMap.LocationToView(
new Location(location.Latitude, parentMap.CoerceLongitude(location.Longitude)));
if (coercedPosition.HasValue && parentMap.InsideViewport(coercedPosition.Value))
{
location = new Location(location.Latitude, longitude);
position = coercedPosition;
}
}
return parentMap.LocationToView(location);
return position;
}
protected ViewRect? GetViewRect(BoundingBox boundingBox)
{
if (parentMap.MapProjection.Type <= MapProjectionType.NormalCylindrical)
{
var center = boundingBox.Center;
var longitude = parentMap.CoerceLongitude(center.Longitude);
if (longitude != center.Longitude)
{
boundingBox.Center = new Location(center.Latitude, longitude);
}
}
var mapRect = parentMap.MapProjection.BoundingBoxToMap(boundingBox);
if (mapRect.HasValue)
@ -227,15 +220,33 @@ namespace MapControl
protected ViewRect GetViewRect(Rect mapRect)
{
var transform = parentMap.ViewTransform;
var center = new Point(mapRect.X + mapRect.Width / 2d, mapRect.Y + mapRect.Height / 2d);
var position = transform.MapToView(center);
var width = mapRect.Width * transform.Scale;
var height = mapRect.Height * transform.Scale;
var position = parentMap.ViewTransform.MapToView(center);
var projection = parentMap.MapProjection;
if (projection.Type <= MapProjectionType.NormalCylindrical &&
!parentMap.InsideViewport(position))
{
var location = projection.MapToLocation(center);
if (location != null)
{
var coercedPosition = parentMap.LocationToView(
new Location(location.Latitude, parentMap.CoerceLongitude(location.Longitude)));
if (coercedPosition.HasValue && parentMap.InsideViewport(coercedPosition.Value))
{
position = coercedPosition.Value;
}
}
}
var width = mapRect.Width * parentMap.ViewTransform.Scale;
var height = mapRect.Height * parentMap.ViewTransform.Scale;
var x = position.X - width / 2d;
var y = position.Y - height / 2d;
return new ViewRect(x, y, width, height, transform.Rotation);
return new ViewRect(x, y, width, height, parentMap.ViewTransform.Rotation);
}
private void ArrangeChildElement(FrameworkElement element, Size panelSize)
@ -250,10 +261,7 @@ namespace MapControl
if (GetAutoCollapse(element))
{
SetVisible(element,
position.HasValue &&
position.Value.X >= 0d && position.Value.X <= parentMap.ActualWidth &&
position.Value.Y >= 0d && position.Value.Y <= parentMap.ActualHeight);
SetVisible(element, position.HasValue && parentMap.InsideViewport(position.Value));
}
if (position.HasValue)

View file

@ -80,9 +80,20 @@ namespace MapControl
{
var longitudeOffset = 0d;
if (location != null && parentMap.MapProjection.Type <= MapProjectionType.NormalCylindrical)
if (parentMap.MapProjection.Type <= MapProjectionType.NormalCylindrical && location != null)
{
longitudeOffset = parentMap.CoerceLongitude(location.Longitude) - location.Longitude;
var position = parentMap.LocationToView(location);
if (position.HasValue && !parentMap.InsideViewport(position.Value))
{
var coercedLongitude = parentMap.CoerceLongitude(location.Longitude);
var coercedPosition = parentMap.LocationToView(new Location(location.Latitude, coercedLongitude));
if (coercedPosition.HasValue && parentMap.InsideViewport(coercedPosition.Value))
{
longitudeOffset = coercedLongitude - location.Longitude;
}
}
}
return longitudeOffset;