在 Silverlight 中在 bing 地图上绘制箭头

发布于 2024-09-25 09:05:25 字数 2970 浏览 1 评论 0原文

我需要在 Bing 地图上画线来演示货物运输。为了澄清起点和终点,我在目的地一侧画了一个小箭头。问题是,当我查看全球地图时,某些线条是沿着“后面”的最短路径绘制的。例如,从纽约到东京,将跨越太平洋。由于箭头是单独绘制的,因此是相反的。

>------- 

<-------

当用户在地图上向东/向西滚动时,这个问题会变得更糟,因此欧洲不再居中。

这是我到目前为止的代码。我没有写这个,但仍然需要修复这个问题中提出的错误。如果您有优化建议,请随时提出。

public class MapArrow
{
    private readonly MapPolyline line;
    private readonly MapLayer arrowLayer;
    private readonly Polyline arrowLine;

    #region constructor

    public MapArrow(Location start, Location end)
        : this(start, end, Colors.Red)
    {

    }

    public MapArrow(Location start, Location end)
    {
        color.A = 200;
        Color = Colors.Red;
        drawingColor = Colors.Red;
        HeadWidth = 8;
        HeadHeight = 8;
        StrokeThikness = 5;
        Start = start;
        End = end;

        line = new MapPolyline();
        arrowLayer = new MapLayer();
        arrowLine = new Polyline();
        arrowLayer.AddChild(arrowLine, end);
        UpdateMapLine();
        UpdateArrowPolyline();
    }

    #endregion

    #region properties

    public double HeadWidth { get; set; }

    public double HeadHeight { get; set; }

    public Color Color { get; set; }

    public int StrokeThikness { get; set; }

    public Location Start { get; private set; }

    public Location End { get; private set; }

    public MapPolyline Line
    {
        get
        {
            return line;
        }
    }
    public MapLayer Arrow
    {
        get
        {
            return arrowLayer;
        }
    }

    #endregion

    private void UpdateMapLine()
    {
        line.Stroke = new SolidColorBrush(drawingColor);
        line.StrokeThickness = StrokeThikness;
        line.Opacity = 1;
        line.Locations = new LocationCollection() 
        {
            Start,
            End
        };
    }

    private void UpdateArrowPolyline()
    {
        double theta = Math.Atan2(Start.Latitude - End.Latitude, Start.Longitude - End.Longitude);
        double sint = Math.Sin(theta);
        double cost = Math.Cos(theta);

        Point corner1;
        Point corner2;
        if (!Start.Equals(End))
        {
            corner1 = new Point(
                (HeadWidth*cost - HeadHeight*sint),
                0 - (HeadWidth*sint + HeadHeight*cost));

            corner2 = new Point(
                (HeadWidth*cost + HeadHeight*sint),
                (HeadHeight*cost - HeadWidth*sint));
        }
        else
        {
            corner1 = new Point(0,StrokeThikness/2);
            corner2 = new Point(0,-StrokeThikness/2);
        }

        Point endPoint = new Point(0, 0);

        arrowLine.Stroke = new SolidColorBrush(drawingColor);
        arrowLine.StrokeThickness = StrokeThikness;
        arrowLine.Opacity = 1;

        arrowLine.Points = new PointCollection() 
        {
            corner1,
            endPoint,
            corner2
        };
    }
}

I need to draw lines to demonstrate transportation of goods on Bing maps. To clarify start- and end-point, I draw a little arrowhead on the destination side. The problem is that when I view the global map, certain lines are drawn along the shortest path 'around the back'. For example going from New York City to Tokyo, it would be drawn across the Pacific Ocean. Since the arrowhead is drawn separately it is reversed.

>------- 

instead of

<-------

This problem gets worse when the user scrolls east/west on the map, so that Europe is no longer centered.

This is the code I have so far. I didn't write this, but still have to fix the bug presented in this question. If you have suggestions for optimization, feel free to mention it.

public class MapArrow
{
    private readonly MapPolyline line;
    private readonly MapLayer arrowLayer;
    private readonly Polyline arrowLine;

    #region constructor

    public MapArrow(Location start, Location end)
        : this(start, end, Colors.Red)
    {

    }

    public MapArrow(Location start, Location end)
    {
        color.A = 200;
        Color = Colors.Red;
        drawingColor = Colors.Red;
        HeadWidth = 8;
        HeadHeight = 8;
        StrokeThikness = 5;
        Start = start;
        End = end;

        line = new MapPolyline();
        arrowLayer = new MapLayer();
        arrowLine = new Polyline();
        arrowLayer.AddChild(arrowLine, end);
        UpdateMapLine();
        UpdateArrowPolyline();
    }

    #endregion

    #region properties

    public double HeadWidth { get; set; }

    public double HeadHeight { get; set; }

    public Color Color { get; set; }

    public int StrokeThikness { get; set; }

    public Location Start { get; private set; }

    public Location End { get; private set; }

    public MapPolyline Line
    {
        get
        {
            return line;
        }
    }
    public MapLayer Arrow
    {
        get
        {
            return arrowLayer;
        }
    }

    #endregion

    private void UpdateMapLine()
    {
        line.Stroke = new SolidColorBrush(drawingColor);
        line.StrokeThickness = StrokeThikness;
        line.Opacity = 1;
        line.Locations = new LocationCollection() 
        {
            Start,
            End
        };
    }

    private void UpdateArrowPolyline()
    {
        double theta = Math.Atan2(Start.Latitude - End.Latitude, Start.Longitude - End.Longitude);
        double sint = Math.Sin(theta);
        double cost = Math.Cos(theta);

        Point corner1;
        Point corner2;
        if (!Start.Equals(End))
        {
            corner1 = new Point(
                (HeadWidth*cost - HeadHeight*sint),
                0 - (HeadWidth*sint + HeadHeight*cost));

            corner2 = new Point(
                (HeadWidth*cost + HeadHeight*sint),
                (HeadHeight*cost - HeadWidth*sint));
        }
        else
        {
            corner1 = new Point(0,StrokeThikness/2);
            corner2 = new Point(0,-StrokeThikness/2);
        }

        Point endPoint = new Point(0, 0);

        arrowLine.Stroke = new SolidColorBrush(drawingColor);
        arrowLine.StrokeThickness = StrokeThikness;
        arrowLine.Opacity = 1;

        arrowLine.Points = new PointCollection() 
        {
            corner1,
            endPoint,
            corner2
        };
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

对你的占有欲 2024-10-02 09:05:25

最短的(大圆)是正确的绘制方法。当你放大到二维投影时它会改变吗?

您能否检测正在显示的视图并据此更改方向?

The shortest (Great Circle) is the correct way to draw it. Is it changing when you zoom in to a 2d projection?

Could you detect which view is being displayed and change the orientation based on this?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文