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

如何用leaflet-geoman在leaflet地图绘制自定义对象并导出GeoJSON

基于leaflet-geoman的多类型绘制功能实现示例

实现逻辑说明

所有需求均可通过leaflet-geoman原生事件+Leaflet基础API实现,核心实现步骤如下:

1. 基础配置

首先初始化地图、不可编辑的底图层,配置三类绘制对象的专属图层组和样式:

// 初始化地图
const map = L.map('map').setView([39.9, 116.3], 13);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png').addTo(map);

// 加载不可编辑的农业地块图层,设置pmIgnore避免被geoman误编辑
const farmlandLayer = L.geoJSON(你的农业地块GeoJSON数据, {
  pmIgnore: true
}).addTo(map);

// 定义三类绘制对象的专属图层组,后续可加入图层控件实现显隐
const treeLayer = L.layerGroup().addTo(map); // 树木标记层
const hedgeLayer = L.layerGroup().addTo(map); // 绿篱折线层
const woodlandLayer = L.layerGroup().addTo(map); // 林地层

// 加入图层控制控件
L.control.layers(null, {
  "树木": treeLayer,
  "绿篱": hedgeLayer,
  "林地": woodlandLayer,
  "农业地块": farmlandLayer
}).addTo(map);

// 自定义树木图标
const treeIcon = L.icon({
  iconUrl: '你的树木图标本地路径',
  iconSize: [32, 32],
  iconAnchor: [16, 32]
});

// 全局变量存储当前选中的绘制类型
let currentDrawType = '';

2. 绘制类型切换逻辑

你可以通过下拉框或按钮触发不同绘制模式,同时绑定对应样式:

// 切换到树木绘制
function enableTreeDraw() {
  currentDrawType = 'tree';
  // 先关闭其他绘制模式
  map.pm.disableDraw();
  map.pm.enableDraw('Marker', {
    markerIcon: treeIcon,
    snappable: false // 不需要吸附可以关闭
  });
}

// 切换到绿篱绘制
function enableHedgeDraw() {
  currentDrawType = 'hedge';
  map.pm.disableDraw();
  map.pm.enableDraw('Line', {
    pathOptions: {
      color: 'brown',
      weight: 3,
      opacity: 0.8
    }
  });
}

// 切换到林地绘制
function enableWoodlandDraw() {
  currentDrawType = 'woodland';
  map.pm.disableDraw();
  map.pm.enableDraw('Polygon', {
    pathOptions: {
      fillColor: 'green',
      fillOpacity: 0.5,
      color: 'darkgreen',
      weight: 2
    }
  });
}

3. 绘制完成后采集补充信息

监听pm:create事件,绘制完成后自动弹出表单填写属性,信息会直接存入要素的properties字段:

map.on('pm:create', e => {
  const layer = e.layer;
  // 弹出信息填写弹窗
  const popupContent = `
    <div style="width: 200px">
      <p>对象名称:<input type="text" id="objName" style="width: 100%"/></p>
      <p>备注信息:<textarea id="objRemark" style="width: 100%" rows="2"></textarea></p>
      <button onclick="saveObjInfo()" style="width: 100%">确认保存</button>
    </div>
  `;
  layer.bindPopup(popupContent).openPopup();

  // 保存信息到图层属性
  window.saveObjInfo = () => {
    const name = document.getElementById('objName').value || '未命名';
    const remark = document.getElementById('objRemark').value || '';
    // 初始化要素属性
    layer.feature = layer.feature || { type: 'Feature', properties: {} };
    layer.feature.properties = {
      name,
      remark,
      objType: currentDrawType
    };
    layer.closePopup();
    // 按类型存入对应图层组
    if (currentDrawType === 'tree') treeLayer.addLayer(layer);
    else if (currentDrawType === 'hedge') hedgeLayer.addLayer(layer);
    else if (currentDrawType === 'woodland') woodlandLayer.addLayer(layer);
    // 绘制完成自动关闭绘制模式,不需要可以删掉
    map.pm.disableDraw();
  }
});

4. 导出带属性的GeoJSON

导出时自动合并三类图层的所有要素,保留所有补充属性:

function exportDrawResult() {
  const features = [];
  // 遍历所有绘制图层收集要素
  [treeLayer, hedgeLayer, woodlandLayer].forEach(group => {
    group.eachLayer(layer => {
      if (layer.feature) features.push(layer.feature);
    });
  });
  // 生成GeoJSON
  const geojsonStr = JSON.stringify({
    type: 'FeatureCollection',
    features: features
  }, null, 2);
  // 触发本地下载
  const blob = new Blob([geojsonStr], { type: 'application/geo+json' });
  const url = URL.createObjectURL(blob);
  const a = document.createElement('a');
  a.href = url;
  a.download = `绘制结果_${Date.now()}.geojson`;
  a.click();
  URL.revokeObjectURL(url);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 02:24:07