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

Folium如何实现标记icon颜色随当前日期动态变化无需修改生成的HTML?

解决方案

核心问题原因

你直接将eval语句传入folium.Icon(color=)参数无效,是因为Folium默认会对所有传入的字符串参数做HTML转义处理,避免注入风险,所以JS逻辑会被转换为纯文本字符串,不会被浏览器识别为可执行代码。

实现方法

方法1:自定义Icon类重写渲染模板(推荐)

直接重写Folium图标的Jinja2渲染模板,把动态颜色判断逻辑内置到模板中,生成的HTML文件直接自带执行逻辑,无需事后修改。
Python实现代码如下:

import folium
from folium.plugins import AwesomeMarkers

# 自定义支持动态日期判断的图标类
class DynamicDateIcon(AwesomeMarkers):
    _template = """
    {% macro script(this, kwargs) %}
    var {{ this.get_name() }} = L.AwesomeMarkers.icon({
        "extraClasses": "{{ this.extra_classes }}",
        "icon": "{{ this.icon }}",
        "iconColor": "{{ this.icon_color }}",
        "markerColor": eval(`
            const targetDate = new Date("{{ this.target_date }}").setHours(0,0,0,0);
            const nowDate = new Date().setHours(0,0,0,0);
            if (targetDate < nowDate) { "lightgray" }
            else if (targetDate == nowDate) { "red" }
            else { "green" }
        `),
        "prefix": "{{ this.prefix }}"
    });
    {% endmacro %}
    """
    def __init__(self, target_date, icon="info-sign", icon_color="white", prefix="glyphicon", **kwargs):
        super().__init__(icon=icon, icon_color=icon_color, prefix=prefix, **kwargs)
        self.target_date = target_date

# 调用示例
m = folium.Map(location=[39.9, 116.4], zoom_start=10)
# 每个标记单独传入对应的目标日期即可
folium.Marker(
    location=[39.9, 116.4],
    icon=DynamicDateIcon(target_date="2021-09-01")
).add_to(m)

m.save("dynamic_icon_map.html")

方法2:全局注入JS逻辑批量修改

如果不想自定义类,也可以在地图生成后插入一段全局JS,页面加载完成后遍历所有标记,根据绑定的目标日期属性修改图标颜色。
Python实现代码如下:

import folium
from folium import Element

m = folium.Map(location=[39.9, 116.4], zoom_start=10)
# 给标记添加自定义属性存储目标日期
marker = folium.Marker(
    location=[39.9, 116.4],
    icon=folium.Icon(color="blue") # 此处默认颜色会被JS覆盖,可随意填写
)
marker.options['target_date'] = "2021-09-01"
marker.add_to(m)

# 插入全局动态颜色修改逻辑
dynamic_js = Element("""
<script>
document.addEventListener('DOMContentLoaded', function() {
    {{ this.parent.get_name() }}.eachLayer(function(layer) {
        if (layer.options.target_date) {
            const targetDate = new Date(layer.options.target_date).setHours(0,0,0,0);
            const nowDate = new Date().setHours(0,0,0,0);
            let color;
            if (targetDate < nowDate) color = "lightgray";
            else if (targetDate == nowDate) color = "red";
            else color = "green";
            layer.setIcon(L.AwesomeMarkers.icon({
                icon: "info-sign",
                iconColor: "white",
                markerColor: color,
                prefix: "glyphicon"
            }));
        }
    });
});
</script>
""")
m.get_root().html.add_child(dynamic_js)

m.save("dynamic_icon_map.html")

说明

  • 两种方法都无需事后通过正则修改生成的HTML代码,直接生成的文件即可正常运行
  • 标记数量较多时推荐使用方法1,性能更优,无需页面加载后二次遍历修改标记

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 05:15:03