如何用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
相关产品推荐
相关产品推荐

