Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to draw lines with arrowheads in a Folium map?

I am running Folium 0.2.1' with Python 2.7.11 on Jupyter Notebook Server 4.2.1

I am trying to plot lines on a map, which have a arrowhead to convey direction

import folium

#DFW, LGA coordinates
coordinates=[(32.900908, -97.040335),(40.768571, -73.861603)]

m = folium.Map(location=[32.900908, -97.040335], zoom_start=4)

#line going from dfw to lga
aline=folium.PolyLine(locations=coordinates,weight=2,color = 'blue')
m.add_children(aline)

enter image description here Is there a way to add an arrowhead to the line?

like image 362
akrishnamo Avatar asked Aug 23 '16 05:08

akrishnamo


2 Answers

You could use a regular polygon marker to draw a triangle at the end point...

folium.RegularPolygonMarker(location=(32.900908, -97.040335), fill_color='blue', number_of_sides=3, radius=10, rotation=???).add_to(m)

You'll have to use some trigonometry to calculate the angle of rotation for the triangle to point in the correct direction. The initial point of any such marker points due east.

like image 100
user3456239 Avatar answered Oct 24 '22 08:10

user3456239


I may be a little late to the party, but I have another suggestions for other people bothered by this problem. I would suggest to use the pyproj package's Geod class, which can do geodetic and great circle calculations. We can use it to get forward and backward azimuth of a piece of a LineString. Then for each piece we add a small polygon marker(or something similar) on one end.

from pyproj import Geod
# loop your lines
for line in lines.itertuples():
    # format coordinates and draw line
    loc = [[j for j in reversed(i)] for i in line.geometry.coords]
    folium.PolyLine(loc, color="red").add_to(m)
    # get pieces of the line
    pairs = [(loc[idx], loc[idx-1]) for idx, val in enumerate(loc) if idx != 0]
    # get rotations from forward azimuth of the line pieces and add an offset of 90°
    geodesic = Geod(ellps='WGS84')
    rotations = [geodesic.inv(pair[0][1], pair[0][0], pair[1][1], pair[1][0])[0]+90 for pair in pairs]
    # create your arrow
    for pair, rot in zip(pairs, rotations):
        folium.RegularPolygonMarker(location=pair[0], color='red', fill=True, fill_color='red', fill_opacity=1,
                                    number_of_sides=3, rotation=rot).add_to(m)

I hope someone will find this snippet helpful. Have a great day! =)

like image 3
Tobias Triesch Avatar answered Oct 24 '22 10:10

Tobias Triesch