是否可以在 Folium 地图中绘制带箭头的线条?
Is it possible to draw lines with arrowheads in a Folium map?
我是 运行 Folium 0.2.1',在 Jupyter Notebook Server 4.2.1 上 Python 2.7.11
我正在尝试在地图上绘制线条,这些线条有一个指示方向的箭头
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)
有没有办法在直线上添加箭头?
您可以使用正多边形标记在终点处画一个三角形...
folium.RegularPolygonMarker(location=(32.900908, -97.040335), fill_color='blue', number_of_sides=3, radius=10, rotation=???).add_to(m)
您必须使用一些三角函数来计算三角形的旋转角度才能指向正确的方向。任何此类标记的初始点指向正东。
我可能来晚了一点,但我对其他被这个问题困扰的人有另一个建议。我建议使用 pyproj 包的 Geod class,它可以进行大地测量和大圆计算。我们可以用它来获取一段 LineString 的前后方位角。然后对于每一块,我们在一端添加一个小的多边形标记(或类似的东西)。
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)
我希望有人会觉得这段代码有用。
祝你有美好的一天! =)
我找到了解决这个问题的方法:
我用三角函数计算自己的箭头点,然后使用这些点调用折线函数。
def arrow_points_calculate(self, ini_lat, ini_long, heading):
lenght_scale = 0.00012
sides_scale = 0.000025
sides_angle = 25
latA= ini_lat
longA = ini_long
latB = lenght_scale * math.cos(math.radians(heading)) + latA
longB = lenght_scale * math.sin(math.radians(heading)) + longA
latC = sides_scale * math.cos(math.radians(heading + 180 - sides_angle)) + latB
longC = sides_scale * math.sin(math.radians(heading + 180 - sides_angle)) + longB
latD = sides_scale * math.cos(math.radians(heading + 180 + sides_angle)) + latB
longD = sides_scale * math.sin(math.radians(heading + 180 + sides_angle)) + longB
pointA = (latA, longA)
pointB = (latB, longB)
pointC = (latC, longC)
pointD = (latD, longD)
point = [pointA, pointB, pointC, pointD, pointB]
return point
folium.PolyLine(locations=points, color="purple").add_to(
position_plot)
Lenght_scale 和 Side_scale 变量必须根据您想要的箭头大小进行修改。
如果你有箭头的开始和结束坐标,只需使用最终坐标作为 B 点,并计算相对于两点之间长度的边比例(我认为点之间长度的 20% 是正确的比例)。
结果示例:
Position plot + heading arrows
希望对你有帮助
我是 运行 Folium 0.2.1',在 Jupyter Notebook Server 4.2.1 上 Python 2.7.11
我正在尝试在地图上绘制线条,这些线条有一个指示方向的箭头
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)
您可以使用正多边形标记在终点处画一个三角形...
folium.RegularPolygonMarker(location=(32.900908, -97.040335), fill_color='blue', number_of_sides=3, radius=10, rotation=???).add_to(m)
您必须使用一些三角函数来计算三角形的旋转角度才能指向正确的方向。任何此类标记的初始点指向正东。
我可能来晚了一点,但我对其他被这个问题困扰的人有另一个建议。我建议使用 pyproj 包的 Geod class,它可以进行大地测量和大圆计算。我们可以用它来获取一段 LineString 的前后方位角。然后对于每一块,我们在一端添加一个小的多边形标记(或类似的东西)。
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)
我希望有人会觉得这段代码有用。 祝你有美好的一天! =)
我找到了解决这个问题的方法: 我用三角函数计算自己的箭头点,然后使用这些点调用折线函数。
def arrow_points_calculate(self, ini_lat, ini_long, heading):
lenght_scale = 0.00012
sides_scale = 0.000025
sides_angle = 25
latA= ini_lat
longA = ini_long
latB = lenght_scale * math.cos(math.radians(heading)) + latA
longB = lenght_scale * math.sin(math.radians(heading)) + longA
latC = sides_scale * math.cos(math.radians(heading + 180 - sides_angle)) + latB
longC = sides_scale * math.sin(math.radians(heading + 180 - sides_angle)) + longB
latD = sides_scale * math.cos(math.radians(heading + 180 + sides_angle)) + latB
longD = sides_scale * math.sin(math.radians(heading + 180 + sides_angle)) + longB
pointA = (latA, longA)
pointB = (latB, longB)
pointC = (latC, longC)
pointD = (latD, longD)
point = [pointA, pointB, pointC, pointD, pointB]
return point
folium.PolyLine(locations=points, color="purple").add_to(
position_plot)
Lenght_scale 和 Side_scale 变量必须根据您想要的箭头大小进行修改。 如果你有箭头的开始和结束坐标,只需使用最终坐标作为 B 点,并计算相对于两点之间长度的边比例(我认为点之间长度的 20% 是正确的比例)。
结果示例: Position plot + heading arrows
希望对你有帮助