mirror of
https://github.com/ClemensFischer/XAML-Map-Control.git
synced 2025-12-06 07:12:04 +01:00
Reworked MapPath and derived classes
This commit is contained in:
parent
414389513e
commit
49d508b3f5
|
|
@ -84,7 +84,7 @@ namespace MapControl
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Normalizes a longitude to a value in the interval [-180..180].
|
||||
/// Normalizes a longitude to a value in the interval [-180 .. 180].
|
||||
/// </summary>
|
||||
public static double NormalizeLongitude(double longitude)
|
||||
{
|
||||
|
|
@ -99,21 +99,5 @@ namespace MapControl
|
|||
|
||||
return longitude;
|
||||
}
|
||||
|
||||
internal static double NearestLongitude(double longitude, double referenceLongitude)
|
||||
{
|
||||
longitude = NormalizeLongitude(longitude);
|
||||
|
||||
if (longitude > referenceLongitude + 180d)
|
||||
{
|
||||
longitude -= 360d;
|
||||
}
|
||||
else if (longitude < referenceLongitude - 180d)
|
||||
{
|
||||
longitude += 360d;
|
||||
}
|
||||
|
||||
return longitude;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -370,6 +370,22 @@ namespace MapControl
|
|||
TargetHeading = 0d;
|
||||
}
|
||||
|
||||
internal double ConstrainedLongitude(double longitude)
|
||||
{
|
||||
var offset = longitude - Center.Longitude;
|
||||
|
||||
if (offset > 180d)
|
||||
{
|
||||
longitude = Center.Longitude - 360d + offset % 360d;
|
||||
}
|
||||
else if (offset < -180d)
|
||||
{
|
||||
longitude = Center.Longitude + 360d + offset % 360d;
|
||||
}
|
||||
|
||||
return longitude;
|
||||
}
|
||||
|
||||
private void MapLayerPropertyChanged(UIElement oldLayer, UIElement newLayer)
|
||||
{
|
||||
if (oldLayer != null)
|
||||
|
|
@ -458,10 +474,6 @@ namespace MapControl
|
|||
|
||||
if (!targetCenter.Equals(Center))
|
||||
{
|
||||
var targetCenterLongitude = MapProjection.IsNormalCylindrical
|
||||
? Location.NearestLongitude(targetCenter.Longitude, Center.Longitude)
|
||||
: targetCenter.Longitude;
|
||||
|
||||
if (centerAnimation != null)
|
||||
{
|
||||
centerAnimation.Completed -= CenterAnimationCompleted;
|
||||
|
|
@ -470,7 +482,7 @@ namespace MapControl
|
|||
centerAnimation = new PointAnimation
|
||||
{
|
||||
From = new Point(Center.Longitude, Center.Latitude),
|
||||
To = new Point(targetCenterLongitude, targetCenter.Latitude),
|
||||
To = new Point(ConstrainedLongitude(targetCenter.Longitude), targetCenter.Latitude),
|
||||
Duration = AnimationDuration,
|
||||
EasingFunction = AnimationEasingFunction
|
||||
};
|
||||
|
|
|
|||
|
|
@ -151,9 +151,9 @@ namespace MapControl
|
|||
(pos.X < 0d || pos.X > parentMap.RenderSize.Width ||
|
||||
pos.Y < 0d || pos.Y > parentMap.RenderSize.Height))
|
||||
{
|
||||
pos = parentMap.LocationToView(new Location(
|
||||
location.Latitude,
|
||||
Location.NearestLongitude(location.Longitude, parentMap.Center.Longitude)));
|
||||
location = new Location(location.Latitude, parentMap.ConstrainedLongitude(location.Longitude));
|
||||
|
||||
pos = parentMap.LocationToView(location);
|
||||
}
|
||||
|
||||
var rect = new Rect(pos, element.DesiredSize);
|
||||
|
|
@ -208,7 +208,7 @@ namespace MapControl
|
|||
pos.Y < 0d || pos.Y > parentMap.RenderSize.Height))
|
||||
{
|
||||
var location = projection.MapToLocation(center);
|
||||
location.Longitude = Location.NearestLongitude(location.Longitude, parentMap.Center.Longitude);
|
||||
location.Longitude = parentMap.ConstrainedLongitude(location.Longitude);
|
||||
|
||||
pos = parentMap.LocationToView(location);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,11 +20,9 @@ namespace MapControl
|
|||
{
|
||||
public static readonly DependencyProperty LocationProperty = DependencyProperty.Register(
|
||||
nameof(Location), typeof(Location), typeof(MapPath),
|
||||
new PropertyMetadata(null, (o, e) => ((MapPath)o).LocationOrViewportChanged()));
|
||||
new PropertyMetadata(null, (o, e) => ((MapPath)o).UpdateData()));
|
||||
|
||||
private MapBase parentMap;
|
||||
private MatrixTransform dataTransform;
|
||||
private double longitudeOffset;
|
||||
|
||||
public MapPath()
|
||||
{
|
||||
|
|
@ -61,30 +59,12 @@ namespace MapControl
|
|||
parentMap.ViewportChanged += OnViewportChanged;
|
||||
}
|
||||
|
||||
LocationOrViewportChanged();
|
||||
UpdateData();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnViewportChanged(object sender, ViewportChangedEventArgs e)
|
||||
{
|
||||
LocationOrViewportChanged();
|
||||
}
|
||||
|
||||
private void LocationOrViewportChanged()
|
||||
{
|
||||
longitudeOffset = 0d;
|
||||
|
||||
if (parentMap != null && parentMap.MapProjection.IsNormalCylindrical && Location != null)
|
||||
{
|
||||
var viewPos = LocationToView(Location);
|
||||
|
||||
if (viewPos.X < 0d || viewPos.X > parentMap.RenderSize.Width ||
|
||||
viewPos.Y < 0d || viewPos.Y > parentMap.RenderSize.Height)
|
||||
{
|
||||
longitudeOffset = Location.NearestLongitude(Location.Longitude, parentMap.Center.Longitude) - Location.Longitude;
|
||||
}
|
||||
}
|
||||
|
||||
UpdateData();
|
||||
}
|
||||
|
||||
|
|
@ -92,21 +72,48 @@ namespace MapControl
|
|||
{
|
||||
if (parentMap != null && Data != null && Location != null)
|
||||
{
|
||||
if (dataTransform == null)
|
||||
var location = Location;
|
||||
var viewPos = parentMap.LocationToView(location);
|
||||
|
||||
if (parentMap.MapProjection.IsNormalCylindrical &&
|
||||
(viewPos.X < 0d || viewPos.X > parentMap.RenderSize.Width ||
|
||||
viewPos.Y < 0d || viewPos.Y > parentMap.RenderSize.Height))
|
||||
{
|
||||
Data.Transform = dataTransform = new MatrixTransform();
|
||||
location = new Location(location.Latitude, parentMap.ConstrainedLongitude(location.Longitude));
|
||||
viewPos = parentMap.LocationToView(location);
|
||||
}
|
||||
|
||||
var viewPos = LocationToView(Location);
|
||||
var scale = parentMap.GetScale(Location);
|
||||
var scale = parentMap.GetScale(location);
|
||||
var transform = new Matrix(scale.X, 0d, 0d, scale.Y, 0d, 0d);
|
||||
|
||||
transform.Rotate(parentMap.ViewTransform.Rotation);
|
||||
transform.Translate(viewPos.X, viewPos.Y);
|
||||
dataTransform.Matrix = transform;
|
||||
|
||||
Data.Transform = new MatrixTransform { Matrix = transform };
|
||||
}
|
||||
}
|
||||
|
||||
protected Point LocationToMap(Location location)
|
||||
#region Method used only by derived classes MapPolyline, MapPolygon and MapMultiPolygon
|
||||
|
||||
protected double GetLongitudeOffset(Location location)
|
||||
{
|
||||
var longitudeOffset = 0d;
|
||||
|
||||
if (location != null && parentMap.MapProjection.IsNormalCylindrical)
|
||||
{
|
||||
var viewPos = parentMap.LocationToView(location);
|
||||
|
||||
if (viewPos.X < 0d || viewPos.X > parentMap.RenderSize.Width ||
|
||||
viewPos.Y < 0d || viewPos.Y > parentMap.RenderSize.Height)
|
||||
{
|
||||
longitudeOffset = parentMap.ConstrainedLongitude(location.Longitude) - location.Longitude;
|
||||
}
|
||||
}
|
||||
|
||||
return longitudeOffset;
|
||||
}
|
||||
|
||||
protected Point LocationToMap(Location location, double longitudeOffset)
|
||||
{
|
||||
if (longitudeOffset != 0d)
|
||||
{
|
||||
|
|
@ -127,9 +134,11 @@ namespace MapControl
|
|||
return point;
|
||||
}
|
||||
|
||||
protected Point LocationToView(Location location)
|
||||
protected Point LocationToView(Location location, double longitudeOffset)
|
||||
{
|
||||
return parentMap.ViewTransform.MapToView(LocationToMap(location));
|
||||
return parentMap.ViewTransform.MapToView(LocationToMap(location, longitudeOffset));
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
// Licensed under the Microsoft Public License (Ms-PL)
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
#if WINDOWS_UWP
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Media;
|
||||
|
|
@ -42,12 +43,14 @@ namespace MapControl
|
|||
|
||||
protected override void UpdateData()
|
||||
{
|
||||
var figures = ((PathGeometry)Data).Figures;
|
||||
figures.Clear();
|
||||
var pathFigures = ((PathGeometry)Data).Figures;
|
||||
pathFigures.Clear();
|
||||
|
||||
if (ParentMap != null)
|
||||
if (ParentMap != null && Locations != null)
|
||||
{
|
||||
AddPolylineLocations(figures, Locations, true);
|
||||
var longitudeOffset = GetLongitudeOffset(Location ?? Locations.FirstOrDefault());
|
||||
|
||||
AddPolylineLocations(pathFigures, Locations, longitudeOffset, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
// Licensed under the Microsoft Public License (Ms-PL)
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
#if WINDOWS_UWP
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Media;
|
||||
|
|
@ -42,12 +43,14 @@ namespace MapControl
|
|||
|
||||
protected override void UpdateData()
|
||||
{
|
||||
var figures = ((PathGeometry)Data).Figures;
|
||||
figures.Clear();
|
||||
var pathFigures = ((PathGeometry)Data).Figures;
|
||||
pathFigures.Clear();
|
||||
|
||||
if (ParentMap != null)
|
||||
if (ParentMap != null && Locations != null)
|
||||
{
|
||||
AddPolylineLocations(figures, Locations, false);
|
||||
var longitudeOffset = GetLongitudeOffset(Location ?? Locations.FirstOrDefault());
|
||||
|
||||
AddPolylineLocations(pathFigures, Locations, longitudeOffset, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,10 +14,7 @@ namespace MapControl
|
|||
{
|
||||
public partial class MapPath : Path
|
||||
{
|
||||
protected void DataCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
|
||||
{
|
||||
UpdateData();
|
||||
}
|
||||
#region Method used only by derived classes MapPolyline and MapPolygon
|
||||
|
||||
protected void DataCollectionPropertyChanged(DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
|
|
@ -34,11 +31,17 @@ namespace MapControl
|
|||
UpdateData();
|
||||
}
|
||||
|
||||
protected void AddPolylineLocations(PathFigureCollection figures, IEnumerable<Location> locations, bool closed)
|
||||
protected void DataCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
|
||||
{
|
||||
if (locations != null && locations.Count() >= 2)
|
||||
UpdateData();
|
||||
}
|
||||
|
||||
protected void AddPolylineLocations(PathFigureCollection pathFigures, IEnumerable<Location> locations, double longitudeOffset, bool closed)
|
||||
{
|
||||
if (locations.Count() >= 2)
|
||||
{
|
||||
var points = locations.Select(loc => LocationToView(loc)).ToList();
|
||||
var points = locations.Select(location => LocationToView(location, longitudeOffset)).ToList();
|
||||
|
||||
if (closed)
|
||||
{
|
||||
points.Add(points[0]);
|
||||
|
|
@ -67,7 +70,7 @@ namespace MapControl
|
|||
|
||||
segment = new PolyLineSegment();
|
||||
figure.Segments.Add(segment);
|
||||
figures.Add(figure);
|
||||
pathFigures.Add(figure);
|
||||
}
|
||||
|
||||
segment.Points.Add(p2);
|
||||
|
|
@ -80,5 +83,7 @@ namespace MapControl
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,14 +38,16 @@ namespace MapControl
|
|||
|
||||
protected override void UpdateData()
|
||||
{
|
||||
var figures = ((PathGeometry)Data).Figures;
|
||||
figures.Clear();
|
||||
var pathFigures = ((PathGeometry)Data).Figures;
|
||||
pathFigures.Clear();
|
||||
|
||||
if (ParentMap != null && Polygons != null)
|
||||
{
|
||||
var longitudeOffset = GetLongitudeOffset(Location);
|
||||
|
||||
foreach (var polygon in Polygons)
|
||||
{
|
||||
AddPolylineLocations(figures, polygon, true);
|
||||
AddPolylineLocations(pathFigures, polygon, longitudeOffset, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,11 +27,7 @@ namespace MapControl
|
|||
get { return Data; }
|
||||
}
|
||||
|
||||
public bool ReceiveWeakEvent(Type managerType, object sender, EventArgs e)
|
||||
{
|
||||
UpdateData();
|
||||
return true;
|
||||
}
|
||||
#region Method used only by derived classes MapPolyline, MapPolygon and MapMultiPolygon
|
||||
|
||||
protected void DataCollectionPropertyChanged(DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
|
|
@ -48,11 +44,17 @@ namespace MapControl
|
|||
UpdateData();
|
||||
}
|
||||
|
||||
protected void AddPolylineLocations(PathFigureCollection figures, IEnumerable<Location> locations, bool closed)
|
||||
bool IWeakEventListener.ReceiveWeakEvent(Type managerType, object sender, EventArgs e)
|
||||
{
|
||||
if (locations != null && locations.Count() >= 2)
|
||||
UpdateData();
|
||||
return true;
|
||||
}
|
||||
|
||||
protected void AddPolylineLocations(PathFigureCollection pathFigures, IEnumerable<Location> locations, double longitudeOffset, bool closed)
|
||||
{
|
||||
if (locations.Count() >= 2)
|
||||
{
|
||||
var points = locations.Select(loc => LocationToView(loc));
|
||||
var points = locations.Select(location => LocationToView(location, longitudeOffset));
|
||||
var figure = new PathFigure
|
||||
{
|
||||
StartPoint = points.First(),
|
||||
|
|
@ -61,8 +63,10 @@ namespace MapControl
|
|||
};
|
||||
|
||||
figure.Segments.Add(new PolyLineSegment(points.Skip(1), true));
|
||||
figures.Add(figure);
|
||||
pathFigures.Add(figure);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue