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

如何在Dash-leaflet的dl.GeoJSON多边形中添加点击弹窗?

为dash-leaflet的dl.GeoJSON多边形添加HTML弹窗的解决方案

方法1:通过Leaflet原生选项绑定弹窗

你可以直接在dl.GeoJSON的options参数里传入onEachFeature函数,给每个多边形绑定自定义HTML弹窗,逻辑和Leaflet原生用法一致:

import dash_leaflet as dl
from dash import Dash, html

# 示例测试GeoJSON数据
test_geojson = {
    "type": "FeatureCollection",
    "features": [
        {
            "type": "Feature",
            "properties": {"name": "测试多边形1", "area": "100㎡"},
            "geometry": {
                "type": "Polygon",
                "coordinates": [[
                    [116.397, 39.908],
                    [116.407, 39.908],
                    [116.407, 39.918],
                    [116.397, 39.918],
                    [116.397, 39.908]
                ]]
            }
        }
    ]
}

def on_each_feature(feature, layer):
    # 构建自定义HTML格式弹窗内容
    popup_html = f"""
    <div style="padding: 10px;">
        <h4>{feature['properties']['name']}</h4>
        <p>面积:{feature['properties']['area']}</p>
    </div>
    """
    layer.bindPopup(popup_html)

app = Dash(__name__)
app.layout = html.Div([
    dl.Map([
        dl.TileLayer(),
        dl.GeoJSON(data=test_geojson, options={"onEachFeature": on_each_feature})
    ], style={"height": "80vh"})
])

if __name__ == "__main__":
    app.run_server(debug=True)

这种方式无需Dash回调,直接利用Leaflet原生能力,适合弹窗内容仅依赖GeoJSON自身属性的场景,性能表现更优。

方法2:通过Dash回调实现动态弹窗

如果需要弹窗内容联动其他组件状态,可监听dl.GeoJSON的click_feature事件,动态更新弹窗内容:

import dash_leaflet as dl
from dash import Dash, html, Input, Output

test_geojson = {
    # 同上述示例GeoJSON数据
}

app = Dash(__name__)
app.layout = html.Div([
    dl.Map([
        dl.TileLayer(),
        dl.GeoJSON(id="geojson-layer", data=test_geojson),
        dl.Popup(id="dynamic-popup")  # 初始化空弹窗,通过回调更新
    ], style={"height": "80vh"})
])

@app.callback(
    Output("dynamic-popup", "children"),
    Output("dynamic-popup", "position"),
    Input("geojson-layer", "click_feature"),
    prevent_initial_call=True
)
def update_popup(feature):
    if not feature:
        return None, None
    # 构建带交互元素的HTML弹窗
    popup_content = html.Div([
        html.H4(feature["properties"]["name"]),
        html.P(f"面积:{feature['properties']['area']}"),
        html.Button("查看详情", id="detail-btn")
    ], style={"padding": "12px"})
    # 计算多边形中心点作为弹窗位置
    coords = feature["geometry"]["coordinates"][0]
    center_lat = sum(p[1] for p in coords)/len(coords)
    center_lng = sum(p[0] for p in coords)/len(coords)
    return popup_content, [center_lat, center_lng]

if __name__ == "__main__":
    app.run_server(debug=True)

这种方式支持弹窗内容与其他Dash组件联动,适配更复杂的业务逻辑需求。

注意事项

  • 弹窗HTML内容可自由定制,包括样式、按钮、图片等,写法与普通Dash组件一致
  • 若GeoJSON数据量较大,优先选择方法1,避免回调通信带来的性能损耗
  • 弹窗位置可选择多边形中心点,或通过click_lat_lng属性获取点击坐标

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 20:10:17