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

Folium GeoJson循环内style_function仅生效最后一次迭代值问题

问题原因

这是Python闭包的延迟绑定特性导致的:循环内定义的style_function lambda不会在定义瞬间捕获当前迭代的list_red_places值,而是在GeoJson实际渲染样式时才去查找该变量。此时整个for循环已经执行完毕,list_red_places指向最后一次迭代(ID为3的波尔图用户)的高亮列表,因此所有图层都复用了最后一套着色规则。

修复方法

通过给lambda增加默认参数的方式,在函数定义时就绑定当前迭代的list_red_places值——Python函数的默认参数会在定义阶段完成求值,不会随外部变量变化。修复后完整保留遍历DataFrame、单用户独立FeatureGroup的原有逻辑:

import folium
import json
import pandas as pd

path = r'file.geojson'
with open(path) as file:
    data = json.load(file)

list_users = [
    [1,'Lisboa'],
    [2,'Porto'],
    [3,'Porto']
]
df_users = pd.DataFrame(list_users,columns = ['ID','Place'])


my_map = folium.Map(location=[39, -5],
        zoom_start=7, min_zoom=4, max_zoom=15,
        max_bounds=True,
        tiles="cartodbpositron"
        )

d = {} # 存储各用户对应的FeatureGroup

for _,user in df_users.iterrows():
    fg_name = f"FG_{user.ID}"
    d[fg_name] = folium.FeatureGroup(name=user.ID,overlay=True,show=False)
    fg_value = d[fg_name]

    # 按用户居住地定义当前图层的高亮区域
    if user.Place == 'Lisboa':
        list_red_places = ['Setúbal']
    elif user.Place == 'Porto':
        list_red_places = ['Braga','Aveiro']

    # 关键修改:通过默认参数绑定当前迭代的高亮列表,避免闭包延迟绑定问题
    folium.GeoJson(
        data=data,
        style_function=lambda x, red_places=list_red_places: {
            'fillColor': 'red' if x['properties']['Distrito'] in red_places else 'green',
            'fillOpacity': .5 if x['properties']['Distrito'] in red_places else 0.1,
            'weight': 0.1    
        }
    ).add_to(fg_value) 

    fg_value.add_to(my_map)

folium.LayerControl().add_to(my_map)
my_map
修复后效果
  • ID为1的里斯本用户图层:仅塞图巴尔区域标红,其余区域为低透明度绿色
  • ID为2、3的波尔图用户图层:布拉加、阿威罗区域标红,其余区域为低透明度绿色
  • 每个用户的图层独立控制显隐,互不干扰

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 16:36:28