mirror of
https://github.com/ClemensFischer/XAML-Map-Control.git
synced 2026-02-06 07:44:13 +01:00
Changed class Location to readonly struct
This commit is contained in:
parent
d7d7bba5f2
commit
6566167ff0
|
|
@ -21,13 +21,13 @@ namespace MapControl
|
|||
DependencyPropertyHelper.Register<MapBase, Easing>(nameof(AnimationEasing), new QuadraticEaseOut());
|
||||
|
||||
public static readonly StyledProperty<Location> CenterProperty =
|
||||
DependencyPropertyHelper.Register<MapBase, Location>(nameof(Center), new Location(),
|
||||
DependencyPropertyHelper.Register<MapBase, Location>(nameof(Center), new Location(0d, 0d),
|
||||
(map, oldValue, newValue) => map.CenterPropertyChanged(newValue),
|
||||
(map, value) => map.CoerceCenterProperty(value),
|
||||
true);
|
||||
|
||||
public static readonly StyledProperty<Location> TargetCenterProperty =
|
||||
DependencyPropertyHelper.Register<MapBase, Location>(nameof(TargetCenter), new Location(),
|
||||
DependencyPropertyHelper.Register<MapBase, Location>(nameof(TargetCenter), new Location(0d, 0d),
|
||||
async (map, oldValue, newValue) => await map.TargetCenterPropertyChanged(newValue),
|
||||
(map, value) => map.CoerceCenterProperty(value),
|
||||
true);
|
||||
|
|
|
|||
|
|
@ -1,42 +0,0 @@
|
|||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
|
||||
namespace MapControl
|
||||
{
|
||||
/// <summary>
|
||||
/// ContentControl placed on a MapPanel at a geographic location specified by the Location property.
|
||||
/// </summary>
|
||||
public class MapContentControl : ContentControl
|
||||
{
|
||||
public static readonly StyledProperty<bool> AutoCollapseProperty =
|
||||
MapPanel.AutoCollapseProperty.AddOwner<MapContentControl>();
|
||||
|
||||
public static readonly StyledProperty<Location> LocationProperty =
|
||||
MapPanel.LocationProperty.AddOwner<MapContentControl>();
|
||||
|
||||
/// <summary>
|
||||
/// Gets/sets MapPanel.AutoCollapse.
|
||||
/// </summary>
|
||||
public bool AutoCollapse
|
||||
{
|
||||
get => GetValue(AutoCollapseProperty);
|
||||
set => SetValue(AutoCollapseProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets/sets MapPanel.Location.
|
||||
/// </summary>
|
||||
public Location Location
|
||||
{
|
||||
get => GetValue(LocationProperty);
|
||||
set => SetValue(LocationProperty, value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// MapContentControl with a Pushpin Style.
|
||||
/// </summary>
|
||||
public class Pushpin : MapContentControl
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
@ -1,22 +1,10 @@
|
|||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Input;
|
||||
|
||||
namespace MapControl
|
||||
{
|
||||
public partial class MapItem
|
||||
{
|
||||
public static readonly StyledProperty<bool> AutoCollapseProperty =
|
||||
MapPanel.AutoCollapseProperty.AddOwner<MapItem>();
|
||||
|
||||
public static readonly StyledProperty<Location> LocationProperty =
|
||||
MapPanel.LocationProperty.AddOwner<MapItem>();
|
||||
|
||||
static MapItem()
|
||||
{
|
||||
LocationProperty.Changed.AddClassHandler<MapItem, Location>((item, e) => item.UpdateMapTransform());
|
||||
}
|
||||
|
||||
protected override void OnPointerPressed(PointerPressedEventArgs e)
|
||||
{
|
||||
if (e.Pointer.Type != PointerType.Mouse &&
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ namespace MapControl
|
|||
public static readonly AttachedProperty<bool> AutoCollapseProperty =
|
||||
DependencyPropertyHelper.RegisterAttached<bool>("AutoCollapse", typeof(MapPanel));
|
||||
|
||||
public static readonly AttachedProperty<Location> LocationProperty =
|
||||
DependencyPropertyHelper.RegisterAttached<Location>("Location", typeof(MapPanel));
|
||||
public static readonly AttachedProperty<Location?> LocationProperty =
|
||||
DependencyPropertyHelper.RegisterAttached<Location?>("Location", typeof(MapPanel));
|
||||
|
||||
public static readonly AttachedProperty<BoundingBox> BoundingBoxProperty =
|
||||
DependencyPropertyHelper.RegisterAttached<BoundingBox>("BoundingBox", typeof(MapPanel));
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ namespace MapControl
|
|||
|
||||
if (ParentMap != null && locations != null)
|
||||
{
|
||||
var longitudeOffset = GetLongitudeOffset(Location ?? locations.FirstOrDefault());
|
||||
var longitudeOffset = GetLongitudeOffset(locations);
|
||||
|
||||
AddPolylinePoints(figures, locations, longitudeOffset, closed);
|
||||
}
|
||||
|
|
@ -28,7 +28,7 @@ namespace MapControl
|
|||
|
||||
if (ParentMap != null && polygons != null)
|
||||
{
|
||||
var longitudeOffset = GetLongitudeOffset(Location);
|
||||
var longitudeOffset = GetLongitudeOffset(polygons.FirstOrDefault());
|
||||
|
||||
foreach (var locations in polygons)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -5,35 +5,20 @@ namespace MapControl
|
|||
{
|
||||
/// <summary>
|
||||
/// A geographic location with latitude and longitude values in degrees.
|
||||
/// For calculations with azimuth and distance on great circles, see
|
||||
/// https://en.wikipedia.org/wiki/Great_circle,
|
||||
/// https://en.wikipedia.org/wiki/Great-circle_distance,
|
||||
/// https://en.wikipedia.org/wiki/Great-circle_navigation.
|
||||
/// </summary>
|
||||
#if UWP || WINUI
|
||||
[Windows.Foundation.Metadata.CreateFromString(MethodName = "Parse")]
|
||||
#else
|
||||
[System.ComponentModel.TypeConverter(typeof(LocationConverter))]
|
||||
#endif
|
||||
public class Location : IEquatable<Location>
|
||||
public readonly struct Location(double latitude, double longitude) : IEquatable<Location>
|
||||
{
|
||||
// Arithmetic mean radius (2*a + b) / 3 == (1 - f/3) * a.
|
||||
// See https://en.wikipedia.org/wiki/Earth_radius#Arithmetic_mean_radius.
|
||||
//
|
||||
public const double Wgs84MeanRadius = (1d - MapProjection.Wgs84Flattening / 3d) * MapProjection.Wgs84EquatorialRadius;
|
||||
public double Latitude { get; } = Math.Min(Math.Max(latitude, -90d), 90d);
|
||||
public double Longitude => longitude;
|
||||
|
||||
public Location()
|
||||
{
|
||||
}
|
||||
public static bool operator ==(Location loc1, Location loc2) => loc1.Equals(loc2);
|
||||
|
||||
public Location(double latitude, double longitude)
|
||||
{
|
||||
Latitude = Math.Min(Math.Max(latitude, -90d), 90d);
|
||||
Longitude = longitude;
|
||||
}
|
||||
|
||||
public double Latitude { get; }
|
||||
public double Longitude { get; }
|
||||
public static bool operator !=(Location loc1, Location loc2) => !loc1.Equals(loc2);
|
||||
|
||||
public bool LatitudeEquals(double latitude) => Math.Abs(Latitude - latitude) < 1e-9;
|
||||
|
||||
|
|
@ -41,9 +26,9 @@ namespace MapControl
|
|||
|
||||
public bool Equals(double latitude, double longitude) => LatitudeEquals(latitude) && LongitudeEquals(longitude);
|
||||
|
||||
public bool Equals(Location location) => location != null && Equals(location.Latitude, location.Longitude);
|
||||
public bool Equals(Location location) => Equals(location.Latitude, location.Longitude);
|
||||
|
||||
public override bool Equals(object obj) => Equals(obj as Location);
|
||||
public override bool Equals(object obj) => obj is Location location && Equals(location);
|
||||
|
||||
public override int GetHashCode() => Latitude.GetHashCode() ^ Longitude.GetHashCode();
|
||||
|
||||
|
|
@ -81,8 +66,14 @@ namespace MapControl
|
|||
return x < 0d ? x + 180d : x - 180d;
|
||||
}
|
||||
|
||||
// Arithmetic mean radius (2*a + b) / 3 == (1 - f/3) * a.
|
||||
// See https://en.wikipedia.org/wiki/Earth_radius#Arithmetic_mean_radius.
|
||||
//
|
||||
public const double Wgs84MeanRadius = (1d - MapProjection.Wgs84Flattening / 3d) * MapProjection.Wgs84EquatorialRadius;
|
||||
|
||||
/// <summary>
|
||||
/// Calculates great circle azimuth in degrees and distance in meters between this and the specified Location.
|
||||
/// See https://en.wikipedia.org/wiki/Great-circle_navigation#Course.
|
||||
/// </summary>
|
||||
public (double, double) GetAzimuthDistance(Location location, double earthRadius = Wgs84MeanRadius)
|
||||
{
|
||||
|
|
@ -108,6 +99,7 @@ namespace MapControl
|
|||
|
||||
/// <summary>
|
||||
/// Calculates great distance in meters between this and the specified Location.
|
||||
/// See https://en.wikipedia.org/wiki/Great-circle_navigation#Course.
|
||||
/// </summary>
|
||||
public double GetDistance(Location location, double earthRadius = Wgs84MeanRadius)
|
||||
{
|
||||
|
|
@ -118,6 +110,7 @@ namespace MapControl
|
|||
|
||||
/// <summary>
|
||||
/// Calculates the Location on a great circle at the specified azimuth in degrees and distance in meters from this Location.
|
||||
/// See https://en.wikipedia.org/wiki/Great-circle_navigation#Finding_way-points.
|
||||
/// </summary>
|
||||
public Location GetLocation(double azimuth, double distance, double earthRadius = Wgs84MeanRadius)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ namespace MapControl
|
|||
DependencyPropertyHelper.Register<MapBase, MapProjection>(nameof(MapProjection), new WebMercatorProjection(),
|
||||
(map, oldValue, newValue) => map.MapProjectionPropertyChanged(newValue));
|
||||
|
||||
private Location transformCenter;
|
||||
private Location? transformCenter;
|
||||
private Point viewCenter;
|
||||
private double centerLongitude;
|
||||
private double maxLatitude = 85.05112878; // default WebMercatorProjection
|
||||
|
|
@ -326,12 +326,7 @@ namespace MapControl
|
|||
|
||||
private Location CoerceCenterProperty(Location center)
|
||||
{
|
||||
if (center == null)
|
||||
{
|
||||
center = new Location();
|
||||
}
|
||||
else if (
|
||||
center.Latitude < -maxLatitude || center.Latitude > maxLatitude ||
|
||||
if (center.Latitude < -maxLatitude || center.Latitude > maxLatitude ||
|
||||
center.Longitude < -180d || center.Longitude > 180d)
|
||||
{
|
||||
center = new Location(
|
||||
|
|
@ -391,7 +386,7 @@ namespace MapControl
|
|||
|
||||
ViewTransform.SetTransform(mapCenter, viewCenter, viewScale, -Heading);
|
||||
|
||||
if (transformCenter != null)
|
||||
if (transformCenter.HasValue)
|
||||
{
|
||||
var center = ViewToLocation(new Point(ActualWidth / 2d, ActualHeight / 2d));
|
||||
var latitude = center.Latitude;
|
||||
|
|
@ -419,7 +414,7 @@ namespace MapControl
|
|||
{
|
||||
// Check if transform center has moved across 180° longitude.
|
||||
//
|
||||
transformCenterChanged = Math.Abs(center.Longitude - transformCenter.Longitude) > 180d;
|
||||
transformCenterChanged = Math.Abs(center.Longitude - transformCenter.Value.Longitude) > 180d;
|
||||
ResetTransformCenter();
|
||||
mapCenter = MapProjection.LocationToMap(center);
|
||||
ViewTransform.SetTransform(mapCenter, viewCenter, viewScale, -Heading);
|
||||
|
|
|
|||
54
MapControl/Shared/MapContentControl.cs
Normal file
54
MapControl/Shared/MapContentControl.cs
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
#if WPF
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
#elif UWP
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
#elif WINUI
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
#elif AVALONIA
|
||||
using Avalonia.Controls;
|
||||
#endif
|
||||
|
||||
namespace MapControl
|
||||
{
|
||||
/// <summary>
|
||||
/// ContentControl placed on a MapPanel at a geographic location specified by the Location property.
|
||||
/// </summary>
|
||||
public partial class MapContentControl : ContentControl
|
||||
{
|
||||
public static readonly DependencyProperty LocationProperty =
|
||||
DependencyPropertyHelper.Register<MapContentControl, Location>(nameof(Location), default,
|
||||
(control, oldValue, newValue) => MapPanel.SetLocation(control, newValue));
|
||||
|
||||
public static readonly DependencyProperty AutoCollapseProperty =
|
||||
DependencyPropertyHelper.Register<MapContentControl, bool>(nameof(AutoCollapse), false,
|
||||
(control, oldValue, newValue) => MapPanel.SetAutoCollapse(control, newValue));
|
||||
|
||||
/// <summary>
|
||||
/// Gets/sets MapPanel.Location.
|
||||
/// </summary>
|
||||
public Location Location
|
||||
{
|
||||
get => (Location)GetValue(LocationProperty);
|
||||
set => SetValue(LocationProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets/sets MapPanel.AutoCollapse.
|
||||
/// </summary>
|
||||
public bool AutoCollapse
|
||||
{
|
||||
get => (bool)GetValue(AutoCollapseProperty);
|
||||
set => SetValue(AutoCollapseProperty, value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// MapContentControl with a Pushpin Style.
|
||||
/// </summary>
|
||||
public partial class Pushpin : MapContentControl
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
@ -1,10 +1,13 @@
|
|||
#if WPF
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Media;
|
||||
#elif UWP
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using Windows.UI.Xaml.Media;
|
||||
#elif WINUI
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using Microsoft.UI.Xaml.Media;
|
||||
#elif AVALONIA
|
||||
|
|
@ -19,14 +22,17 @@ namespace MapControl
|
|||
/// </summary>
|
||||
public partial class MapItem : ListBoxItem, IMapElement
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets/sets MapPanel.AutoCollapse.
|
||||
/// </summary>
|
||||
public bool AutoCollapse
|
||||
{
|
||||
get => (bool)GetValue(AutoCollapseProperty);
|
||||
set => SetValue(AutoCollapseProperty, value);
|
||||
}
|
||||
public static readonly DependencyProperty LocationProperty =
|
||||
DependencyPropertyHelper.Register<MapItem, Location>(nameof(Location), default,
|
||||
(item, oldValue, newValue) =>
|
||||
{
|
||||
MapPanel.SetLocation(item, newValue);
|
||||
item.UpdateMapTransform();
|
||||
});
|
||||
|
||||
public static readonly DependencyProperty AutoCollapseProperty =
|
||||
DependencyPropertyHelper.Register<MapItem, bool>(nameof(AutoCollapse), false,
|
||||
(item, oldValue, newValue) => MapPanel.SetAutoCollapse(item, newValue));
|
||||
|
||||
/// <summary>
|
||||
/// Gets/sets MapPanel.Location.
|
||||
|
|
@ -37,6 +43,15 @@ namespace MapControl
|
|||
set => SetValue(LocationProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets/sets MapPanel.AutoCollapse.
|
||||
/// </summary>
|
||||
public bool AutoCollapse
|
||||
{
|
||||
get => (bool)GetValue(AutoCollapseProperty);
|
||||
set => SetValue(AutoCollapseProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Implements IMapElement.ParentMap.
|
||||
/// </summary>
|
||||
|
|
@ -94,7 +109,7 @@ namespace MapControl
|
|||
|
||||
private void UpdateMapTransform()
|
||||
{
|
||||
if (MapTransform != null && ParentMap != null && Location != null)
|
||||
if (MapTransform != null && ParentMap != null)
|
||||
{
|
||||
MapTransform.Matrix = ParentMap.GetMapToViewTransform(Location);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ namespace MapControl
|
|||
{
|
||||
var location = MapPanel.GetLocation(ContainerFromItem(item));
|
||||
|
||||
return location != null && predicate(location);
|
||||
return location.HasValue && predicate(location.Value);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -99,15 +99,15 @@ namespace MapControl
|
|||
/// <summary>
|
||||
/// Gets the Location of an element.
|
||||
/// </summary>
|
||||
public static Location GetLocation(FrameworkElement element)
|
||||
public static Location? GetLocation(FrameworkElement element)
|
||||
{
|
||||
return (Location)element.GetValue(LocationProperty);
|
||||
return (Location?)element.GetValue(LocationProperty);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the Location of an element.
|
||||
/// </summary>
|
||||
public static void SetLocation(FrameworkElement element, Location value)
|
||||
public static void SetLocation(FrameworkElement element, Location? value)
|
||||
{
|
||||
element.SetValue(LocationProperty, value);
|
||||
}
|
||||
|
|
@ -261,9 +261,9 @@ namespace MapControl
|
|||
{
|
||||
var location = GetLocation(element);
|
||||
|
||||
if (location != null)
|
||||
if (location.HasValue)
|
||||
{
|
||||
var position = SetViewPosition(element, GetViewPosition(location));
|
||||
var position = SetViewPosition(element, GetViewPosition(location.Value));
|
||||
|
||||
if (GetAutoCollapse(element))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -17,15 +17,15 @@ namespace MapControl
|
|||
public partial class MapPath : IMapElement
|
||||
{
|
||||
public static readonly DependencyProperty LocationProperty =
|
||||
DependencyPropertyHelper.Register<MapPath, Location>(nameof(Location), null,
|
||||
DependencyPropertyHelper.Register<MapPath, Location>(nameof(Location), default,
|
||||
(path, oldValue, newValue) => path.UpdateData());
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a Location that is used as
|
||||
/// - either the origin point of a geometry specified in projected map coordinates (meters)
|
||||
/// - or as an optional anchor point to constrain the view position of MapPaths with multiple
|
||||
/// Locations (like MapPolyline or MapPolygon) to the visible map viewport, as done
|
||||
/// for elements where the MapPanel.Location property is set.
|
||||
/// Gets or sets a Location that is either used as
|
||||
/// - the origin point of a geometry specified in projected map coordinates (meters) or
|
||||
/// - as an optional anchor point to constrain the view position of MapPaths with
|
||||
/// multiple Locations (like MapPolyline or MapPolygon) to the visible map viewport,
|
||||
/// as done for elements where the MapPanel.Location property is set.
|
||||
/// </summary>
|
||||
public Location Location
|
||||
{
|
||||
|
|
@ -64,7 +64,7 @@ namespace MapControl
|
|||
|
||||
protected virtual void UpdateData()
|
||||
{
|
||||
if (ParentMap != null && Location != null && Data != null)
|
||||
if (ParentMap != null && Data != null)
|
||||
{
|
||||
SetDataTransform(ParentMap.GetMapToViewTransform(Location));
|
||||
}
|
||||
|
|
@ -72,23 +72,6 @@ namespace MapControl
|
|||
MapPanel.SetLocation(this, Location);
|
||||
}
|
||||
|
||||
protected double GetLongitudeOffset(Location location)
|
||||
{
|
||||
var longitudeOffset = 0d;
|
||||
|
||||
if (location != null != ParentMap.MapProjection.IsNormalCylindrical)
|
||||
{
|
||||
var position = ParentMap.LocationToView(location);
|
||||
|
||||
if (!ParentMap.InsideViewBounds(position))
|
||||
{
|
||||
longitudeOffset = ParentMap.NearestLongitude(location.Longitude) - location.Longitude;
|
||||
}
|
||||
}
|
||||
|
||||
return longitudeOffset;
|
||||
}
|
||||
|
||||
protected Point LocationToMap(Location location, double longitudeOffset)
|
||||
{
|
||||
var point = ParentMap.MapProjection.LocationToMap(location.Latitude, location.Longitude + longitudeOffset);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,8 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.Linq;
|
||||
|
||||
#if WPF
|
||||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
|
|
@ -37,6 +40,7 @@ namespace MapControl
|
|||
protected MapPolypoint()
|
||||
{
|
||||
Data = new PolypointGeometry();
|
||||
Location = new Location(0d, double.NaN);
|
||||
}
|
||||
|
||||
protected void DataCollectionPropertyChanged(IEnumerable oldValue, IEnumerable newValue)
|
||||
|
|
@ -58,5 +62,35 @@ namespace MapControl
|
|||
{
|
||||
UpdateData();
|
||||
}
|
||||
|
||||
protected double GetLongitudeOffset(IEnumerable<Location> locations)
|
||||
{
|
||||
if (!ParentMap.MapProjection.IsNormalCylindrical)
|
||||
{
|
||||
return 0d;
|
||||
}
|
||||
|
||||
Location location;
|
||||
|
||||
if (!double.IsNaN(Location.Longitude))
|
||||
{
|
||||
location = Location;
|
||||
}
|
||||
else if (locations != null && locations.Any())
|
||||
{
|
||||
location = locations.First();
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0d;
|
||||
}
|
||||
|
||||
if (ParentMap.InsideViewBounds(ParentMap.LocationToView(location)))
|
||||
{
|
||||
return 0d;
|
||||
}
|
||||
|
||||
return ParentMap.NearestLongitude(location.Longitude) - location.Longitude;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,13 +15,13 @@ namespace MapControl
|
|||
new QuadraticEase { EasingMode = EasingMode.EaseOut });
|
||||
|
||||
public static readonly DependencyProperty CenterProperty =
|
||||
DependencyPropertyHelper.Register<MapBase, Location>(nameof(Center), new Location(),
|
||||
DependencyPropertyHelper.Register<MapBase, Location>(nameof(Center), new Location(0d, 0d),
|
||||
(map, oldValue, newValue) => map.CenterPropertyChanged(newValue),
|
||||
(map, value) => map.CoerceCenterProperty(value),
|
||||
true);
|
||||
|
||||
public static readonly DependencyProperty TargetCenterProperty =
|
||||
DependencyPropertyHelper.Register<MapBase, Location>(nameof(TargetCenter), new Location(),
|
||||
DependencyPropertyHelper.Register<MapBase, Location>(nameof(TargetCenter), new Location(0d, 0d),
|
||||
(map, oldValue, newValue) => map.TargetCenterPropertyChanged(newValue),
|
||||
(map, value) => map.CoerceCenterProperty(value),
|
||||
true);
|
||||
|
|
|
|||
|
|
@ -1,47 +1,16 @@
|
|||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace MapControl
|
||||
{
|
||||
/// <summary>
|
||||
/// ContentControl placed on a MapPanel at a geographic location specified by the Location property.
|
||||
/// </summary>
|
||||
public class MapContentControl : ContentControl
|
||||
public partial class MapContentControl
|
||||
{
|
||||
public static readonly DependencyProperty AutoCollapseProperty =
|
||||
MapPanel.AutoCollapseProperty.AddOwner(typeof(MapContentControl));
|
||||
|
||||
public static readonly DependencyProperty LocationProperty =
|
||||
MapPanel.LocationProperty.AddOwner(typeof(MapContentControl));
|
||||
|
||||
static MapContentControl()
|
||||
{
|
||||
DefaultStyleKeyProperty.OverrideMetadata(typeof(MapContentControl), new FrameworkPropertyMetadata(typeof(MapContentControl)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets/sets MapPanel.AutoCollapse.
|
||||
/// </summary>
|
||||
public bool AutoCollapse
|
||||
{
|
||||
get => (bool)GetValue(AutoCollapseProperty);
|
||||
set => SetValue(AutoCollapseProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets/sets MapPanel.Location.
|
||||
/// </summary>
|
||||
public Location Location
|
||||
{
|
||||
get => (Location)GetValue(LocationProperty);
|
||||
set => SetValue(LocationProperty, value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// MapContentControl with a Pushpin Style.
|
||||
/// </summary>
|
||||
public class Pushpin : MapContentControl
|
||||
public partial class Pushpin
|
||||
{
|
||||
static Pushpin()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -6,13 +6,6 @@ namespace MapControl
|
|||
{
|
||||
public partial class MapItem
|
||||
{
|
||||
public static readonly DependencyProperty AutoCollapseProperty =
|
||||
MapPanel.AutoCollapseProperty.AddOwner(typeof(MapItem));
|
||||
|
||||
public static readonly DependencyProperty LocationProperty =
|
||||
MapPanel.LocationProperty.AddOwner(typeof(MapItem),
|
||||
new FrameworkPropertyMetadata(null, (o, e) => ((MapItem)o).UpdateMapTransform()));
|
||||
|
||||
static MapItem()
|
||||
{
|
||||
DefaultStyleKeyProperty.OverrideMetadata(typeof(MapItem), new FrameworkPropertyMetadata(typeof(MapItem)));
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ namespace MapControl
|
|||
DependencyPropertyHelper.RegisterAttached< bool>("AutoCollapse", typeof(MapPanel));
|
||||
|
||||
public static readonly DependencyProperty LocationProperty =
|
||||
DependencyPropertyHelper.RegisterAttached<Location>("Location", typeof(MapPanel), null,
|
||||
DependencyPropertyHelper.RegisterAttached<Location?>("Location", typeof(MapPanel), null,
|
||||
FrameworkPropertyMetadataOptions.AffectsParentArrange);
|
||||
|
||||
public static readonly DependencyProperty BoundingBoxProperty =
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ namespace MapControl
|
|||
|
||||
if (ParentMap != null && locations != null)
|
||||
{
|
||||
var longitudeOffset = GetLongitudeOffset(Location ?? locations.FirstOrDefault());
|
||||
var longitudeOffset = GetLongitudeOffset(locations);
|
||||
|
||||
AddPolylinePoints(context, locations, longitudeOffset, closed);
|
||||
}
|
||||
|
|
@ -25,7 +25,7 @@ namespace MapControl
|
|||
|
||||
if (ParentMap != null && polygons != null)
|
||||
{
|
||||
var longitudeOffset = GetLongitudeOffset(Location);
|
||||
var longitudeOffset = GetLongitudeOffset(polygons.FirstOrDefault());
|
||||
|
||||
foreach (var locations in polygons)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -23,11 +23,11 @@ namespace MapControl
|
|||
new QuadraticEase { EasingMode = EasingMode.EaseOut });
|
||||
|
||||
public static readonly DependencyProperty CenterProperty =
|
||||
DependencyPropertyHelper.Register<MapBase, Location>(nameof(Center), new Location(),
|
||||
DependencyPropertyHelper.Register<MapBase, Location>(nameof(Center), new Location(0d, 0d),
|
||||
(map, oldValue, newValue) => map.CenterPropertyChanged(newValue));
|
||||
|
||||
public static readonly DependencyProperty TargetCenterProperty =
|
||||
DependencyPropertyHelper.Register<MapBase, Location>(nameof(TargetCenter), new Location(),
|
||||
DependencyPropertyHelper.Register<MapBase, Location>(nameof(TargetCenter), new Location(0d, 0d),
|
||||
(map, oldValue, newValue) => map.TargetCenterPropertyChanged(newValue));
|
||||
|
||||
public static readonly DependencyProperty MinZoomLevelProperty =
|
||||
|
|
|
|||
|
|
@ -1,52 +1,21 @@
|
|||
#if UWP
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using Windows.UI.Xaml.Data;
|
||||
#else
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using Microsoft.UI.Xaml.Data;
|
||||
#endif
|
||||
|
||||
namespace MapControl
|
||||
{
|
||||
/// <summary>
|
||||
/// ContentControl placed on a MapPanel at a geographic location specified by the Location property.
|
||||
/// </summary>
|
||||
public partial class MapContentControl : ContentControl
|
||||
public partial class MapContentControl
|
||||
{
|
||||
public static readonly DependencyProperty AutoCollapseProperty =
|
||||
DependencyPropertyHelper.Register<MapContentControl, bool>(nameof(AutoCollapse), false,
|
||||
(control, oldValue, newValue) => MapPanel.SetAutoCollapse(control, newValue));
|
||||
|
||||
public static readonly DependencyProperty LocationProperty =
|
||||
DependencyPropertyHelper.Register<MapContentControl, Location>(nameof(Location), null,
|
||||
(control, oldValue, newValue) => MapPanel.SetLocation(control, newValue));
|
||||
|
||||
public MapContentControl()
|
||||
{
|
||||
DefaultStyleKey = typeof(MapContentControl);
|
||||
MapPanel.InitMapElement(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets/sets MapPanel.AutoCollapse.
|
||||
/// </summary>
|
||||
public bool AutoCollapse
|
||||
{
|
||||
get => (bool)GetValue(AutoCollapseProperty);
|
||||
set => SetValue(AutoCollapseProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets/sets MapPanel.Location.
|
||||
/// </summary>
|
||||
public Location Location
|
||||
{
|
||||
get => (Location)GetValue(LocationProperty);
|
||||
set => SetValue(LocationProperty, value);
|
||||
}
|
||||
|
||||
protected override void OnApplyTemplate()
|
||||
{
|
||||
base.OnApplyTemplate();
|
||||
|
|
@ -76,10 +45,7 @@ namespace MapControl
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// MapContentControl with a Pushpin Style.
|
||||
/// </summary>
|
||||
public class Pushpin : MapContentControl
|
||||
public partial class Pushpin : MapContentControl
|
||||
{
|
||||
public Pushpin()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -16,18 +16,6 @@ namespace MapControl
|
|||
{
|
||||
public partial class MapItem
|
||||
{
|
||||
public static readonly DependencyProperty AutoCollapseProperty =
|
||||
DependencyPropertyHelper.Register<MapItem, bool>(nameof(AutoCollapse), false,
|
||||
(item, oldValue, newValue) => MapPanel.SetAutoCollapse(item, newValue));
|
||||
|
||||
public static readonly DependencyProperty LocationProperty =
|
||||
DependencyPropertyHelper.Register<MapItem, Location>(nameof(Location), null,
|
||||
(item, oldValue, newValue) =>
|
||||
{
|
||||
MapPanel.SetLocation(item, newValue);
|
||||
item.UpdateMapTransform();
|
||||
});
|
||||
|
||||
private Windows.Foundation.Point? pointerPressedPosition;
|
||||
|
||||
public MapItem()
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ namespace MapControl
|
|||
DependencyPropertyHelper.RegisterAttached<bool>("AutoCollapse", typeof(MapPanel));
|
||||
|
||||
public static readonly DependencyProperty LocationProperty =
|
||||
DependencyPropertyHelper.RegisterAttached<Location>("Location", typeof(MapPanel), null,
|
||||
DependencyPropertyHelper.RegisterAttached<Location?>("Location", typeof(MapPanel), null,
|
||||
(element, oldValue, newValue) => (element.Parent as MapPanel)?.InvalidateArrange());
|
||||
|
||||
public static readonly DependencyProperty BoundingBoxProperty =
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ namespace MapControl
|
|||
|
||||
if (ParentMap != null && locations != null)
|
||||
{
|
||||
var longitudeOffset = GetLongitudeOffset(Location ?? locations.FirstOrDefault());
|
||||
var longitudeOffset = GetLongitudeOffset(locations);
|
||||
|
||||
AddPolylinePoints(figures, locations, longitudeOffset, closed);
|
||||
}
|
||||
|
|
@ -31,7 +31,7 @@ namespace MapControl
|
|||
|
||||
if (ParentMap != null && polygons != null)
|
||||
{
|
||||
var longitudeOffset = GetLongitudeOffset(Location);
|
||||
var longitudeOffset = GetLongitudeOffset(polygons.FirstOrDefault());
|
||||
|
||||
foreach (var locations in polygons)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -5,28 +5,12 @@ namespace MapControl
|
|||
/// <summary>
|
||||
/// Replaces Windows.Foundation.Rect for double floating point precision.
|
||||
/// </summary>
|
||||
public readonly struct Rect : IEquatable<Rect>
|
||||
public readonly struct Rect(double x, double y, double width, double height) : IEquatable<Rect>
|
||||
{
|
||||
public Rect(double x, double y, double width, double height)
|
||||
{
|
||||
X = x;
|
||||
Y = y;
|
||||
Width = width;
|
||||
Height = height;
|
||||
}
|
||||
|
||||
public Rect(Point p1, Point p2)
|
||||
{
|
||||
X = Math.Min(p1.X, p2.X);
|
||||
Y = Math.Min(p1.Y, p2.Y);
|
||||
Width = Math.Max(p1.X, p2.X) - X;
|
||||
Height = Math.Max(p1.Y, p2.Y) - Y;
|
||||
}
|
||||
|
||||
public double X { get; }
|
||||
public double Y { get; }
|
||||
public double Width { get; }
|
||||
public double Height { get; }
|
||||
public double X => x;
|
||||
public double Y => y;
|
||||
public double Width => width;
|
||||
public double Height => height;
|
||||
|
||||
public static implicit operator Windows.Foundation.Rect(Rect r) => new(r.X, r.Y, r.Width, r.Height);
|
||||
|
||||
|
|
|
|||
|
|
@ -63,12 +63,9 @@ namespace SampleApplication
|
|||
e.Pointer.Capture(map);
|
||||
var location = map.ViewToLocation(point.Position);
|
||||
|
||||
if (location != null)
|
||||
{
|
||||
map.Cursor = new Cursor(StandardCursorType.Cross);
|
||||
measurementLine.IsVisible = true;
|
||||
measurementLine.Locations = new LocationCollection(location);
|
||||
}
|
||||
map.Cursor = new Cursor(StandardCursorType.Cross);
|
||||
measurementLine.IsVisible = true;
|
||||
measurementLine.Locations = new LocationCollection(location);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -88,23 +85,14 @@ namespace SampleApplication
|
|||
{
|
||||
var location = map.ViewToLocation(e.GetPosition(map));
|
||||
|
||||
if (location != null)
|
||||
{
|
||||
mouseLocation.IsVisible = true;
|
||||
mouseLocation.Text = GetLatLonText(location);
|
||||
mouseLocation.IsVisible = true;
|
||||
mouseLocation.Text = GetLatLonText(location);
|
||||
|
||||
var start = measurementLine.Locations?.FirstOrDefault();
|
||||
|
||||
if (start != null)
|
||||
{
|
||||
measurementLine.Locations = LocationCollection.GeodesicLocations(start, location);
|
||||
mouseLocation.Text += GetDistanceText(location.GetDistance(start));
|
||||
}
|
||||
}
|
||||
else
|
||||
if (measurementLine.Locations != null)
|
||||
{
|
||||
mouseLocation.IsVisible = false;
|
||||
mouseLocation.Text = "";
|
||||
var start = measurementLine.Locations.First();
|
||||
measurementLine.Locations = LocationCollection.GeodesicLocations(start, location);
|
||||
mouseLocation.Text += GetDistanceText(location.GetDistance(start));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -59,11 +59,8 @@ namespace SampleApplication
|
|||
{
|
||||
var location = map.ViewToLocation(point.Position);
|
||||
|
||||
if (location != null)
|
||||
{
|
||||
measurementLine.Visibility = Visibility.Visible;
|
||||
measurementLine.Locations = new LocationCollection(location);
|
||||
}
|
||||
measurementLine.Visibility = Visibility.Visible;
|
||||
measurementLine.Locations = new LocationCollection(location);
|
||||
}
|
||||
else if (e.KeyModifiers.HasFlag(VirtualKeyModifiers.Control) && map.MapLayer is WmsImageLayer wmsLayer)
|
||||
{
|
||||
|
|
@ -87,23 +84,14 @@ namespace SampleApplication
|
|||
var point = e.GetCurrentPoint(map);
|
||||
var location = map.ViewToLocation(point.Position);
|
||||
|
||||
if (location != null)
|
||||
{
|
||||
mouseLocation.Visibility = Visibility.Visible;
|
||||
mouseLocation.Text = GetLatLonText(location);
|
||||
mouseLocation.Visibility = Visibility.Visible;
|
||||
mouseLocation.Text = GetLatLonText(location);
|
||||
|
||||
var start = measurementLine.Locations?.FirstOrDefault();
|
||||
|
||||
if (start != null)
|
||||
{
|
||||
measurementLine.Locations = LocationCollection.GeodesicLocations(start, location);
|
||||
mouseLocation.Text += GetDistanceText(location.GetDistance(start));
|
||||
}
|
||||
}
|
||||
else
|
||||
if (measurementLine.Locations != null)
|
||||
{
|
||||
mouseLocation.Visibility = Visibility.Collapsed;
|
||||
mouseLocation.Text = "";
|
||||
var start = measurementLine.Locations.First();
|
||||
measurementLine.Locations = LocationCollection.GeodesicLocations(start, location);
|
||||
mouseLocation.Text += GetDistanceText(location.GetDistance(start));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ namespace SampleApplication
|
|||
{
|
||||
var location = map.ViewToLocation(e.GetPosition(map));
|
||||
|
||||
if (location != null && map.CaptureMouse())
|
||||
if (map.CaptureMouse())
|
||||
{
|
||||
map.Cursor = Cursors.Cross;
|
||||
measurementLine.Visibility = Visibility.Visible;
|
||||
|
|
@ -100,23 +100,14 @@ namespace SampleApplication
|
|||
{
|
||||
var location = map.ViewToLocation(e.GetPosition(map));
|
||||
|
||||
if (location != null)
|
||||
{
|
||||
mouseLocation.Visibility = Visibility.Visible;
|
||||
mouseLocation.Text = GetLatLonText(location);
|
||||
mouseLocation.Visibility = Visibility.Visible;
|
||||
mouseLocation.Text = GetLatLonText(location);
|
||||
|
||||
var start = measurementLine.Locations?.FirstOrDefault();
|
||||
|
||||
if (start != null)
|
||||
{
|
||||
measurementLine.Locations = LocationCollection.GeodesicLocations(start, location);
|
||||
mouseLocation.Text += GetDistanceText(location.GetDistance(start));
|
||||
}
|
||||
}
|
||||
else
|
||||
if (measurementLine.Locations != null)
|
||||
{
|
||||
mouseLocation.Visibility = Visibility.Collapsed;
|
||||
mouseLocation.Text = "";
|
||||
var start = measurementLine.Locations.First();
|
||||
measurementLine.Locations = LocationCollection.GeodesicLocations(start, location);
|
||||
mouseLocation.Text += GetDistanceText(location.GetDistance(start));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue