0

A device is traveling from source to destination and has support for GPS,

we are able to locate the nearest signal using (current loc - static fixed traffic signals array) here D1 is nearest, but we want to select D2 as it is facing our direction,

my approach is to find the perpendicular to the current location if a signal is perpendicular, then select that one, but I can't figure out how to, thought of using another value attached to each signal called angle, which is the angle from the north ie 180 deg in our case and somehow calculate the angle of the andriod from the north and compare it. if it is opposite (180 - south , 0 - north) select that one.

using gmaps API to find the direction from source to destination and converting the string(Encoded Polyline) to lat log using python decode polyline function.)

How can I implement the above solution, is it functional, or do I have any other options

I was able to only find out this code, but it is for the angle between a straight line to the x-axis

I think math.atan2(x, y) also provides an angle, right?

import math 

def calculate_initial_compass_bearing(pointA, pointB):
    """
    Calculates the bearing between two points.
    The formulae used is the following:
        θ = atan2(sin(Δlong).cos(lat2),
                  cos(lat1).sin(lat2) − sin(lat1).cos(lat2).cos(Δlong))
    :Parameters:
      - `pointA: The tuple representing the latitude/longitude for the
        first point. Latitude and longitude must be in decimal degrees
      - `pointB: The tuple representing the latitude/longitude for the
        second point. Latitude and longitude must be in decimal degrees
    :Returns:
      The bearing in degrees
    :Returns Type:
      float
    """
    if (type(pointA) != tuple) or (type(pointB) != tuple):
        raise TypeError("Only tuples are supported as arguments")

    lat1 = math.radians(pointA[0])
    lat2 = math.radians(pointB[0])

    diffLong = math.radians(pointB[1] - pointA[1])

    x = math.sin(diffLong) * math.cos(lat2)
    y = math.cos(lat1) * math.sin(lat2) - (math.sin(lat1)
            * math.cos(lat2) * math.cos(diffLong))

    initial_bearing = math.atan2(x, y)
    #print(initial_bearing)
    # Now we have the initial bearing but math.atan2 return values
    # from -180° to + 180° which is not what we want for a compass bearing
    # The solution is to normalize the initial bearing as shown below
    initial_bearing = math.degrees(initial_bearing)
    compass_bearing = (initial_bearing + 360) % 360

    return compass_bearing
Arshad
  • 35
  • 6

1 Answers1

0

You're assuming the phone is installed straight forward and not at an angle. That isn't a good assumption. My phone is rarely straight forwared, its usually thrown in the center console in whatever way it lands. Or sitting on the passenger seat, same thing. A better idea would be to look at the heading the last time their speed was non-zero- that will show the direction they were going in. Of course if they made a last minute lane change it could be a bit off, but it will be more accurate.

Gabe Sechan
  • 90,003
  • 9
  • 87
  • 127
  • actually we don't use the mobile other than it gps coordinates that it, nothing more than that. – Arshad Jan 01 '23 at 06:10
  • @Arshad The heading is on the GPS response, It's called the bearing. You use location.getBearing(). It returns a number [0,360). And if for some reason that doesn't work, you can calculate it by using 2 consecutive location values and comparing. – Gabe Sechan Jan 01 '23 at 06:13
  • thanks, can you tell me more about the second one using " 2 consecutive location values and comparing.", some explanation, documentation or code would be really helpfully. we have the source and destination they would be using google maps so predefined path. and we are going to know which signals to use based on the route, we are able to select those signals based on the nearest distance from the road that we are going to take – Arshad Jan 01 '23 at 06:19
  • 1
    So let's imagine we have 2 GPS points (x1,y1) and (x2,y2) where x is latitude and y is longitude. The distance between the two can be calculated using the distanceTo function in android (I'm sure there's a python equivalent). Imagine that being the hypotneuse of a right triangle. The distance from (x2, y1) to (x2, y1) would be the length of the adjacent side. From trigonometry, cos(alpha)=adjacent/hypotneuse. so the bearing alpha= acos(adjacent/hypotneuse). – Gabe Sechan Jan 01 '23 at 06:44
  • 1
    To make that calculation a bit less expensive- if longitude is held constant, the distance between two points is the change in latiturde*110567 meters. So for the length of the adjacent side you can just multiply the difference in latitude by that constant. – Gabe Sechan Jan 01 '23 at 06:46
  • thanks a lot can u please have a look if i was able to solve it properly – Arshad Jan 01 '23 at 11:27
  • https://gist.github.com/lARSHADl/11af40a12834d6504fbf56f6bcee31eb – Arshad Jan 01 '23 at 11:47
  • i think there should be a correct in this "The distance from (x2, y1) to (x2, y1) would be the length of the adjacent side." is it (x2,y2) -(x1,y1) – Arshad Jan 01 '23 at 12:06
  • 1
    @Arshad No, (x2,y2)-(x1,y1) is the hypotneuse. Think of a cartesian coordinate system. If you have one point at (0,0) and one at (10,5), you can make a right triangle with the hypotneuse being the vector to the point, the adjacent side being the vector from (0,0) to (10,0) and the opposite side being (10,0) to (10,5). This is the same thing, but with GPS coordinates on a spherical grid. – Gabe Sechan Jan 01 '23 at 15:16