Search code examples
pythonpython-2.7gpsgeolocationcoordinate-systems

Finding a gps location at a certain time given two points?


If I have two known locations and a known speed, how can I calculate the current position at distance d (in km)?

For example, given:

Two gps locations in ES4236:

37.783333, -122.416667   # San Francisco
32.715, -117.1625        # San Diego

Traveling at 1km/min in a straight line (ignoring altitude)

How can I find the gps coordinate at a certain distance? A similar SO question uses VincentyDistance in geopy to calculate the next point based on bearing and distance.

I guess, more specifically:

  • How can I calculate the bearing between two gps points using geopy?

  • Using VincentyDistance to get the next gps point by bearing and distance, how do I know if I have arrived at my destination, or if I should keep going? It doesn't need to be exactly on the destination to be considered being arrived. Maybe any point with a radius of .5 km of the destination is considered 'arrived'.

ie,

import geopy

POS1 = (37.783333, -122.416667)     # origin
POS2 = (32.715, -117.1625)          # dest

def get_current_position(d):
    # use geopy to calculate bearing between POS1 and POS2
    # then use VincentyDistance to get next coord

    return gps_coord_at_distance_d

# If current position is within .5 km of destination, consider it 'arrived'
def has_arrived(curr_pos):
    return True/False

d = 50     # 50 km
print get_current_position(d)
print has_arrived(get_current_position(d))

Solution

  • Ok, figured I'd come back to this question and give it my best shot given that it hasn't seen any other solutions. Unfortunately I can't test code right now, but I believe there is a solution to your problem using both geopy and geographiclib. Here goes.

    From the terminal (possibly with sudo)

    pip install geographiclib
    pip install geopy
    

    Now with Python

    Get Current Position

    import geographiclib
    from geopy import geopy.distance
    
    # Get the first azimuth, which should be the bearing
    bearing = geographiclib.WGS84.Inverse(37.783333, -122.416667, 32.715, -117.1625)[2]
    
    
    # Now we use geopy to calculate the distance over time
    dist = geopy.distance.VincentyDistance(kilometers = 1)
    san_fran = geopy.Point(37.783333, -122.416667)
    
    print dist.destination(point=san_fran, bearing=bearing)
    

    Has Arrived

    def has_arrived(d):
        return geopy.distance.vincenty(curr_pos, (32.715, -117.1625)).kilometers < .5
    

    Like I said, I unfortunately can't test this, but I believe this is correct. It's possible there will be some unit differences with the bearing calculation: it calculates bearing off of North as seen here. Sorry if this isn't exactly correct, but like I said since this hasn't received a response since I figured I may as well throw in what I know.