UWP/WPF MapControl:XAML Line连接Geopoint方向异常问题
问题原因
你遇到的问题核心在于错误地给XAML Line绑定了MapControl的地理定位属性:
- 调用
MapControl.SetLocation(line, nPoint)后,MapControl会接管Line的位置布局,将Line的锚点绑定到第二个地理点的屏幕位置。 - 而你给Line设置的
X1/Y1/X2/Y2是屏幕绝对坐标,并非相对于锚点的相对坐标,这就导致只有当第二个点在第一个点右下方向时,坐标偏移逻辑才刚好匹配,其他方向的Line会被锚点定位规则偏移到错误位置。
解决方案
移除对Line的MapControl.SetLocation和SetNormalizedAnchorPoint调用,直接基于屏幕坐标定位Line即可。XAML Line作为MapControl的子元素,默认在MapControl内部Canvas上以屏幕坐标布局,无需绑定地理点(你已经明确缩放平移后需要重绘,因此无需依赖MapControl的自动地理绑定)。
具体修改步骤:
- 删除
MapControl.SetLocation(line, nPoint);代码行 - 删除所有判断并设置
SetNormalizedAnchorPoint的代码块 - 调整Line的坐标为相对偏移:将第一个点的屏幕坐标作为Line的Canvas定位,Line起点设为(0,0),终点设为两个点的屏幕坐标差
修改后的代码
using System.Collections.Generic; using System.Linq; using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Media; using Windows.Devices.Geolocation; using Windows.UI.Xaml.Shapes; using Windows.UI.Xaml.Controls.Maps; namespace MapControlSandbox { public sealed partial class MainPage : Page { List<BasicGeoposition> ListOfPoints = new List<BasicGeoposition>(); public MainPage() { this.InitializeComponent(); } private void AddCircleToMap(Geopoint nPoint) { Ellipse circle = new Ellipse() { Height = 10, Width = 10, Fill = new SolidColorBrush(Windows.UI.Colors.GreenYellow) }; mapControl.Children.Add(circle); MapControl.SetLocation(circle, nPoint); MapControl.SetNormalizedAnchorPoint(circle, new Windows.Foundation.Point(0.5, 0.5)); } private void mapControl_MapTapped(MapControl sender, MapInputEventArgs args) { var tappedGeoPosition = args.Location.Position; if (ListOfPoints.Count() > 1) ListOfPoints.Clear(); ListOfPoints.Add(tappedGeoPosition); Geopoint nPoint = new Geopoint(tappedGeoPosition, AltitudeReferenceSystem.Ellipsoid); AddCircleToMap(nPoint); if (ListOfPoints.Count() > 1) { // 保留原有MapPolyline绘制逻辑 var mapPolyline = new MapPolyline(); mapPolyline.Path = new Geopath(new List<BasicGeoposition>() { ListOfPoints[0], ListOfPoints[1] }, AltitudeReferenceSystem.Ellipsoid); mapPolyline.StrokeColor = Windows.UI.Colors.Red; mapPolyline.StrokeThickness = 3; mapPolyline.StrokeDashed = true; mapControl.MapElements.Add(mapPolyline); // 修改后的XAML Line绘制逻辑 Windows.Foundation.Point offset1; Windows.Foundation.Point offset2; var gp1 = new Geopoint(ListOfPoints[0], AltitudeReferenceSystem.Ellipsoid); var gp2 = new Geopoint(ListOfPoints[1], AltitudeReferenceSystem.Ellipsoid); mapControl.GetOffsetFromLocation(gp1, out offset1); mapControl.GetOffsetFromLocation(gp2, out offset2); Line line = new Line() { // 设置相对坐标:起点为(0,0),终点为两点屏幕坐标差 X1 = 0, Y1 = 0, X2 = offset2.X - offset1.X, Y2 = offset2.Y - offset1.Y, Stroke = new SolidColorBrush(Windows.UI.Colors.Black), StrokeThickness = 1.0, }; // 将Line定位到第一个点的屏幕位置 Canvas.SetLeft(line, offset1.X); Canvas.SetTop(line, offset1.Y); mapControl.Children.Add(line); } } } }
补充说明
- 若需保留Line的地理绑定(比如希望平移地图时Line自动跟随,缩放仍需重绘),可监听MapControl的
ViewChanged事件,在事件中重新计算Line坐标,而非一开始就绑定Location属性。 - 修改后的代码中,Line位置完全由Canvas.Left/Top和自身相对坐标控制,不受MapControl地理定位规则干扰,所有方向的线条都能正确显示。
内容的提问来源于stack exchange,提问作者AlexS
相关产品推荐
相关产品推荐

