跳转至

地图字段(MapField)设计方案

地图字段用于在表单中嵌入交互式地图,支持用户在地图上标记点位、绘制路径与区域、填写地址与备注,并将结果以 JSON 字符串形式持久化到文档 Item 中。

层次 实现位置
后端 / Java cn.myapps.core.runtime.dynaform.form.ejb.MapFieldobpm-core/.../form/ejb/MapField.java
表单设计器 MapField.js(scope: mapFieldobpm-designer-vue3 字段模块)
前端运行时(PC) <o-map>obpm-runtime-web/portal/vue3/src/components/field/o_map.vue
前端运行时(移动端) o_map.vueobpm-runtime-mobile-vue3/src/components/o_map.vue

表单 XML 中字段标签名为 mapfield,解析时映射到 MapField 类;运行时通过 toAttributes 将配置下发至 o-map 组件。


后端定义(Java)

MapField 继承 FormField,实现 ValueStoreField 接口,表示该字段值会写入文档 Item 并持久化到数据库。

专有属性

属性 类型 说明
openType String 地图打开/展示方式。dialog:弹窗模式;其他值(默认 iframe):内嵌模式
valueType String 数据存储类型(几何语义),决定字段值 JSON 的结构与地图交互模式。可选:PointMultiPointLineStringBoundsPolygon;默认 Point。后端常量见 MapField.VALUE_TYPE_*
defaultCenterAddress String 默认中心地址。字符串存储,整段地址文本,格式如「中国北京市市辖区东城区」。地图初次打开时作为 geocoder 关键字定位初始中心;为空时使用固定默认坐标
level String 默认缩放级别。天地图 zoom,取值 1–18;未配置时 getter 兜底 "4"

valueType 取值说明

valueType 含义 典型场景 目标 JSON type
Point 单坐标点 / 单标记点 地址选点、单点定位 "Point"
MultiPoint 多坐标点 / 多标记点 批量标注、门店分布、巡检点位 "MultiPoint"
LineString 路径 / 轨迹 路线规划、移动轨迹、道路 "LineString"
Bounds 矩形可视范围 地图视口、矩形围栏 "Bounds"
Polygon 多边形区域 不规则围栏、行政区范围 "Polygon"

设计器配置 valueType 后,后端通过 toAttributes / toPrintAttributesvalueType 下发至运行时;o-map 据此限制可绘制的几何类型,并按对应结构读写 value。旧版标记点数组在读取时兼容为 MultiPoint

默认缩放级别(level)

规则 说明
存储 字符串,如 "4""12"
取值范围 1–18,与天地图 zoom 一致
getter 未配置或无效时返回 "4"
设计器 UI el-select 绑定 levelNumber,选项来自 zoomLevels(1–18),选项文案 i18n 键 view.zoom_level_options.{level};变更时通过 onLevelChange 写回 level

继承自 FormField 的常用属性

属性 说明
name 字段名,对应文档 Item 名称
fieldtype 值类型,设计器默认为 VALUE_TYPE_TEXT(文本)
discript 字段描述
hiddenScript / hiddenValue 隐藏条件脚本及隐藏时显示值
hiddenPrintScript / printHiddenValue 打印隐藏条件及打印隐藏显示值
readonlyScript 只读条件脚本
calculateOnRefresh / onlyCalculate 重计算相关
mobile 移动端适配
instantValidate / validateLibs 即时校验

渲染输出

MapField 在不同场景下输出不同 HTML / 属性:

方法 场景 行为
toHtmlTemplate Vue3 表单模板 输出 <o-map id="..."></o-map>
toAttributes Vue3 运行时属性 输出 idnamevalueopenTypedisplayType 等属性 Map
toHtml / toPreviewHtml 传统 HTML 模式 输出 type='hidden'<input moduleType='mapField'>,携带 openTypedisplayTypevalue
toGridHtmlText 列表/网格视图 不支持,显示红色提示 {*[cn.myapps.runtime.dynaform.view.GridNotSupportMapField]*}
toPrintHtmlTxt 打印 隐藏时返回 printHiddenValue,否则为空
toPdfHtmlTxt PDF 导出 输出地图图标 <img src=".../mapfield/img.png">

