You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flask中如何获取Folium标记ID并调用Python函数实现弹窗绘图

问题分析与解决方案

核心问题梳理

你的代码存在以下几个关键问题导致功能失效:

  • Marker的ID未绑定到可读取的位置:Folium的Marker参数id不会自动映射到DOM元素的可读取属性,JS无法提取目标ID
  • JS执行时机错误:DOM未完全渲染(包括Marker加载完成)就执行元素查询,找不到标记节点
  • Python语法错误:使用了JS风格的//注释,Python需用#;模板字符串的引号转义冗余
  • 仅处理单个站点:if ia==0导致只有第一个气象站被添加标记

修正后的完整代码

import folium, branca, requests
from branca.element import Element
from flask import Flask, request, jsonify
from folium.plugins import LocateControl

app = Flask(__name__)

@app.route('/')
def map():    
    start_coords = (38.7088, -9.1576)
    folium_map = folium.Map(
        location=start_coords, 
        zoom_start=8,
        max_bounds=True,
        height="100%",
        zoom_control=False
    )

    fig = branca.element.Figure(height="100%", width='100%')
    fig.add_child(folium_map)

    # 添加地图插件
    folium.plugins.Fullscreen(position='bottomleft').add_to(folium_map)
    folium.LatLngPopup2().add_to(folium_map)
    LocateControl(strings={'drawMarker':'False'}).add_to(folium_map)

    ft_grp = folium.map.FeatureGroup(name='Meteo Stations - last 24H', show=False)
    rsp = requests.get('https://api.ipma.pt/open-data/observation/meteorology/stations/stations.json')
    codes = rsp.json()
    
    # 调整JS模板:使用Leaflet原生事件监听,避免DOM查询漏洞
    template = '''
        document.addEventListener('DOMContentLoaded', function() {
            // 获取Leaflet地图实例
            var map = window.L.mapInstances[0];
            // 监听地图上的标记点击事件
            map.on('click', function(e) {
                if (e.target instanceof L.Marker) {
                    var markerId = e.target.options.markerId;
                    if (markerId) {
                        handleMarkerClick(markerId);
                    }
                }
            });
        });

        function handleMarkerClick(markerId) {
            $.ajax({
                type: "POST",
                url: "/plot_station",
                data: JSON.stringify({ id: markerId }),
                contentType: "application/json; charset=utf-8",
                dataType: "json",
                success: function(response) {
                    console.log('请求成功:', response.message);
                    // 后续可在此处添加弹窗展示图表的逻辑
                },
                error: function(xhr, status, error) {
                    console.error('请求失败:', error);
                }
            });
        }
    '''
    
    # 循环处理所有气象站标记
    for cd in codes:
        station_id = cd['properties']['idEstacao']
        coord = cd['geometry']['coordinates']
        
        # 创建Marker时将ID存入Leaflet配置,同时设置popup
        marker = folium.Marker(
            location=[coord[1], coord[0]],
            popup=folium.Popup(f"站点ID: {station_id}", max_width=150),
            options={'markerId': station_id}
        ).add_to(ft_grp)
        
    # 注入自定义JS到地图页面
    e = Element(template)
    html = folium_map.get_root()
    html.script._children[e.get_name()] = e  
     
    folium_map.add_child(ft_grp)
    folium.LayerControl().add_to(folium_map)

    return fig._repr_html_()


@app.route('/plot_station', methods=['POST'])
def plot_station():
    data = request.get_json()
    marker_id = data.get('id')
    print(f"收到站点ID: {marker_id}")

    if marker_id:
        # 生成文件示例(后续可替换为图表生成逻辑)
        filename = f"{marker_id}.txt"
        with open(filename, 'w') as fid:
            fid.write(f"站点 {marker_id} 被点击!")

    return jsonify({"message": f"已处理站点 {marker_id}"})

if __name__ == '__main__':
    app.run(debug=True)

关键修改说明

  1. Marker ID存储优化:
    通过options={'markerId': station_id}将站点ID直接存入Leaflet Marker的配置对象中,无需依赖DOM属性,避免DOM结构变化导致的读取失败。

  2. JS事件监听优化:

    • 使用DOMContentLoaded确保地图完全加载后再绑定事件
    • 直接监听Leaflet地图的click事件,通过判断点击目标类型获取Marker,避免DOM查询的兼容性问题
  3. 修复语法与逻辑问题:

    • 替换Python中的//注释为合法的#注释
    • 移除if ia==0判断,循环所有气象站生成标记
    • 简化JS模板的引号使用,删除不必要的转义字符
  4. 后续扩展建议:

    • 若要在弹窗展示图表,可在handleMarkerClick的success回调中,将后端生成的图表(如Matplotlib转成的base64图片)插入到自定义弹窗中
    • 可结合Bootstrap模态框实现更美观、功能更完善的弹窗效果

内容的提问来源于stack exchange,提问作者Elcook

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 06:24:49