0

I want to calculate the maneuver details (turn-left, turn-right, etc) from the coordinates array returned by google roads API. I know maneuver details only returned by google directions API. But If I draw custom routes using roads API then how do I calculate maneuver details? I tried to calculate the degrees between two coordinates using this code:

function radians(n) {
  return n * (Math.PI / 180);
}
function degrees(n) {
  return n * (180 / Math.PI);
}

function getBearing(startLat,startLong,endLat,endLong){
  startLat = radians(startLat);
  startLong = radians(startLong);
  endLat = radians(endLat);
  endLong = radians(endLong);

  var dLong = endLong - startLong;

  var dPhi = Math.log(Math.tan(endLat/2.0+Math.PI/4.0)/Math.tan(startLat/2.0+Math.PI/4.0));
  if (Math.abs(dLong) > Math.PI){
    if (dLong > 0.0)
       dLong = -(2.0 * Math.PI - dLong);
    else
       dLong = (2.0 * Math.PI + dLong);
  }

  return (degrees(Math.atan2(dLong, dPhi)) + 360.0) % 360.0;
}

this function returns degrees, but I don't know how to calculate or what is the logic to manipulate the maneuver details from the degrees?

Is there any other way to calculate maneuver details from coordinates?

Poles
  • 3,585
  • 9
  • 43
  • 91

2 Answers2

0

I did something like this in c#. First I calculated Slopes of Line Joining two points. 2nd Colum of Datatable "create Path" was X amd 3rd Column was Y

    /// <Find Slopes>
    /// Find Slopes Between 2 Nodes:Value of Slope in radians
    /// </summary>
    /// <param name="createPath"></param>
    /// <returns></returns>
    public List <double> slope(DataTable createPath)
    {
        List<double> slopes = new List<double>();
        for (int i = 1; i < createPath.Rows.Count; i++)
        {      
            slopes.Add (Math.Atan2((Convert.ToDouble(createPath.Rows[i][2]) - Convert.ToDouble(createPath.Rows[i - 1][2])),
                (Convert.ToDouble(createPath.Rows[i][1]) - Convert.ToDouble(createPath.Rows[i - 1][1]))));      
        }
        return slopes;
    }

once you get slopes

    /// <Directions: Turns Left or Right.>
    /// 
    /// </summary>
    /// <param name="createPath"></param>
    /// <returns></returns>
    public List<string> manoeuvre(DataTable createPath)
    {
        List<string> theManoeuvre = new List<string>();
        List<double> slopes = new List<double>();
        slopes = slope(createPath);
        int count = (slopes.Count);
        //Checking For Starights
        for (int i=1; i<count; i++)
        {
            if ((slopes[i]-slopes[i-1]) == 0)// Staright Combination
            {
                if (slopes[i-1] ==0)
                    theManoeuvre.Add("Straight Right");
                else if (slopes[i-1] == Math.PI)
                    theManoeuvre.Add("Straight Left");
                else if (slopes[i-1] == (Math.PI)/2)
                    theManoeuvre.Add("Straight Up");
                else if (slopes[i-1] == -(Math.PI)/2)
                    theManoeuvre.Add("Straight Down");
                else
                    theManoeuvre.Add("Slant");
            }
            else if ((((slopes[i] - slopes[i - 1]) > 0) && ((slopes[i] - slopes[i - 1]) <= Math.PI)) ||
                (((slopes[i] - slopes[i - 1]) < (-1 * Math.PI)) && ((slopes[i] - slopes[i - 1]) > (-2 * Math.PI))))
            {
                if (Convert.ToDouble(createPath.Rows[i][5]) != Convert.ToDouble(createPath.Rows[i+1][5]))

                    theManoeuvre.Add("Turn Left");
                else
                    theManoeuvre.Add("Lane Change");

            }
            else
            {
                if (Convert.ToDouble(createPath.Rows[i][5]) != Convert.ToDouble(createPath.Rows[i + 1][5]))

                    theManoeuvre.Add("Turn Right");
                else
                    theManoeuvre.Add("Lane Change"); 
            }
        }
        return theManoeuvre;
    }

I hope it helps you. just to find the conditions.

  • When there is a straight Line between 2 points (x1,y1) and (x2,y2). then the Slope = arctan ((y2-y1)/(x2-x1)). This is a very commanly used term in geometry. To find maneuver you need to compare two such straight lines. (ie. 3 points now.) if three points are in line then you are going staright. if not then you make some turn. Depending on Change of slopes of those 2 lines you calculate left or right. – Abhishek Kumar Sep 01 '15 at 10:06
  • I am trying. I will let you know. Thanks. – Poles Sep 01 '15 at 11:58
  • Please tell me what value exists in `createPath.Rows[i][5]` ? – Poles Sep 01 '15 at 13:10
  • I am going to give you another answer if you don't need lane change. – Abhishek Kumar Sep 01 '15 at 13:36
  • Ok, It will be great. – Poles Sep 01 '15 at 13:38
0

Here is another answer without i+5,

    public List<string> manoeuvre(DataTable createPath)
    {
        List<string> theManoeuvre = new List<string>();
        List<double> slopes = new List<double>();
        slopes = slope(createPath);
        int count = (slopes.Count);
        //Checking For Starights
        for (int i=1; i<count; i++)
        {
            if ((slopes[i]-slopes[i-1]) == 0)// Staright Combination
            {
                if (slopes[i-1] ==0)
                    theManoeuvre.Add("Straight Right");
                else if (slopes[i-1] == Math.PI)
                    theManoeuvre.Add("Straight Left");
                else if (slopes[i-1] == (Math.PI)/2)
                    theManoeuvre.Add("Straight Up");
                else if (slopes[i-1] == -(Math.PI)/2)
                    theManoeuvre.Add("Straight Down");
                else
                    theManoeuvre.Add("Slant");
            }
            else if ((((slopes[i] - slopes[i - 1]) > 0) && ((slopes[i] - slopes[i - 1]) <= Math.PI)) ||
                (((slopes[i] - slopes[i - 1]) < (-1 * Math.PI)) && ((slopes[i] - slopes[i - 1]) > (-2 * Math.PI))))
            {
                theManoeuvre.Add("Turn Left");
            }
            else
                theManoeuvre.Add("Turn Right");
        }
        return theManoeuvre;
    }

I us sixth column for putting the supposed Orientation of a Vehicle at that point to determine if its going be a lane change or just a right turn. I dont think you need it.