Drawing arrow heads on Polylines

Sometimes adding an arrow head to polyline is desired. There are a couple of ways to do this. One way is to use arrow head images as icons and rotate to point in the desired direction. A second method is to extend the polyline and draw the arrow point. The flowing code shows you how to implement the second method.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
   <head>
      <title></title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <script src="http://dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=6.2"></script>
    <script>
    var earthRadius = 6367; //radius in km
    var map;
    var point1 = new VELatLong(40.02,-105.03);
    var point2 = new VELatLong(40.02,-105.02);
    var point3 = new VELatLong(40.015,-105.025);
    function GetMap()
    {
        map = new VEMap(‘mymap’);
        map.LoadMap();
        var points = generatePolylinePointsWithArrow([point1,point2,point3]);
        var polyline = new VEShape(VEShapeType.Polyline,points);
        polyline.HideIcon();
        map.AddShape(polyline);
        map.SetMapView(points);
    }
    function generatePolylinePointsWithArrow(points)
    {
        //last point in polyline array
        var anchorPoint = points[points.length-1];
        //bearing from last point to second last point in pointline array
        var bearing = calculateBearing(anchorPoint,points[points.length-2]);
        //length of arrow head lines in km
        var arrowLength = 0.05;
        //angle of arrow lines relative to polyline in degrees
        var arrowAngle = 15;
        //calculate coordinates of arrow tips
        var arrowPoint1 = calculateCoord(anchorPoint, bearing-arrowAngle, arrowLength);
        var arrowPoint2 = calculateCoord(anchorPoint, bearing+arrowAngle, arrowLength);
        //go from last point in polyline to one arrow tip, then back to the 
        //last point then to the second arrow tip.
        points.push(arrowPoint1);
        points.push(anchorPoint);
        points.push(arrowPoint2);
        return points;
    }
    function DegtoRad(x)
    {
        return x*Math.PI/180;
    }
    function RadtoDeg(x)
    {
        return x*180/Math.PI;
    }
    function calculateCoord(origin, brng, arcLength)
    {
        var lat1 = DegtoRad(origin.Latitude);
        var lon1 = DegtoRad(origin.Longitude);
        var centralAngle = arcLength /earthRadius;
        var lat2 = Math.asin( Math.sin(lat1)*Math.cos(centralAngle) + Math.cos(lat1)*Math.sin(centralAngle)*Math.cos(DegtoRad(brng)));
        var lon2 = lon1+Math.atan2(Math.sin(DegToRad(brng))*Math.sin(centralAngle)*Math.cos(lat1),Math.cos(centralAngle)-Math.sin(lat1)*Math.sin(lat2));
        return new VELatLong(RadtoDeg(lat2),RadtoDeg(lon2));
    }
    function calculateBearing(A,B)
    {
        var lat1 = DegtoRad(A.Latitude);
        var lon1 = A.Longitude;
        var lat2 = DegtoRad(B.Latitude);
        var lon2 = B.Longitude;
        var dLon = DegtoRad(lon2-lon1);
        var y = Math.sin(dLon) * Math.cos(lat2);
        var x = Math.cos(lat1)*Math.sin(lat2) – Math.sin(lat1)*Math.cos(lat2)*Math.cos(dLon);
        var brng = (RadtoDeg(Math.atan2(y, x))+360)%360;
        return brng;
    }
      </script>
      </head>
   <body onload="GetMap();">
        <div id=’mymap’ style="position:relative; height:400px; width:800px;"></div>
   </body>
</html>

Advertisements

11 thoughts on “Drawing arrow heads on Polylines

  1. Hello Ricky,

    I am developing bing map and drawing object like polyline,polygon,rectangle and circle using bing map api.
    I have successfully drawn all these object.
    Now i want to add new point in any object.
    Say for example i have drawn polygon on bing map but now i have to add another point in bing map and point should be on line of polygon it should not be inside or outside of polygon.
    Must be exactly on polygon’s Line.
    Say for example.
    I have five line
    1. A-B
    2. B-C
    3. C-D
    4. C-E
    5. E-A
    If i clicked on A-B than point should be added between A-B else it should not be.
    Can any one help me how can i do that?

    Thanks isn advance.

    • Using regular javascript this is not possible, you will need several images at different angles and update the icon. Using HTML 5 might work but will only work on HTML5 browsers.

    • That’s an old post. An easy option is to use custom pushpins for arrows. You just need one image and you can use CSS transforms to rotate it. If you specify the HTML content of the pushpin with an image tag with a style property, this should be fairly easy to do. You will need to calculate the angles to rotate the arrows though. To start off with have the arrow point up. This will align with north (0 degrees). You can then take two coordinate pairs an calculate their direction. One option to do this is to use the spatially accurate method: https://rbrundritt.wordpress.com/2008/10/14/calculating-bearing/ However, this may not look great in some cases as the lines in Bing Maps are not geodesic (follow curvature of the earth), so their visual angle can be slightly different. For a more visually appealing rotation of the arrow icon turn the coordinate pairs into pixel coordinates using the maps tryLocationToPixel function, then use simple geometry to calculate the angle between the points.

  2. Please can you help me again?i have a project in gis and i have to create a database for my project.How can i create it?

  3. Please can you help me again?i have a project in gis and i have to create a database for my project.How can i create it?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s