Search code examples
pythonpandasroutesgeospatialfolium

How to plot routes between pairs of starting and ending geospatial points using Folium?


I am having a pandas DataFrames with latitude longitude of start and end of a route, so these are my columns ('origin_lat, 'origin_lon',destination_lat','destination_lon').

I am able to plot the locations on Folium map but I am looking for a way to plot the routes between each location.

Here is the code I am using:

m = folium.Map([16.7, 81.095], zoom_start=11)
m

# mark each origin as a point

for index, row in df.iterrows():
    folium.CircleMarker([row['origin_lat'], row['origin_lng']],
                        radius=15,
                        fill_color="#3db7e4", # divvy color
                       ).add_to(m)

for index, row in df.iterrows():
    folium.CircleMarker([row['destination_lat'], row['destination_lng']],
                        radius=15,
                        fill_color="red", # divvy color
                       ).add_to(m)

#add routes

folium.PolyLine([list(zip(df.origin_lat, df.origin_lng)),list(zip(df.destination_lat, df.destination_lng))], line_opacity = 0.5, color='white',line_weight=5).add_to(m)


The code I am using is connecting all the origin locations together and all the destination locations together but I want to plot routes between origin and destination locations instead. Any way I can fix it?


Solution

  • If I understood your question correctly, I believe I have your solution

    Some imports

    import pandas as pd
    import numpy as np
    import folium
    

    Some sample data

    centroid_lat = 16.7
    centroid_lon = 81.095
    
    x = .1
    
    n = 10
    
    o_lats = np.random.uniform(low=centroid_lat - x, high=centroid_lat + x, size=(n,))
    o_lons = np.random.uniform(low=centroid_lon - x, high=centroid_lon + x, size=(n,))
    d_lats = np.random.uniform(low=centroid_lat - x, high=centroid_lat + x, size=(n,))
    d_lons = np.random.uniform(low=centroid_lon - x, high=centroid_lon + x, size=(n,))
    
    df = pd.DataFrame({'origin_lng' : o_lons, 'origin_lat' : o_lats,
                       'destination_lng': d_lons, 'destination_lat': d_lats})
    
    print(df.head())
       destination_lat  destination_lng  origin_lat  origin_lng
    0        16.797057        81.074000   16.660164   81.080038
    1        16.615371        81.001004   16.772645   80.997770
    2        16.784289        81.117082   16.670008   81.032719
    3        16.686201        81.184775   16.787999   81.189585
    4        16.757704        81.127280   16.720080   81.178466
    

    Then the map. No need for two for loops and I'm creating a line each iteration

    m = folium.Map([centroid_lat, centroid_lon], zoom_start=11)
    
    for _, row in df.iterrows():
        folium.CircleMarker([row['origin_lat'], row['origin_lng']],
                            radius=15,
                            fill_color="#3db7e4", # divvy color
                           ).add_to(m)
    
        folium.CircleMarker([row['destination_lat'], row['destination_lng']],
                            radius=15,
                            fill_color="red", # divvy color
                           ).add_to(m)
    
        folium.PolyLine([[row['origin_lat'], row['origin_lng']], 
                         [row['destination_lat'], row['destination_lng']]]).add_to(m)
    m
    

    enter image description here