Search code examples
pythonpandasgeopandas

computing haversine over two lists


I'm currently trying to compute route distance of (lat/long) coordinates that I have in Geopandas data frame. I'm pretty new to the package, but basically I have several points that make up a route and all I'm trying to do is find the total real distance of the route. I'm able to do so with two fixed points, to which I owe the help to user @steve clark:

# Start
lon1 = 41.592181
lat1 = -87.638856
# End
lat2 = -86.754688
lon2 = 41.877575

def haversine(lat1, lon1, lat2, lon2):
    """
    Calculate the great circle distance between two points 
    on the earth (specified in decimal degrees)
    """
    # convert decimal degrees to radians 
    lon1, lat1, lon2, lat2 = map(radians, [lon1, lat1, lon2, lat2])

    # haversine formula 
    dlon = lon2 - lon1 
    dlat = lat2 - lat1 
    a = sin(dlat/2)**2 + cos(lat1) * cos(lat2) * sin(dlon/2)**2
    c = 2 * asin(sqrt(a))
    r = 6371 # Radius of earth in kilometers
    print('Distance from beginning to end of route in km: ',round((c * r), 2),'\n')

I get stuck on two things, I'm currently scouring around to see if I can just calculate distance from the Geopandas point() object, but in all honesty the examples I find are either not related to my question, or beyond my scope of understanding (at this time).

I'm able to pull both latitude and longitude columns from my gpd into lists but I get stuck applying it over loop

LatList = geo_data['latitude'].tolist()
LonList = geo_data['longitude'].tolist()

I try and append what I iterate through into a new list and sum the distances, but I end up getting a list with the same value appended 2,850 times. Any help or direction appreciated!

EDIT: As requested, this is the code that fails

distance = []

    for i, j in zip(LatList, LonList):

        dlat = i - i+1
        dlon = j - j+1

        a = sin(dlat/2)**2 + cos(lat1) * cos(lat2) * sin(dlon/2)**2
        c = 2 * asin(sqrt(a))
        r = 6371 # Radius of earth in kilometers

        distance.append(round((c * r), 2))

    print(distance)

Solution

  • You need to adjust the definitions of i, i+1, j and j+1, otherwise the loop will not do what you want it to.

    distance = []
    
    LatLonList = list(zip(LatList, LonList))
    
        # notice that if you do "for n in len(LatLonList)", the loop will fail in the last element
        for n in len(LatLonList) -1:
    
            dlat = LatLonList[n][0] - LatLonList[n+1][0]  # this is for i
            dlon = LatLonList[n][1] - LatLonList[n+1][1]  # this is for j
    
            a = sin(dlat/2)**2 + cos(lat1) * cos(lat2) * sin(dlon/2)**2
            c = 2 * asin(sqrt(a))
            r = 6371 # Radius of earth in kilometers
    
            distance.append(round((c * r), 2))
    
        print(distance)