如何在Folium+ipywidgets组件中获取绘制矩形的经纬度坐标
解决folium绘制矩形后获取边界坐标的问题
要获取用户绘制的矩形的北、南、东、西边界坐标,需要通过JavaScript监听Leaflet的绘制事件将前端坐标数据传递到Python变量,再在按钮点击事件中解析显示。以下是修改后的完整代码:
import folium, folium.plugins import ipywidgets as ipyw # must be below v7.7 from IPython.display import display, HTML, clear_output import json %matplotlib inline # 创建地图并仅启用矩形绘制工具 f = folium.Figure(width=750,height=350) m = folium.Map(location=[39, -95],zoom_start=3).add_to(f) draw = folium.plugins.Draw(draw_options={'polyline':False,'polygon':False,'rectangle':True, 'circle':False,'marker':False,'circlemarker':False}).add_to(m) # 添加鼠标位置经纬度显示插件 formatter = "function(num) {return L.Util.formatNum(num, 6) + ' º ';};" folium.plugins.MousePosition(position='topright',separator=' | ',empty_string='NaN', lng_first=False,num_digits=20,prefix='Coordinates:', lat_formatter=formatter,lng_formatter=formatter ).add_to(m) # 创建隐藏的widget用于存储矩形边界数据 bounds_store = ipyw.Text(value='', disabled=True, layout=ipyw.Layout(display='none')) # 添加JavaScript监听绘制完成事件,将坐标数据传递到Python js_code = """ map.on('draw:created', function(e) { var type = e.layerType; var layer = e.layer; if (type === 'rectangle') { var bounds = layer.getBounds(); var boundsData = JSON.stringify({ north: bounds.getNorth(), south: bounds.getSouth(), east: bounds.getEast(), west: bounds.getWest() }); // 将数据发送到Python的bounds_store变量 IPython.notebook.kernel.execute(`bounds_store.value = '${boundsData}'`); } }); """ m.add_child(folium.Element(f'<script>{js_code}</script>')) # 显示地图组件 map_output = ipyw.Output(layout=ipyw.Layout(width='100%')) with map_output: display(m) # 创建提交按钮及点击事件逻辑 button_submit = ipyw.Button(description='Submit',tooltip='Send',style={'description_width':'initial'}) button_output = ipyw.Output() def on_button_clicked(event): with button_output: clear_output() if bounds_store.value: bounds = json.loads(bounds_store.value) print(f"北纬度 (North): {bounds['north']:.6f} º") print(f"南纬度 (South): {bounds['south']:.6f} º") print(f"东经度 (East): {bounds['east']:.6f} º") print(f"西经度 (West): {bounds['west']:.6f} º") else: print("请先在地图上绘制一个矩形!") # 组装并显示所有组件 button_submit.on_click(on_button_clicked) page1 = ipyw.VBox([ ipyw.HBox([map_output],layout=ipyw.Layout(justify_content='center')), ipyw.HBox([ipyw.VBox([button_submit,button_output])],layout=ipyw.Layout(justify_content='center')), bounds_store # 必须加入页面才能接收前端数据 ],layout=ipyw.Layout(display='flex',flex_flow='column',align_content='space-around',align_items='center')) display(page1)
关键逻辑说明:
- 前端数据捕获:通过Leaflet的
draw:created事件监听矩形绘制动作,调用layer.getBounds()直接获取矩形的四个边界坐标 - 数据跨端传递:用
IPython.notebook.kernel.execute将JSON格式的坐标数据写入Python侧的bounds_store变量 - 后端解析显示:按钮点击时读取
bounds_store中的数据,解析后格式化输出四个方向的经纬度
内容的提问来源于stack exchange,提问作者Alex Thompson
相关产品推荐
相关产品推荐

