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

如何为Folium Draw Toolbar添加图层选择选项框?

协作地图项目完整解决方案

针对你的需求,以下是基于Folium和Draw插件的实现方案,包含图层选择下拉框、绘制元素关联图层、数据保存三个核心功能:

1. 创建基础地图与图层

首先初始化地图和三个目标图层,每个图层分配唯一名称用于后续关联:

import folium
from folium.plugins import Draw
from folium.elements import MacroElement

# 初始化地图(坐标示例为利马,可根据需求修改)
m = folium.Map(location=[-12.0464, -77.0428], zoom_start=12)

# 创建三个业务图层
layer_mujeres = folium.FeatureGroup(name="Ubicacion de mujeres", show=True)
layer_violencia = folium.FeatureGroup(name="Zona de Violencia", show=True)
layer_diversas = folium.FeatureGroup(name="Poblaciones diversas", show=True)

# 添加图层到地图并启用图层控制器
m.add_child(layer_mujeres)
m.add_child(layer_violencia)
m.add_child(layer_diversas)
folium.LayerControl().add_to(m)

2. 添加图层选择下拉框与绘制逻辑

通过自定义MacroElement插入HTML和JS代码,实现绘制前选择图层,自动将标记/多边形添加到选中图层:

class LayerSelector(MacroElement):
    def __init__(self):
        super().__init__()
        self._template = """
        {% macro script(this, kwargs) %}
        <!-- 图层选择UI -->
        <div style="position: fixed; top: 10px; right: 100px; z-index: 9999; background: #fff; padding: 8px 12px; border-radius: 6px; box-shadow: 0 2px 4px rgba(0,0,0,0.1);">
            <label for="layer-picker" style="margin-right: 8px;">选择图层:</label>
            <select id="layer-picker" style="padding: 4px; border-radius: 4px; border: 1px solid #ddd;">
                <option value="Ubicacion de mujeres">Ubicacion de mujeres</option>
                <option value="Zona de Violencia">Zona de Violencia</option>
                <option value="Poblaciones diversas">Poblaciones diversas</option>
            </select>
        </div>

        <!-- 绑定Draw插件的绘制事件 -->
        <script>
            const layerPicker = document.getElementById('layer-picker');
            // 映射图层名称到实际图层对象
            const targetLayers = {
                'Ubicacion de mujeres': {{ this._parent.get_name() }}.getChild('Ubicacion de mujeres'),
                'Zona de Violencia': {{ this._parent.get_name() }}.getChild('Zona de Violencia'),
                'Poblaciones diversas': {{ this._parent.get_name() }}.getChild('Poblaciones diversas')
            };

            // 监听绘制完成事件
            {{ this._parent.get_name() }}.on('draw:created', function(e) {
                const drawnLayer = e.layer;
                const selectedLayerName = layerPicker.value;
                
                // 给绘制元素添加图层归属属性,方便后续识别
                drawnLayer.feature.properties = {
                    layer: selectedLayerName
                };
                
                // 将元素添加到选中的图层
                targetLayers[selectedLayerName].addLayer(drawnLayer);
            });
        </script>
        {% endmacro %}
        """

# 添加图层选择器到地图
LayerSelector().add_to(m)

# 配置Draw插件,只启用需要的绘制类型
Draw(
    draw_options={
        'marker': True,       # 允许添加标记
        'polygon': True,      # 允许添加多边形
        'polyline': False,
        'rectangle': False,
        'circle': False,
        'circlemarker': False
    },
    edit_options={'edit': False}  # 可根据需求开启编辑功能
).add_to(m)

3. 添加数据保存功能

同样通过MacroElement添加保存按钮,点击后导出所有绘制元素为GeoJSON格式:

class SaveMapData(MacroElement):
    def __init__(self):
        super().__init__()
        self._template = """
        {% macro script(this, kwargs) %}
        <!-- 保存按钮UI -->
        <div style="position: fixed; top: 10px; right: 10px; z-index: 9999;">
            <button onclick="exportMapData()" style="padding: 8px 16px; border-radius: 6px; background: #28a745; color: #fff; border: none; cursor: pointer;">保存数据</button>
        </div>

        <script>
            function exportMapData() {
                const allFeatures = [];
                
                // 遍历所有图层,收集绘制的要素
                {% for layer in this._parent._children.values() %}
                    if ({{ layer.get_name() }} instanceof L.FeatureGroup) {
                        {{ layer.get_name() }}.eachLayer(function(layer) {
                            if (layer.feature) {
                                allFeatures.push(layer.feature);
                            }
                        });
                    }
                {% endfor %}

                // 构建标准GeoJSON对象
                const geoJSON = {
                    type: 'FeatureCollection',
                    features: allFeatures
                };

                // 创建下载链接
                const dataStr = JSON.stringify(geoJSON, null, 2);
                const dataUri = 'data:application/json;charset=utf-8,' + encodeURIComponent(dataStr);
                const link = document.createElement('a');
                
                link.href = dataUri;
                link.download = 'map-drawings.geojson';
                link.click();
            }
        </script>
        {% endmacro %}
        """

# 添加保存功能到地图
SaveMapData().add_to(m)

# 生成最终的地图HTML文件
m.save('collaborative_map.html')

核心要点说明

  • 图层选择框采用固定定位,悬浮在地图右上角,不影响地图操作
  • 绘制元素会自动关联选中的图层,同时在要素属性中标记归属图层,便于后续数据分类
  • 保存功能导出的GeoJSON是标准格式,可直接导入GIS工具或后端数据库
  • 如果需要后端实时保存,可修改exportMapData函数,通过AJAX将GeoJSON数据发送到你的后端接口

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 14:45:24