如何用plotly在卫星视图地图上绘制箭头 [英] How to draw arrows on satellite view map with plotly
问题描述
我正在尝试使用 plotly 在卫星视图地图上可视化风向和强度.在 Python 中工作,但我想这个问题不是特定于平台的.
I'm trying to visualize wind direction and strength on a satellite view map with plotly. Working in Python but, I guess, this question is not platform specific.
以下是过去用Matlab制作的风图截图:
Below is a screenshot of a wind map made in the past with Matlab:
这可以用 plotly 吗?我试图查看注释,但我无法让它们在地图上工作.
Is this possible with plotly? I tried to look into annotations but I couldn't get them to work on a map.
我尝试过类似下面的操作,但是当我添加注释时,地图停止工作:
I tried something like below but when I add the annotation the map stops working:
import plotly.graph_objects as go
fig = go.Figure(go.Scattermapbox(
mode = "lines",
lon = [10, 20],
lat = [10,20],
marker = {'size': 10}))
fig.add_annotation(
x = [10,],
y = [10],
xref = "x", yref = "y",
axref = "x", ayref = "y",
ax = [20],
ay = [20],
text = "",
showarrow = True
)
fig.update_layout(
margin ={'l':0,'t':0,'b':0,'r':0},
mapbox = {
'center': {'lon': 10, 'lat': 10},
'style': "stamen-terrain",
'center': {'lon': 10, 'lat': 10},
'zoom': 3})
fig.show()
推荐答案
无法在散点图框上绘制箭头作为注释并保持箭头的 3D 位置.
It is not possible to plot arrows as annotation on a scattermapbox and maintain the 3D locations of the arrows.
我所做的是为每个箭头生成 2 条轨迹.第一条轨迹由 2 个点组成,开始和结束,而第二条轨迹有 4 个点,[end,tipA,tipB,end) 并填充onself".
What I did was to generate 2 traces for each arrow. The first trace is composed of 2 points, start and end, while the second trace has 4 points, [end, tipA, tipB, end) and filled "onself".
windField.windvectorList.forEach((item) =>{
this.TrackMapPlot_data.push({
type: "scattermapbox",
mode: "lines",
lat: [item.startlat, item.stoplat],
lon: [item.startlon, item.stoplon],
line: { color: "rgb(48,151,255)", width: 3}
});
this.TrackMapPlot_data.push({
type: "scattermapbox",
mode: "lines",
fill:"toself",
fillcolor: "rgb(48,151,255)",
lat: [item.stoplat, item.tipalat, item.tipblat, item.stoplat ],
lon: [item.stoplon, item.tipalon, item.tipblon, item.stoplon],
line: { color: "rgb(48,151,255)", width: 3}
})
});
想出tipA 和tipB 并使箭头尖端也随我定义的箭头长度缩放:
To come up with tipA and tipB and have the arrow tip also scale with the arrow length I define:
- 箭头开口:alpha
- 箭头长度占总箭头长度的百分比:d
- 使用 python 后端中的 geopy 库生成 3 个附加点.箭头末端和 2 个箭头提示.
def AddArrowTipsToWindVectors(wind_table: pd.DataFrame(), scale: float) -> pd.DataFrame():
#wind_table = wind_table.loc[:100, :]
# Make wind vectors
arrow_angle = 20
arrow_length = 0.2
wind_vectors = list()
wind_table['WindArrowTipALat'] = 0
wind_table['WindArrowTipALon'] = 0
wind_table['WindArrowTipBLat'] = 0
wind_table['WindArrowTipBLon'] = 0
for index, wind_row in wind_table.iterrows():
arrow_delta = math.asin(arrow_length*math.sin(math.radians(arrow_angle/2))/(1-arrow_length))
arrow_dist = wind_row['WindSpeed']*scale*(1-arrow_length)/math.cos(arrow_delta)
arrow_tip_A = GetTerminalLocFromDistAndHeading(wind_row['StationLat'], wind_row['StationLon'], arrow_dist, wind_row['WindDirection'] + math.degrees(arrow_delta))
wind_table.loc[index, 'WindArrowTipALat'] = arrow_tip_A[0]
wind_table.loc[index, 'WindArrowTipALon'] = arrow_tip_A[1]
arrow_tip_B = GetTerminalLocFromDistAndHeading(wind_row['StationLat'], wind_row['StationLon'], arrow_dist, wind_row['WindDirection'] - math.degrees(arrow_delta))
wind_table.loc[index, 'WindArrowTipBLat'] = arrow_tip_B[0]
wind_table.loc[index, 'WindArrowTipBLon'] = arrow_tip_B[1]
这不是一个很好的解决方案,但它有效.但是,plotly 和 mapbox 存在一个大问题.不幸的是,如以下 github 链接中所指出的那样,当添加多个跟踪时,一切都会变得非常缓慢:https://github.com/plotly/plotly.js/issues/3227https://github.com/plotly/plotly.js/issues/1535
This is not a great solution but it works. HOWEVER, there is a big issue with plotly and mapbox. Unfortunately, when adding several traces everything becomes extremely slow as pointed out in the following github links: https://github.com/plotly/plotly.js/issues/3227 https://github.com/plotly/plotly.js/issues/1535
问题不在于单个轨迹中的点数,而在于轨迹的数量.这使得我的应用程序无法使用.
The problem is not the number of points in a single trace but the number of traces. This makes plotly unusable for my application.
年度股东大会解决方案
Angular Google Maps 似乎运行良好.https://angular-maps.com/guides/getting-started/这是一个展示我如何使用它的片段:
Angular Google Maps seems to work very well. https://angular-maps.com/guides/getting-started/ Here is a snippet that shows how I use it:
<agm-map
[clickableIcons]="false"
[disableDefaultUI]="true"
[latitude]="trackDetails.mapboxlat"
[longitude]="trackDetails.mapboxlon"
[mapTypeId]="'satellite'"
[zoom]="trackDetails.mapboxzoomsmall"
(mapClick)="onChoseLocation($event)"
>
<agm-polyline *ngFor="let windvector of windField.windvectorList"
[visible]="true" [strokeWeight]="2" [strokeColor]="'rgb(43,42,255)'">
<agm-polyline-point
[latitude]="windvector.startlat"
[longitude]="windvector.startlon">
</agm-polyline-point>
<agm-polyline-point
[latitude]="windvector.stoplat"
[longitude]="windvector.stoplon">
</agm-polyline-point>
<agm-icon-sequence
[fixedRotation]="false"
[scale]="1.5"
[path]="'FORWARD_OPEN_ARROW'"
[fillColor]="'rgb(43,42,255)'">
</agm-icon-sequence>
</agm-polyline>
</agm-map>
这篇关于如何用plotly在卫星视图地图上绘制箭头的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!