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
相关产品推荐
相关产品推荐

