views:

140

answers:

1

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. Problem is, 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 Tokio, 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 scroll east/west on the map, so that Europe is no longer centered.

This is the code I have so far. Problem is, I didn't write this, but still have 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
        };
    }
}
A: 

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?

winwaed