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

如何在Shiny for Python中保存folium地图点击坐标至响应式变量?

如何在Shiny for Python中保存folium地图点击坐标至响应式变量?

我明白你的困扰——folium本身是基于Leaflet的纯HTML/JS地图库,不像ipyleaflet那样原生支持ipywidgets的双向绑定,所以需要手动添加一点JavaScript代码来把点击事件传递给Shiny。下面我会给你修改后的完整代码,一步步解决这个问题:

修改后的完整代码

from shiny import App, render, ui, reactive
import folium

def server(input, output, session):
    # Initialize reactive value for coordinates
    coords = reactive.Value({'lat': None, 'lng': None})
    
    @output
    @render.ui
    def map():
        m = folium.Map(location=[-1.9403, 29.8739], zoom_start=8) 
        
        # 添加自定义JavaScript捕获地图点击事件
        click_js = """
        <script>
        document.addEventListener('DOMContentLoaded', function() {
            // 找到folium创建的Leaflet地图实例(window中以map_开头的变量)
            var mapKey = Object.keys(window).find(key => key.startsWith('map_'));
            var map = window[mapKey];
            
            // 监听地图点击事件
            map.on('click', function(e) {
                var lat = e.latlng.lat;
                var lng = e.latlng.lng;
                // 将坐标发送给Shiny的输入对象
                Shiny.setInputValue('folium_map_click', {lat: lat, lng: lng}, {priority: 'event'});
            });
        });
        </script>
        """
        # 将JS代码添加到地图HTML中
        map_html = m._repr_html_() + click_js
        return ui.HTML(map_html)
    
    # 监听地图点击事件,更新响应式变量
    @reactive.Effect
    @reactive.event(input.folium_map_click)
    def update_coords():
        clicked_coords = input.folium_map_click()
        coords.set(clicked_coords)
        print(f"点击的坐标: {clicked_coords}")  # 控制台打印,方便调试
    
    # 输出当前点击的坐标,用于验证
    @output
    @render.text
    def clicked_coords_display():
        current_coords = coords.get()
        if current_coords['lat'] is not None:
            return f"当前点击的坐标: 纬度 {current_coords['lat']:.4f}, 经度 {current_coords['lng']:.4f}"
        else:
            return "点击地图任意位置获取坐标"

app_ui = ui.page_fluid(
    ui.h1("Folium Map that returns Coordinates of clicked spot"),
    ui.div(
        ui.output_ui("map"),
        style="height: 600px; width: 100%;"
    ),
    ui.br(),
    ui.h3(ui.output_text("clicked_coords_display"))
)

app = App(app_ui, server)

关键改动说明

  • 添加JavaScript事件监听:folium生成的地图会在浏览器的window对象中创建一个以map_开头的变量(对应Leaflet地图实例),我们通过查找这个变量来绑定点击事件。当用户点击地图时,会获取点击位置的经纬度,再通过Shiny.setInputValue方法将数据发送到Shiny的输入系统中,命名为folium_map_click。
  • 响应式变量更新:在server中,我们用reactive.Effect和reactive.event监听input.folium_map_click,一旦有点击事件触发,就把坐标更新到响应式变量coords里。
  • 可视化验证:添加了一个文本输出区域,实时显示当前点击的坐标,方便你快速验证功能是否正常工作。

这样修改后,你就可以在coords响应式变量中获取到用户点击的坐标,后续可以基于这些坐标进行统计计算或生成plotly图表,完全不会和plotly的依赖冲突。

备注:内容来源于stack exchange,提问作者Faustin Gashakamba

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 17:39:37