如何获取folium地图点击或绘制图形的经纬度并解决draw插件导出问题
问题根因
folium为纯前端渲染类库,所有交互逻辑均在浏览器端执行,受浏览器沙箱安全限制,Draw插件的导出功能无法直接写入你指定的本地绝对路径:
- 你配置的
filename参数仅代表下载文件的命名,点击导出按钮后文件会默认保存到浏览器的默认下载目录,不会生成在你填写的桌面路径下 - 点击绘制图形弹出JS Alert是插件的默认提示行为,原生配置下该数据不会直接回传给Python运行环境
解决方案
方案1:前端直接查看/获取坐标(无需回传Python)
通过注入自定义JS覆盖默认事件,实现点击地图、绘制图形时直接弹窗展示坐标,同时支持控制台打印坐标数据,示例代码如下:
import folium from folium.plugins import Draw # 初始化地图 m = folium.Map(location=[30, 120], zoom_start=10) # 配置Draw插件,可自行调整支持绘制的图形类型 draw = Draw( export=True, filename="draw_data.geojson", position='topright', draw_options={'polyline': True, 'marker': True, 'polygon': False, 'circle': False, 'rectangle': False}, edit_options={'remove': True} ) draw.add_to(m) # 注入自定义JS监听交互事件 folium.Element(""" <script> document.addEventListener('DOMContentLoaded', function() { // 监听绘制完成事件 window.map.on('draw:created', function(e) { const layer = e.layer; const drawType = e.layerType; // 标记点类型 if (drawType === 'marker') { const latlng = layer.getLatLng(); const coordText = `经纬度:${latlng.lat.toFixed(6)}, ${latlng.lng.toFixed(6)}`; layer.bindPopup(coordText).openPopup(); console.log('绘制标记点坐标:', latlng); } // 折线类型 else if (drawType === 'polyline') { const coordList = layer.getLatLngs(); const coordText = coordList.map(p => `${p.lat.toFixed(6)}, ${p.lng.toFixed(6)}`).join('<br>'); layer.bindPopup(`折线节点坐标:<br>${coordText}`).openPopup(); console.log('绘制折线坐标集合:', coordList); } // 打印完整GeoJSON数据 console.log('图形GeoJSON:', layer.toGeoJSON()); }); // 监听地图点击事件 window.map.on('click', function(e) { L.popup() .setLatLng(e.latlng) .setContent(`点击位置经纬度:<br>${e.latlng.lat.toFixed(6)}, ${e.latlng.lng.toFixed(6)}`) .openOn(window.map); console.log('地图点击坐标:', e.latlng); }); }); </script> """).add_to(m.get_root()) # 保存地图文件,打开后即可使用 m.save('map.html')
运行后打开生成的map.html即可实现需求,点击Draw插件的导出按钮,GeoJSON文件会自动下载到浏览器默认目录。
方案2:坐标回传Python后端处理
如果需要将坐标直接传入Python环境做后续处理,可搭配轻量web框架接收前端上报的坐标数据,以Flask为例示例代码如下:
from flask import Flask, request, jsonify import folium from folium.plugins import Draw app = Flask(__name__) # 地图页面路由 @app.route('/') def map_page(): m = folium.Map(location=[30, 120], zoom_start=10) Draw(export=False).add_to(m) # 注入JS上报绘制数据到后端接口 folium.Element(""" <script> document.addEventListener('DOMContentLoaded', function() { window.map.on('draw:created', function(e) { const geojson = e.layer.toGeoJSON(); // 上报数据到后端 fetch('/save_coords', { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify(geojson) }).then(res => res.json()).then(data => console.log('上报成功', data)); }); }); </script> """).add_to(m.get_root()) return m._repr_html_() # 接收坐标的接口路由 @app.route('/save_coords', methods=['POST']) def save_coords(): geojson_data = request.get_json() coords = geojson_data['geometry']['coordinates'] # 可自行扩展逻辑:将坐标写入本地文件/数据库等 print('接收到绘制坐标:', coords) return jsonify(status='success', coords=coords) if __name__ == '__main__': app.run(debug=True)
运行后访问http://127.0.0.1:5000即可使用,绘制的图形坐标会自动上报到Python后端,控制台会实时打印收到的坐标数据。
内容的提问来源于stack exchange,提问作者selection project
相关产品推荐
相关产品推荐