openType 与 HTML 属性映射

if (openType == "dialog" || openType.equals("dialog")) {
    html.append("display='true'");   // 弹窗模式
} else {
    html.append("nodialog='true'"); // 内嵌模式(默认 iframe)
}

toAttributes 输出字段

运行时前端通过 toAttributes 获取以下关键属性:

  • iddivIddocIdformId
  • namefieldtypelayoutType
  • displayType(权限显示类型)
  • value(文档 Item 值,JSON 字符串)
  • openType
  • valueType(数据存储类型,Point / MultiPoint / LineString / Bounds / Polygon,默认 Point
  • defaultCenterAddress(默认中心地址,整段地址字符串)
  • level(默认缩放级别,天地图 zoom 1–18,默认 "4"
  • hiddenValuehiddenScript
  • formField(固定为 MapField
  • mobileinstantValidatevalidateLibscalculateOnRefresh

权限显示类型(displayType)

getDisplayType 按以下优先级判定:

  1. HIDDEN(隐藏):流程字段权限为隐藏,或隐藏脚本返回 true
  2. DISABLED(屏蔽):文档不可编辑
  3. READONLY(只读):流程字段权限为只读,或只读脚本返回 true
  4. MODIFY(修改):默认可编辑

前端 o-map 组件根据 displayType 分别渲染:隐藏占位、只读/屏蔽地图、可编辑地图(含弹窗/内嵌两种 openType)。


设计器配置

表单设计器字段模块为 MapField.js(scope: mapField),在表单「内容」页签拖拽或插入地图字段后,于属性面板配置以下项:

属性 默认值 说明
name 地图{N} 字段名称
opentype iframe 打开方式:iframe(嵌入到页面)/ dialog(弹窗)
maptype tianditu 地图插件,固定为天地图(tianditu
valueType Point 数据存储类型:Point / MultiPoint / LineString / Bounds / Polygon(表单 XML 属性 valuetype,后端已实现)
defaultCenterAddress 默认中心地址,整段文本字符串(如 中国北京市市辖区东城区
level '4' 默认缩放级别。el-select 下拉选择,选项 1–18(zoomLevels),文案 i18n 键 view.zoom_level_options.{level};保存至 MapField.level
calculateonrefresh false 刷新时重计算
onlyCalculate false 仅计算不存值
discript 描述
hiddenscript / hiddenvalue 隐藏条件与隐藏显示值
hiddenprintscript / printhiddenvalue 打印隐藏条件与显示值

设计器属性名与后端 Java 属性存在大小写差异(如 opentypeopenType),保存至表单 XML 时由字段模块映射。


前端运行时(PC)

PC 端运行时组件为 <o-map>o_map.vue),由 NormalForm 动态模板渲染;移动端为独立 o_map.vue 实现,部分能力与 PC 存在差异(见 已知限制与注意事项)。

后端配置在前端的消费

后端 / 设计器来源 前端行为
displayType 隐藏占位 / 只读屏蔽 / 可编辑地图
openType dialog 弹窗打开地图;其他值内嵌 iframe
valueType 限制可绘制几何类型,决定读写 JSON 结构
defaultCenterAddress + level 初始视口中心与缩放级别
value 文档 Item 中的 JSON 字符串,解析后渲染几何与标记

地图引擎

  • PC 端:天地图 API 4.0(矢量 vec / 影像 img
  • 移动端:天地图(obpm-runtime-mobile-vue3/src/components/o_map.vue

初始视口

地图加载前,前端读取 defaultCenterAddress 作为关键字,调用天地图 geocoder API 定位初始中心,并使用 level 作为初始 zoom(无效或未配置时兜底 "4");若未配置默认地址或 geocoder 无结果,则使用固定默认坐标(广州附近)及 level 作为 zoom。

openType 展示差异

openType 展示方式
dialog 显示按钮,点击后弹出对话框内嵌地图
其他(iframe 直接在表单中内嵌地图区域

交互操作

可编辑模式(displayType = MODIFY)下,地图上方显示操作栏。选点模式外显示 添加,选点模式内显示 添加完成(二者互斥,按状态切换);其后为 清除查询。不使用右键添加。

按钮 说明
添加 非选点模式时显示。点击进入选点模式,**左键点击地图**添加或继续编辑几何数据;点类型标记会逆地理编码获取地址
添加完成 选点模式时显示。退出选点模式。Polygon 且顶点 ≥ 3 时确认保存当前多边形;未完成的 Bounds 选点(仅第一点)会被取消
清除 清空当前字段全部几何数据并退出选点模式

valueType 的选点行为:

valueType 选点模式下的地图左键点击行为
Point 设置/替换单个标记点,点击「添加完成」退出选点模式
MultiPoint 添加一个标记点,可连续点击地图追加多点,点击「添加完成」退出
LineString 按顺序追加路径节点,点击「添加完成」退出
Bounds 依次选择对角两点确定矩形范围,点击「添加完成」退出
Polygon 依次追加顶点(至少 3 个),首尾自然连线闭合;点击「添加完成」保存并退出

PointMultiPoint 标记点在地图上 常驻显示标题(title)与内容(detail(有值时以文字标签显示在标记点上方,两行换行展示);点击标记仍可打开信息窗口编辑标题与内容。标记点以及 LineStringBoundsPolygon 的几何顶点,在可编辑模式下均 可拖动;拖动后更新坐标(标记点同步逆地理编码地址)并写回字段值。其中 LineStringBoundsPolygon 的顶点以 圆形句点 样式显示;点击句点选中**后句点高亮,并在句点 **右侧显示删除图标,点击删除图标可移除对应节点(Bounds 删除角点即清除整个矩形范围)。点击地图空白处取消选中。

其他操作

  • 点击标记:弹出信息窗口,可编辑标题(title)、内容(detail);确认后更新地图上的标题与内容标签
  • 搜索:支持经纬度定位、关键字地址搜索(天地图 geocoder API)
  • 地图/混合:切换矢量底图与卫星影像

当前 value 存储格式

字段值以 JSON 字符串 存入文档 Item(fieldtype = VALUE_TYPE_TEXT)。
当前运行时(o_map.vue)实际使用的是 标记点数组(语义上对应 MultiPoint),而非下方规划中的 GeoJSON 结构:

[
  {
    "id": 1,
    "lng": 113.27,
    "lat": 23.13,
    "address": "广东省广州市天河区...",
    "title": "标记标题",
    "detail": "标记详细内容",
    "isShow": true
  }
]
字段 类型 说明
id Number 标记唯一 ID,前端自增
lng Number 经度(WGS84 / GCJ-02,取决于地图 API)
lat Number 纬度
address String 逆地理编码地址
title String 用户填写的标记标题
detail String 用户填写的标记内容
isShow Boolean 是否显示

空值或未标记时存储为空字符串 "" 或空数组 []

目标 value 存储格式(规划)

valueType 区分五类几何数据:单点、多点、路径(线)、矩形范围、多边形区域。
以下为 规划中的统一 JSON 结构,由字段专有属性 valueType 指定;MapField 后端已支持 valueType 定义与下发,o-map 组件尚未按类型读写,迁移时需兼容上方当前标记点数组格式。

valueType JSON 根字段 type 说明
Point "Point" 单个坐标点
MultiPoint "MultiPoint" 多个坐标点集合
LineString "LineString" 有序路径点列
Bounds "Bounds" min_lng / min_lat / max_lng / max_lat 矩形
Polygon "Polygon" 多边形顶点序列(首尾自然连线闭合,不重复存储闭合点)

基础几何定义(统一标准)

采用 WGS84 经纬度(lng 经度,lat 纬度),统一单位:十进制小数。

  • 单点:Point(lng, lat)
  • 多点:无序或有序点集合 MultiPoint[(lng1,lat1),(lng2,lat2)...]
  • 路径 / 轨迹:有序点集合 LineString[(lng1,lat1),(lng2,lat2)...]
  • 地图范围:
  • 矩形边界(可视框):min_lng, min_lat, max_lng, max_lat
  • 多边形区域(行政 / 围栏):Polygon[(lng,lat)...],按顺序连线,最后一个点与第一个点自然闭合

坐标点/点位 Point(单点)

通用结构体:

{
  "type": "Point",
  "data": {
    "lng": 113.27,
    "lat": 23.13,
    "extra": {}
  }
}

extra 为扩展字段,可存放高度、速度、地址等。

多点 MultiPoint(多标记点)

多个独立坐标点,每点可携带独立扩展信息;与当前运行时标记点数组语义一致:

{
  "type": "MultiPoint",
  "data": {
    "points": [
      {
        "id": 1,
        "lng": 113.27,
        "lat": 23.13,
        "extra": {
          "address": "广东省广州市天河区...",
          "title": "标记标题",
          "detail": "标记详细内容",
          "isShow": true
        }
      },
      {
        "id": 2,
        "lng": 113.28,
        "lat": 23.14,
        "extra": {
          "address": "广东省广州市越秀区...",
          "title": "标记标题 2",
          "detail": "标记详细内容 2",
          "isShow": true
        }
      }
    ]
  }
}
字段 类型 说明
id Number 标记唯一 ID,前端自增
lng Number 经度
lat Number 纬度
extra.address String 逆地理编码地址
extra.title String 用户填写的标记标题
extra.detail String 用户填写的标记内容
extra.isShow Boolean 是否显示

points 为空数组时表示无标记。

地图路径 LineString(轨迹 / 路线 / 道路)

路径是有序连续点,必须保留顺序,支持分段、里程、时间序列:

{
  "type": "LineString",
  "data": {
    "points": [
      {
        "lng": 113.27,
        "lat": 23.13,
        "time": 1786000000
      },
      {
        "lng": 113.28,
        "lat": 23.14,
        "time": 1786000010
      }
    ],
    "distance": 1250.3,
    "start_point": {
      "lng": 113.27,
      "lat": 23.13
    },
    "end_point": {
      "lng": 113.28,
      "lat": 23.14
    },
    "bounds": {
      "min_lng": 113.27,
      "min_lat": 23.13,
      "max_lng": 113.28,
      "max_lat": 23.14
    },
    "extra": {}
  }
}
  • distance:总长度(米)
  • bounds:路径自身包围盒
  • extra:路况、速度、路线类型等

矩形可视范围 Bounds

{
  "type": "Bounds",
  "data": {
    "min_lng": 113.26,
    "min_lat": 23.11,
    "max_lng": 113.30,
    "max_lat": 23.16,
    "zoom": 12,
    "source": "前端视口/区域围栏"
  }
}

多边形区域 Polygon(不规则围栏、行政区)

{
  "type": "Polygon",
  "data": {
    "points": [
      [113.26, 23.11],
      [113.30, 23.11],
      [113.30, 23.16],
      [113.26, 23.16]
    ],
    "bounds": {
      "min_lng": 113.26,
      "min_lat": 23.11,
      "max_lng": 113.30,
      "max_lat": 23.16
    }
  }
}

多边形 points 按顺序存储顶点,不在末尾重复第一个点;地图渲染与几何计算时,最后一个点与第一个点自动连线形成闭合区域。bounds 为多边形外接矩形,用于快速过滤。

当前格式 → 目标格式映射

当前字段 valueType 目标结构
标记点数组 [{lng, lat, address, title, detail}] MultiPoint { "type": "MultiPoint", "data": { "points": [{ "id", "lng", "lat", "extra": { "address", "title", "detail", "isShow" } }] } }
单点选点(规划) Point { "type": "Point", "data": { "lng", "lat", "extra": { "address", "title", "detail" } } }
无路径支持 LineString 见上文 LineString 结构
无视口/围栏 Bounds / Polygon 见上文 Bounds / Polygon 结构

已知限制与注意事项

  • 列表视图不支持toGridHtmlText 直接返回不支持提示,视图中无法展示地图字段内容
  • 打印/PDF:打印模式不渲染地图,PDF 仅显示地图图标
  • 移动端只读/屏蔽:移动端 o-map 在只读和屏蔽状态下不渲染地图区域
  • 格式演进o-map PC 端已按 valueType 读写;移动端尚未同步;旧版标记点数组读取时兼容为 MultiPoint