外观
2D · TMapPolygonEditor 多边形编辑器
2D 文档 · Leaflet Draw 组件
组件负责区域绘制、选择、编辑、删除、洞岛关系和净面积计算;业务字段、接口请求和弹窗内容由使用方维护。
数据结构
ts
const polygons = ref<TMapPolygonData[]>([{
id: "area-1",
points: [
{ lng: 116.3, lat: 39.8 },
{ lng: 116.5, lat: 39.8 },
{ lng: 116.5, lat: 40.0 },
],
holes: [[/* 从主区域扣除的轮廓 */]],
islands: [[/* 与主区域同属一条数据的独立轮廓 */]],
area: 0,
properties: { name: "监管区", status: "正常" },
}]);area 由组件在创建和编辑后计算,单位固定为平方米,计算关系为“主轮廓 − 洞 + 岛”。
基础用法
vue
<TMap provider="osm">
<TMapPolygonEditor
ref="editorRef"
v-model="polygons"
:options="editorOptions"
@created="createArea"
@edited="updateArea"
@deleted="removeArea"
/>
</TMap>Options
| 名称 | 类型 | 默认值 | 说明 |
|---|---|---|---|
showToolbar | boolean | true | 显示 Leaflet Draw 工具栏 |
showPopup | boolean | true | 渲染 popup 插槽 |
popupPosition | "top" | "center" | "click" | "top" | popup 插槽定位方式:顶部中心、区域中心或点击位置 |
popupOffset | [number, number] | [0, -12] | 弹层相对定位锚点的像素偏移 |
allowIntersection | boolean | false | 允许轮廓自相交 |
pathOptions | Leaflet.PathOptions | — | 普通样式 |
selectedPathOptions | Leaflet.PathOptions | — | 选择/编辑样式 |
单条数据中的样式会覆盖全局 Options。旧版的独立样式 Props 仍可使用,但推荐统一传 options。
事件
| 事件 | 参数 | 说明 |
|---|---|---|
update:modelValue | TMapPolygonData[] | 同步全部区域 |
created | TMapPolygonChangeEvent | 新增完成 |
edited | TMapPolygonChangeEvent | 编辑保存完成 |
deleted | TMapPolygonChangeEvent | 删除完成 |
select | TMapPolygonSelectEvent | 选中区域 |
deselect | TMapPolygonData | 取消选择 |
popup-position-change | TMapPolygonSelectEvent | 弹层锚点变化 |
完成事件同时返回 polygons(本次变化)和 allPolygons(当前全部)。取消编辑不会触发完成事件。
插槽
| 插槽名 | 说明 |
|---|---|
popup | 自定义选中区域后的弹窗内容。组件提供当前区域、编辑状态、操作方法和弹窗位置。 |
默认情况下,弹窗位置由组件内部管理;业务侧只写 #popup 内容即可。
popup 插槽只有在满足以下条件时才会显示:
showPopup为true。- 用户已经点击并选中了一个多边形。
- 当前已经计算出弹窗锚点位置。
- 已传入
#popup插槽内容。
vue
<template #popup="{ polygon, editing, edit, remove, save, cancel, close }">
<section class="area-popup">
<button @click="close">关闭</button>
<h3>{{ polygon.properties?.name }}</h3>
<p>面积:{{ polygon.area }} 平方米</p>
<template v-if="editing">
<button @click="save">保存</button>
<button @click="cancel">取消</button>
</template>
<template v-else>
<button @click="edit">编辑</button>
<button @click="remove">删除</button>
</template>
</section>
</template>popup 插槽参数
| 参数 | 类型 | 说明 |
|---|---|---|
polygon | TMapPolygonData | 当前选中的多边形数据,可读取名称、状态、面积等业务字段。 |
position | TMapPolygonPopupPosition | 弹窗锚点位置。内部弹窗通常不用;外部自定义弹层时可读取。 |
editing | boolean | 当前是否正在编辑顶点,可用于切换“编辑/删除”和“保存/取消”按钮。 |
edit | () => boolean | 编辑当前多边形,成功返回 true。 |
remove | () => boolean | 删除当前多边形,并触发 deleted。 |
save | () => void | 保存编辑结果,更新坐标和面积,并触发 edited。 |
cancel | () => void | 取消编辑并恢复原坐标,不触发 edited。 |
close | () => void | 关闭弹窗并取消选择;编辑中关闭会先取消本次编辑。 |
使用建议
popup 插槽适合放区域名称、面积、状态、编辑按钮、删除按钮等业务内容。组件内部会在地图拖动、缩放和区域编辑时自动更新弹窗位置。保存接口仍建议放在 created、edited、deleted 事件中处理。
popup 定位方式
ts
const editorOptions: TMapPolygonEditorOptions = {
showPopup: true,
popupPosition: "click",
popupOffset: [0, -12],
};| 值 | 说明 |
|---|---|
top | 默认值,定位到多边形顶部中心,兼容旧版本。 |
center | 定位到多边形范围中心。 |
click | 定位到用户点击处,适合较大的园区或地块。 |
popupPosition: "click" 会记录点击经纬度,并在地图拖动或缩放后重新换算像素位置,弹窗会继续跟随点击点。
暴露方法
| 方法 | 用途 |
|---|---|
startDraw() | 绘制新的主区域 |
startDrawHole() | 为当前选中区域添加洞 |
startDrawIsland() | 为当前选中区域添加岛 |
startEdit() / startDelete() | 批量编辑或删除模式 |
saveAction() / stopAction() | 保存或取消当前操作 |
selectPolygon(id) | 按业务 ID 选择 |
editPolygon(id) | 按业务 ID 编辑 |
deletePolygon(id) | 按业务 ID 删除 |
clear() | 清空全部区域 |
getPolygons() | 获取标准化区域数据 |
updatePopupPosition() | 手动刷新弹层位置 |
添加洞或岛前必须先选中一个业务区域;非法轮廓不会写入数据。
移动端绘制
移动端绘制时仍可单指拖动地图和双指缩放。组件会自动区分地图手势与绘制操作:只有单指短按且手指移动距离很小时才添加顶点,拖动地图、双指缩放、系统取消触摸以及拖动已有顶点都不会新增顶点。手势结束后产生的残余点击也会自动过滤,业务侧不需要另外处理。