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

folium中两个MarkerCluster不同步?如何集成CircleMarker与Marker

Folium中MarkerCluster图层同步问题解决方法

问题描述

我在Folium中为现有Marker添加MarkerCluster来区分标记,聚类功能正常但图层不同步:关闭一个图层时,仅第一个MarkerCluster消失,作为第二个标记的CircleMarker仍显示。

原代码如下:

df = pd.read_csv("or_geo.csv")
fo=FeatureGroup(name="OR",overlay = True)
openreach_cluster = MarkerCluster(name="OR").add_to(map)
openreach_status = MarkerCluster(control=False,
                              visible=True
                              ).add_to(map)
for i,row in df.iterrows():
   lat =df.at[i, 'lat']
   lng = df.at[i, 'lng']
   sp = df.at[i, 'sp']
   stat = df.at[i,'status'] 
   popup = df.at[i,'sp'] +'<br>' + str(df.at[i, 'street']) + '<br>' + str(df.at[i, 'post code']) + '<br>{}'.format(style)

   or_marker = folium.Marker(location=[lat,lng], tooltip='<strong>Job details</strong>', popup=popup, icon = folium.Icon(
    color='blue', icon='glyphicon-calendar'))

or_stat_marker = folium.CircleMarker(
    location=[lat,lng],
    radius=10,
    color=or_color(stat),
    fill_color=or_color(stat),
    fill_opacity=0.5)

openreach_cluster.add_child(or_marker)
openreach_status.add_child(or_stat_marker)

我尝试过两种方案但未达预期:第一种导致标记重复,需点击才能查看;第二种仍有聚类重复,且CircleMarker位置异常。我需要实现CircleMarker与Point Marker集成,达到示例图效果,请问如何合并或同步这两个MarkerCluster?


问题分析

  1. 原代码中openreach_status设置了control=False,意味着该聚类不会出现在图层控制列表中,无法通过图层开关同步控制它的显示/隐藏。
  2. or_stat_marker的代码缩进错误,位于for循环外部,只会基于最后一行数据创建单个CircleMarker,这是位置异常的直接原因。

解决方案

方案一:同一位置标记绑定到FeatureGroup,再加入单个MarkerCluster

将每个坐标点的Marker和CircleMarker放入同一个FeatureGroup,再将该组加入单个MarkerCluster,这样图层控制就能同步控制所有标记的显示状态:

import folium
from folium.plugins import MarkerCluster
import pandas as pd

def or_color(status):
    # 补充你的状态-颜色映射逻辑,示例如下
    if status == "completed":
        return "green"
    elif status == "pending":
        return "orange"
    else:
        return "red"

df = pd.read_csv("or_geo.csv")
map = folium.Map(location=[df['lat'].mean(), df['lng'].mean()], zoom_start=10)

# 创建单个用于图层控制的MarkerCluster
openreach_cluster = MarkerCluster(name="OR").add_to(map)

for i, row in df.iterrows():
    lat = row['lat']
    lng = row['lng']
    sp = row['sp']
    stat = row['status']
    style = ""  # 补充你的style变量值
    popup = f"{sp}<br>{row['street']}<br>{row['post code']}<br>{style}"

    # 创建当前位置的FeatureGroup,包含两个标记
    location_group = folium.FeatureGroup(show=True)
    
    # 添加普通Marker
    or_marker = folium.Marker(
        location=[lat, lng],
        tooltip='<strong>Job details</strong>',
        popup=popup,
        icon=folium.Icon(color='blue', icon='glyphicon-calendar')
    )
    location_group.add_child(or_marker)
    
    # 添加CircleMarker
    or_stat_marker = folium.CircleMarker(
        location=[lat, lng],
        radius=10,
        color=or_color(stat),
        fill_color=or_color(stat),
        fill_opacity=0.5
    )
    location_group.add_child(or_stat_marker)
    
    # 将位置组加入聚类
    openreach_cluster.add_child(location_group)

# 添加图层控制组件
folium.LayerControl().add_to(map)
map.save("map.html")

方案二:自定义JS同步两个独立MarkerCluster的可见性

如果需要保留两个独立的MarkerCluster,可通过自定义JavaScript监听图层控制的变化,同步两个聚类的显示状态:

import folium
from folium.plugins import MarkerCluster
import pandas as pd

def or_color(status):
    if status == "completed":
        return "green"
    elif status == "pending":
        return "orange"
    else:
        return "red"

df = pd.read_csv("or_geo.csv")
map = folium.Map(location=[df['lat'].mean(), df['lng'].mean()], zoom_start=10)

# 创建两个均加入图层控制的MarkerCluster
openreach_cluster = MarkerCluster(name="OR").add_to(map)
openreach_status = MarkerCluster(name="OR Status").add_to(map)

for i, row in df.iterrows():
    lat = row['lat']
    lng = row['lng']
    sp = row['sp']
    stat = row['status']
    style = ""
    popup = f"{sp}<br>{row['street']}<br>{row['post code']}<br>{style}"

    or_marker = folium.Marker(
        location=[lat, lng],
        tooltip='<strong>Job details</strong>',
        popup=popup,
        icon=folium.Icon(color='blue', icon='glyphicon-calendar')
    )
    openreach_cluster.add_child(or_marker)
    
    or_stat_marker = folium.CircleMarker(
        location=[lat, lng],
        radius=10,
        color=or_color(stat),
        fill_color=or_color(stat),
        fill_opacity=0.5
    )
    openreach_status.add_child(or_stat_marker)

# 添加自定义JS同步图层状态
custom_js = """
document.addEventListener('DOMContentLoaded', function() {
    var cluster1 = document.querySelector('.leaflet-control-layers').querySelector('input[value="OR"]');
    var cluster2 = document.querySelector('.leaflet-control-layers').querySelector('input[value="OR Status"]');
    
    cluster1.addEventListener('change', function() {
        cluster2.checked = cluster1.checked;
        map._layers[cluster2.layerId].setVisible(cluster1.checked);
    });
    
    cluster2.addEventListener('change', function() {
        cluster1.checked = cluster2.checked;
        map._layers[cluster1.layerId].setVisible(cluster2.checked);
    });
});
"""

folium.Element(custom_js).add_to(map.get_root().html)
folium.LayerControl().add_to(map)
map.save("map.html")

注意事项

  • 方案一更简洁,推荐使用,它将同一位置的两个标记绑定,聚类和图层控制逻辑清晰。
  • 方案二适合需要单独控制两个聚类但又要同步的场景,需根据实际图层名称调整JS中的选择器。
  • 已修复原代码中CircleMarker缩进错误的问题,确保每个数据行都能生成对应标记。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 11:35:28