Folium按激活图层显示对应标记及双地图子组异常问题咨询
问题1:为不同瓦片图层配置独立标记集合的实现
是可以实现的,核心逻辑是将对应图层的标记放入FeatureGroup中,两种常用实现方案:
- 方案1:单地图模式,通过自定义JS监听瓦片图层切换事件,动态显示/隐藏绑定的标记
FeatureGroup - 方案2:双地图模式(即你已采纳的
DualMap方案),分别给两个子地图配置独立的瓦片层和标记集合,兼容性更高,无需额外写JS代码
问题2:DualMap子组逻辑颠倒、弹窗错位的修复方案
你遇到的问题核心原因是**FeatureGroup、子组、标记集群都直接加到了全局DualMap对象上,默认绑定到左侧m1主地图,没有给右侧m2次地图配置独立的图层体系**。修改需要调整以下核心逻辑:
核心修改点
- 不要把图层组件直接加到全局
DualMap对象,分别给m1(左图,OpenStreetMap)和m2(右图,Google Maps)创建独立的图层体系 - 左右地图的图层变量名区分开,避免ID冲突
- 分别给两个子地图添加独立的
LayerControl,不要给全局DualMap添加
修复后的核心代码示例
替换原代码中图层配置、标记添加部分即可:
# 原有DualMap初始化、瓦片图层添加逻辑保留 folium_map = folium.plugins.DualMap(location=[50, 50], control_scale=True, zoom_start=9, tiles=None, max_bounds=True, prefer_canvas=False) folium.TileLayer('openstreetmap').add_to(folium_map.m1) folium.raster_layers.TileLayer( tiles="http://{s}.google.com/vt/lyrs=s&x={x}&y={y}&z={z}", attr="google", name="google maps", max_zoom=20, subdomains=["mt0", "mt1", "mt2", "mt3"], overlay=False, control=True, ).add_to(folium_map.m2) # -------------------------- # 新增:分别给左右子地图创建独立图层体系 # -------------------------- ### 左图m1图层(OpenStreetMap,展示带图标+文本标记) mcg_m1 = folium.plugins.MarkerCluster(name="Locations with Images", control=False) folium_map.m1.add_child(mcg_m1) # ABC Stores左图图层 fg1_m1 = folium.FeatureGroup(name='ABC Stores') folium_map.m1.add_child(fg1_m1) g1_m1_own = plugins.FeatureGroupSubGroup(fg1_m1, '\tOwn - ABC', show=False) folium_map.m1.add_child(g1_m1_own) g1_m1_partner = plugins.FeatureGroupSubGroup(fg1_m1, '\tPartnership - ABC', show=False) folium_map.m1.add_child(g1_m1_partner) # Acme Fitness左图图层 fg2_m1 = folium.FeatureGroup(name='Acme Fitness') folium_map.m1.add_child(fg2_m1) g2_m1_own = plugins.FeatureGroupSubGroup(fg2_m1, '\tOwn - ACME', show=False) folium_map.m1.add_child(g2_m1_own) g2_m1_partner = plugins.FeatureGroupSubGroup(fg2_m1, '\tPartnership - ACME', show=False) folium_map.m1.add_child(g2_m1_partner) ### 右图m2图层(Google Maps,展示纯文本标记) mcg_m2 = folium.plugins.MarkerCluster(name="Locations with Text", control=False) folium_map.m2.add_child(mcg_m2) # ABC Stores右图图层 fg1_m2 = folium.FeatureGroup(name='ABC Stores') folium_map.m2.add_child(fg1_m2) g1_m2_own = plugins.FeatureGroupSubGroup(fg1_m2, '\tOwn - ABC', show=False) folium_map.m2.add_child(g1_m2_own) g1_m2_partner = plugins.FeatureGroupSubGroup(fg1_m2, '\tPartnership - ABC', show=False) folium_map.m2.add_child(g1_m2_partner) # Acme Fitness右图图层 fg2_m2 = folium.FeatureGroup(name='Acme Fitness') folium_map.m2.add_child(fg2_m2) g2_m2_own = plugins.FeatureGroupSubGroup(fg2_m2, '\tOwn - ACME', show=False) folium_map.m2.add_child(g2_m2_own) g2_m2_partner = plugins.FeatureGroupSubGroup(fg2_m2, '\tPartnership - ACME', show=False) folium_map.m2.add_child(g2_m2_partner) # -------------------------- # 标记添加:分别给左右图层添加对应样式的标记 # -------------------------- for index, row in df1.iterrows(): popup = row['Name'] tooltip = f'<strong>{row["Location"]}</strong>' if row['Type'] == 'ABC': # 左图用带购物车的图标 icon_left = folium.Icon(color=row['Color'], icon="shopping-cart") # 右图用纯文本DivIcon,可自定义样式 icon_right = folium.DivIcon(html=f"<div style='font-size:12px;color:{row['Color']}'>{row['Name']}</div>") if row['Ownership'] == 'Own': folium.Marker(location=[row['Latitude'], row['Longitude']], draggable=False, clustered_marker=True, tooltip=tooltip, popup=folium.Popup(popup, max_width=350), icon=icon_left).add_to(g1_m1_own) folium.Marker(location=[row['Latitude'], row['Longitude']], draggable=False, clustered_marker=True, tooltip=tooltip, popup=folium.Popup(popup, max_width=350), icon=icon_right).add_to(g1_m2_own) else: folium.Marker(location=[row['Latitude'], row['Longitude']], draggable=False, clustered_marker=True, tooltip=tooltip, popup=folium.Popup(popup, max_width=350), icon=icon_left).add_to(g1_m1_partner) folium.Marker(location=[row['Latitude'], row['Longitude']], draggable=False, clustered_marker=True, tooltip=tooltip, popup=folium.Popup(popup, max_width=350), icon=icon_right).add_to(g1_m2_partner) elif row['Type'] == 'Acme': icon_left = folium.Icon(prefix="fa", color=row['Color'], icon="camera") icon_right = folium.DivIcon(html=f"<div style='font-size:12px;color:{row['Color']}'>{row['Name']}</div>") if row['Ownership'] == 'Own': folium.Marker(location=[row['Latitude'], row['Longitude']], draggable=False, clustered_marker=True, tooltip=tooltip, popup=folium.Popup(popup, max_width=350), icon=icon_left).add_to(g2_m1_own) folium.Marker(location=[row['Latitude'], row['Longitude']], draggable=False, clustered_marker=True, tooltip=tooltip, popup=folium.Popup(popup, max_width=350), icon=icon_right).add_to(g2_m2_own) else: folium.Marker(location=[row['Latitude'], row['Longitude']], draggable=False, clustered_marker=True, tooltip=tooltip, popup=folium.Popup(popup, max_width=350), icon=icon_left).add_to(g2_m1_partner) folium.Marker(location=[row['Latitude'], row['Longitude']], draggable=False, clustered_marker=True, tooltip=tooltip, popup=folium.Popup(popup, max_width=350), icon=icon_right).add_to(g2_m2_partner) # -------------------------- # 分别给两个子地图添加图层控制,不要给全局folium_map添加 # -------------------------- folium.LayerControl().add_to(folium_map.m1) folium.LayerControl().add_to(folium_map.m2) # 原有小地图、全屏插件添加逻辑保留即可
内容的提问来源于stack exchange,提问作者sdewitt
相关产品推荐
相关产品推荐

