You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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的自动地理绑定)。

具体修改步骤:

  1. 删除MapControl.SetLocation(line, nPoint);代码行
  2. 删除所有判断并设置SetNormalizedAnchorPoint的代码块
  3. 调整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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 23:05:33