跳转至

地图视图(MapView)设计方案

地图视图用于在模块中以地图方式展示表单数据:将视图列中映射的地址字段地理编码后在地图上打点,或读取 MapField 坐标/几何数据直接渲染;点击标记可查看标题、地址、内容等信息,并支持删除文档等视图操作。

层次 实现位置
后端 / Java cn.myapps.core.common.model.view.MapViewobpm-core/.../view/MapView.java
cn.myapps.core.common.model.view.type.MapType(视图类型实现,数据加载与列映射)
cn.myapps.core.common.model.view.dto.builder.MapViewBuilder(保存时写入专有属性)
视图设计器 ViewBasic.vueViewData.vueViewCity.vueobpm-designer-vue3/src/components/Modules/
config.jsmapDisplayTypeOptions()mapDisplayTypeValueTypeMapmapData
前端运行时(PC) view_mapview.vueobpm-runtime-web/portal/vue3/src/components/view/view_mapview.vue
view_delegate.vue(按 simpleClassName == 'MapView' 路由)
前端运行时(移动端) view_mapview.vueobpm-runtime-mobile-vue3/src/components/view_mapview.vue

本文档 地图视图 对应后端 ViewConstant.VIEW_TYPE_MAP0x0000012,十进制 18);设计器 intValue == 18 与之一致。


后端定义(Java)

MapView 模型

MapView 继承 AbstractView,通过 JAXB 序列化为 XML 根元素 <MapView>,JSON 序列化时忽略空字段(@JsonInclude(NON_EMPTY))。

视图类型常量:ViewConstant.VIEW_TYPE_MAP = 0x0000012(十进制 18)。

专有属性

属性 类型 默认值 说明
isSateMap boolean false 是否需要卫星地图展示(设计器可配置;PC 运行时目前由前端按钮切换,未直接读取该字段)
defaultCenterAddress String "" 地图打开时的默认中心地址(整段文本,如「广东省广州市天河区」)
level String "4"(getter 兜底) 打开地图时的默认缩放级别(1–18),设计器 ViewCity 页签配置
mapType String 地图引擎类型,如 baidumaparcgis
mapDisplayType String PointMarker 展示类型,决定数据在地图上的渲染方式
mapDataSourceField String "" 地图数据源字段:数据来源表单中 MapField 的字段名(name),用于读取 GeoJSON 几何数据
mapDisplayType 与 MapField.valueType 匹配规则

设计器加载字段列表时,先取表单中 formField == MapFieldvalueType 属于 Point / MultiPoint / LineString / Bounds / Polygon 的字段,再按当前 mapDisplayType 筛选:

mapDisplayType 允许的 valueType
PointMarker PointMultiPoint
MarkerCluster PointMultiPoint
Heatmap PointMultiPoint
MultiLineString LineString
MultiPolygon PolygonBounds

点类型展示(基础标记 / 聚合点 / 热力图)mapDataSourceField 均支持 PointMultiPointPoint 每条文档对应一个坐标;MultiPoint 每条文档可含多个坐标,运行时展开为多个地图点(基础标记为多个 T.Marker,聚合点参与聚合,热力图参与密度计算)。

面类型展示(多面)mapDataSourceField 支持 PolygonBoundsPolygon 为不规则多边形顶点;Bounds 为矩形范围,运行时通过 boundsToPolygonPoints 转为四顶点矩形并以 T.Polygon 绘制。设计器筛选见 config.jsmapDisplayTypeValueTypeMap

字段列表接口:GET /designer/api/designtime/applications/{appId}/modules/forms/{formId}/fields(MapField 额外返回 formFieldvalueType)。

mapDisplayType 取值说明(点类型)
mapDisplayType 含义 典型场景
PointMarker 基础标记 普通图标点位、POI、设备点位、人员定位;支持自定义图标、弹窗、文字标注
MarkerCluster 聚合点 海量点位自动聚合,缩放地图时拆分;百万级点位必备
Heatmap 热力图 基于大量点密度渲染渐变色块,展示人流、车辆分布、点位密集度
mapDisplayType 取值说明(线类型)
mapDisplayType 含义 典型场景
MultiLineString 多段复合线 多条不连续路线合并展示(多条道路、分段轨迹)
mapDisplayType 取值说明(面类型)
mapDisplayType 含义 典型场景
MultiPolygon 多面 包含多个不相连区域(如海岛、分散地块)

默认中心地址读写规则

defaultCenterAddress整段地址字符串(设计器 ViewCity 页签使用 el-input 录入,示例:广东省广州市天河区)。

规则 说明
setter 过滤空值与占位符 "请选择",trim 后存储;blank 存 ""
getter 优先返回 defaultCenterAddress;若为空则 兼容旧 XML,拼接 legacy 字段 country + province + city + town
保存 MapViewBuilder 写入 defaultCenterAddress,并清空 legacy 四级地址字段

level 的 getter:若未配置则返回 "4"

Legacy 字段country / province / city / town)仍保留于 XML 反序列化,供旧视图升级读取;新配置统一使用 defaultCenterAddress

继承自 AbstractView 的常用属性

属性 说明
name / description 视图名称与描述
formId / dataSourceId 数据来源表单
columns 视图列定义(含映射字段 mappingField
relatedMap 列映射 JSON,键 mapview 存放地图列映射
filterScript / searchFormId 筛选脚本与查询表单
activitys / events 视图操作按钮与事件
showTotalRow 是否显示总记录数
readonly 视图只读
pagination / pageLines 分页配置(地图视图运行时由 MapType 屏蔽分页)
openType / displayType / templateForm 打开方式与数据呈现模式
styleId / orderno 样式库与排序号

视图类型(MapType)

MapType 实现 ViewType 接口,负责地图视图的数据加载与列映射约定。

列映射字段

mappingField 含义 说明
mapcolumn 地图控件列 默认关键字段(DEFAULT_KEY_FIELDS
titlecolumn 地图标题列 标记信息窗口标题
addresscolumn 地图详细地址列 运行时地理编码与打点的核心字段(兼容旧配置)
detailcolumn 地图内容列 标记信息窗口详细内容

列映射通过 getColumnMapping() / getColumnMap()view.columnsrelatedMap(键 "mapview")解析。

MapType.addField(key, name) 支持动态扩展映射字段到 ALL_FIELDS

分页行为

MapType.getViewDatas(...) 重载父类方法,不传递分页参数,直接调用 EditMode.getDataPackage 获取全部符合条件的数据,即地图视图在运行时一次性加载数据、不分页展示。

构造器(MapViewBuilder)

保存视图时,MapViewBuilder.buildViewSpecialPortal() 将 ViewCity 页签的 defaultCenterAddresslevel 写入 MapView;若 defaultCenterAddress 为空则尝试从 legacy 四级地址拼接。新保存会清空 legacy 字段。


设计器配置

视图设计器入口为模块详情页视图编辑;地图视图对应 intValue == 18。视图 XML 根标签名为 MapView

基本信息(ViewBasic.vue,intValue == 18

属性 默认值 说明
mapType tianditu 地图插件:目前仅 tianditu(天地图);标注「仅 PC 端」
mapDisplayType PointMarker 地图展示类型,分组下拉:点类型 / 线类型 / 面类型(见上文 mapDisplayType 取值说明)
isSateMap false 是否允许卫星地图展示

下拉选项定义于 config.jsmapDisplayTypeOptions(),按点 / 线 / 面分组展示;保存时随视图 XML 一并写入 MapView.mapDisplayType

数据页签(ViewData.vue,地图视图 intValue == 18

位于「数据来源表单」(relatedForm)下方:

属性 默认值 说明
mapDataSourceField 地图数据源字段:根据已选 relatedForm 调用 fields 接口加载 MapField 列表,再按「基本」页签中的 mapDisplayType 筛选

地图数据源字段通过 FormApi.getFieldData(appId, relatedForm) 加载,筛选逻辑见 config.jsmapDisplayTypeValueTypeMap;存字段 nameMapView.mapDataSourceField。切换数据来源表单或 mapDisplayType 时自动刷新选项并清除不匹配的旧值。

默认加载城市(ViewCity.vue 页签)

属性 默认值 说明
defaultCenterAddress 默认中心地址,el-input 录入整段文本(如 广东省广州市天河区
level '4' 默认缩放级别(天地图 zoom,1–18);保存至 MapView.level

打开已有视图时,若 XML 仅有 legacy 四级地址而无 defaultCenterAddress,设计器会自动拼接为整段文本展示。有视图数据且成功解析坐标时,运行时优先通过 setMapViewport 自适应全览,不受 level 限制。

视图列映射(config.js → mapData)

设计器批量创建列时,地图视图可选映射:

标签 mappingField
地图标题 titlecolumn
地图详细地址 addresscolumn
地图内容 detailcolumn

前端运行时(PC)

组件路由

view_delegate.vue 根据后端 simpleClassName == 'MapView' 渲染 view_mapview 组件。

地图引擎

  • PC 端:天地图 API 4.0(矢量 vec / 影像 img),mapType == 'arcgis' 时不初始化地图组件
  • 设计器中的 mapType 选项仍为 baidumap / arcgis,PC 运行时实际已切换为天地图(与地图字段 MapField 情况类似)

初始视口

加载数据前,前端读取 view.defaultCenterAddress(或兼容拼接 legacy 地址)作为关键字,调用天地图 geocoder API 定位初始中心;若无默认地址则使用固定默认坐标(广州附近)及 view.level 作为 zoom。

view.level 在设计器 ViewCity 页签配置(默认 '4',范围 1–18)。PC 前端 getData 在定位默认地址时使用 view.level 作为初始 zoom;无默认地址时同样回退至 view.level(无效值时兜底 4)。有视图数据且解析出坐标后,通过 setMapViewport 自动计算包围盒与缩放级别(多点优先调用天地图 map.setViewport),覆盖初始 level

自适应缩放按钮

PC 地图左上角 T.Control.Zoom(+ / −)控件正下方 提供 「自适应缩放」 按钮(map-fit-viewport-btn):

说明
位置 地图容器内绝对定位,left: 10px,紧贴缩放控件下方(top: 86px,与天地图默认 Zoom 控件对齐)
显示条件 当前视图已成功解析出至少 1 个坐标点时显示(mapFitLocations.length > 0
点击行为 调用 fitMapToViewData()setMapViewport(mapFitLocations),将地图中心与缩放级别调整为包含全部已加载要素
数据来源 getData 加载完成后缓存 validLocations(标记 / 聚合点 / 热力点 / 折线顶点 / 多边形顶点等)至 mapFitLocations
文案 i18n 键 map_fit_viewport(简体中文:「自适应缩放」);title 提示,按钮为图标样式

数据加载完成时会 自动执行一次 自适应缩放;用户手动平移/缩放后,可再次点击该按钮恢复「全览」视口。

数据加载与打点

  1. 调用 POST /runtime/.../views/{viewId}/documents 获取视图全部文档(MapView 无分页,page_lines = Integer.MAX_VALUE
  2. 每条文档除 items 外,若配置了 mapDataSourceField,后端补充 mapDataItem(MapField 原始值 + 解析后的 lng/lat/extra/parsed
  3. mapDisplayType 分支加载坐标(均已配置 mapDataSourceField 时,数据源字段支持 Point / MultiPoint):
  4. PointMarker:读取全部点位(extractMapDocumentLocations),每个坐标添加 T.Marker 及常驻标签,不做地理编码MultiPoint 同一文档展开为多个标记,点击任一点弹出同一文档的信息窗口
  5. MarkerCluster:读取全部点位,交给天地图 T.MarkerClusterer 聚合展示;缩放级别 ≤ MAP_CLUSTER_MAX_ZOOM 时自动聚合,放大后拆分为单点
  6. Heatmap:读取全部点位,动态加载天地图开源 HeatmapOverlay 插件后渲染热力图层(T.HeatmapOverlay + setDataSet);MultiPoint 展开为多个热力点,默认每点 count: 1
  7. MultiLineString:读取每条文档的 LineString 路径点(extractMapDocumentLinePoints,至少 2 个点),以 T.Polyline 绘制折线;多条文档即地图上多条不连续路线,不做地理编码;点击折线弹出该文档信息窗口
  8. MultiPolygon:读取每条文档的 Polygon 顶点或 Bounds 矩形(extractMapDocumentPolygonPointsBounds 转为四顶点矩形,至少 3 个顶点),以 T.Polygon 绘制闭合区域;多条文档即地图上多个不相连多边形,不做地理编码;点击多边形弹出该文档信息窗口
  9. 其他情况(兼容旧配置):遍历 mappingField == "addresscolumn" 的列,对地址文本做地理编码后打点(MarkerCluster / Heatmap 模式下同样走对应渲染器)
  10. PointMarker:在 T.Marker 上方追加 T.Label,按视图列定义常驻展示文档摘要(见「地图标记标签」);MarkerCluster / Heatmap / MultiLineString / MultiPolygon 不显示常驻标签
  11. 点击标记(或聚合拆分后的单点、折线、多边形)弹出 T.InfoWindow,展示各列值;非只读模式下可删除文档(Heatmap 模式无单点标记,不提供点击信息窗口

MarkerCluster 运行时参数(view_mapview.vue 顶部常量)

常量 默认值 说明
MAP_CLUSTER_GRID_SIZE 60 聚合网格像素大小,越小聚合越细
MAP_CLUSTER_MAX_ZOOM 18 最大聚合缩放级别,超过后显示单点
MAP_CLUSTER_STYLES 天地图 heart 图标 不同数量区间的聚合点样式

Heatmap 运行时参数(view_mapview.vue 顶部常量)

常量 默认值 说明
MAP_HEATMAP_RADIUS 30 每个热力点影响半径(像素)
MAP_HEATMAP_MAX_COUNT 0 setDataSetmax0 表示按数据自动取最大 count
MAP_HEATMAP_GRADIENT 黄→橙→红 热力强度渐变色

热力图依赖天地图开源脚本 HeatmapOverlay.min.js(内置 h337 + T.HeatmapOverlay),由 tianditu_heatmap.js 在首次渲染时动态加载:优先本地 public/static/js/tianditu/HeatmapOverlay.min.js,失败时回退 https://lbs.tianditu.gov.cn/api/js4.0/opensource/openlibrary/HeatmapOverlay.min.js(勿使用 api.tianditu.gov.cn 同路径,该地址 404)。每个点位默认 count: 1;同一文档的 MultiPoint 会展开为多个热力点。

MultiLineString 运行时参数(view_mapview.vue 顶部常量)

常量 默认值 说明
MAP_POLYLINE_COLOR #3388ff 折线颜色(与 MapField o_map.vue LineString 一致)
MAP_POLYLINE_WEIGHT 4 折线宽度(像素)
MAP_POLYLINE_OPACITY 0.8 折线透明度

mapDataSourceField 须绑定表单中 valueType = LineString 的 MapField;每条视图文档对应一条折线,路径点不足 2 个时跳过该文档。

MultiPolygon 运行时参数(view_mapview.vue 顶部常量)

常量 默认值 说明
MAP_POLYGON_COLOR #3388ff 多边形边框颜色(与 MapField o_map.vue Polygon 一致)
MAP_POLYGON_WEIGHT 2 边框宽度(像素)
MAP_POLYGON_OPACITY 0.9 边框透明度
MAP_POLYGON_FILL_COLOR #3388ff 填充颜色
MAP_POLYGON_FILL_OPACITY 0.2 填充透明度

mapDataSourceField 须绑定表单中 valueType = PolygonBounds 的 MapField;Bounds 在运行时转为矩形四顶点后绘制;每条视图文档对应一个多边形,有效顶点不足 3 个时跳过该文档。

mapDataItem 结构(Point / MultiPoint / LineString / Polygon / Bounds)

字段 说明
name MapField 字段名(同 mapDataSourceField
formField 固定 MapField
valueType MapField 存储类型:PointMultiPointLineStringPolygonBounds
value / showValue 文档 Item 原始 JSON 字符串
lng / lat 解析后的坐标(WGS84 十进制);MultiPoint 时多为首点摘要,全部点位由 extractMapDocumentLocationsvalue / parsed 展开
extra 扩展信息(address / title / detail / isShow 等)
parsed 完整解析后的 JSON 对象(GeoJSON 结构时存在)

地图标记标签(视图列数据)

mapDisplayType = PointMarker 时,除标记图标外,在标记点上方 常驻显示文字标签(天地图 T.Label 覆盖物),用于展示该条文档的视图列数据。交互与样式参考 MapField 的 o_map.vuebuildMarkerLabelHtml / addMarkerLabel),数据取值与格式化 对齐列表视图 view_listview.vueview_listview_cell.vue

参与列与排版

view.columns 顺序遍历(与列表视图列顺序一致),规则如下:

规则 说明
参与列 列类型为 COLUMN_TYPE_FIELD / COLUMN_TYPE_SCRIPT,且该文档对应 Item 有可读展示值
排除列 hiddenColumn == trueCOLUMN_TYPE_OPERATE / COLUMN_TYPE_LOGO / COLUMN_TYPE_ROWNUMformField == MapField(坐标已由 mapDataSourceField 承担,标签中不再重复展示 JSON)
首行(加粗) mappingField == titlecolumn 的列;未配置时取参与列中的第一列
次行 mappingField == detailcolumn 的列(有值时追加,样式为副文本)
其余行 其余参与列按列顺序追加;同一列仅出现一次(已在首/次行展示的列不再重复)

标签 HTML 结构复用 MapField 样式类:marker-label-wrap(容器)、marker-label(首行加粗)、marker-detail(其余行)。锚点位于标签底边中点(setAnchorPer([0.5, 1])),相对标记点的像素偏移由 view_mapview.vue 顶部常量 MAP_MARKER_LABEL_OFFSET_X / MAP_MARKER_LABEL_OFFSET_Y 控制(默认 0 / -70,X 向右、Y 向下为正)。

取值与格式化(对齐 view_listview_cell.vue)

地图视图拿到的文档结构与列表视图相同(doc.items[column.id])。渲染标签前,应将文档整理为与 view_listview 表格行一致的结构(row[column.id] = doc.items[column.id]),再按 view_listview_cell.vue 的规则取 纯文本展示值

维度 规则
基础取值 getCellValue(row, column)showType == '01' 时优先 showValue,否则在 options 中匹配选项文案;默认取 item.value
formatType number / currency / simple 及默认分支,与列表单元格相同(含 displayTypedisplayLength、小数位、货币符号等)
columnField 部门/用户字段取路径最后一段(; 分隔多条);附件/图片/在线拍照等 仅输出文件名或地址类摘要,不嵌入 <img>HTMLEditorField 剥离 HTML 标签后取纯文本
列样式 标签为地图覆盖物,仅输出文本;groundColor / color / fontSize / showAsLabel 等列样式属性 不应用于 T.Label(列表视图中 showAsLabel 主要影响单元格背景,见 view_listview_cell.vue 外层 :style
空值 格式化结果为空字符串的列跳过,不占行

建议将上述逻辑抽取为与 view_listview_cell.vue 共用的 单元格文本化函数(如 getViewCellDisplayText(row, column)),供地图标签与信息窗口共用,避免地图视图单独维护一套列解析。

生命周期
  1. addMarkerToMap 添加 T.Marker 后,调用 addMapMarkerLabel(doc, location) 追加 T.Label
  2. restoreMapBaseLayers 清除覆盖物时,同步清除全部标签引用
  3. 缩放 / 平移地图时标签随坐标附着,无需单独重算(与 MapField 一致)

点击标记仍打开 T.InfoWindow;信息窗口内容亦按相同列规则输出(getViewCellDisplayText)。地址列若字段名为 addr_list,信息窗口显示为「地址:xxx」。

用户操作

功能 说明
地图 / 卫星 切换矢量底图与影像底图(normalMap / mixMap
自适应缩放 左上角 Zoom 控件下方按钮,重新 fit 至全部已加载要素(fitMapToViewData
显示/隐藏街道名 切换标注图层 cva/cia
删除 标记信息窗口内删除,调用 batchRemoveDocuments

只读判定

view.readonly 或包含元素权限为只读/屏蔽时,isReadonly = true,信息窗口不显示删除按钮。


前端运行时(移动端)

移动端使用独立组件 obpm-runtime-mobile-vue3/src/components/view_mapview.vue

维度 说明
地图引擎 天地图(EPSG:4326
只读判定 view.readonly 为 true 时不显示删除按钮
列索引 getData 中通过 j == 1 硬编码取第二列作为地址,应改为与 PC 一致的 mappingField == "addresscolumn" 判断(见「已知限制」)

与地图字段(MapField)的关系

维度 MapField(表单字段) MapView(视图)
用途 单条文档内编辑/展示地图标记 多条文档在地图上聚合展示
值存储 文档 Item,JSON 标记点数组 不存储地图值;读取各列 Item
核心列 mapDataSourceField(MapField 坐标)或 addresscolumn(地址地理编码,兼容旧配置)
列表视图 不支持网格展示 本身就是地图展示
地图引擎 PC 天地图 PC/移动 天地图

配置 mapDisplayType基础标记 / 聚合点 / 热力图 且指定 mapDataSourceField 时,运行时直接读取 MapField 的 PointMultiPoint 坐标;多段复合线 模式读取 LineString 路径;多面 模式读取 Polygon 顶点或 Bounds 矩形;未配置时仍可通过 addresscolumn 地址列地理编码打点(兼容旧视图,线/面类型不适用)。


运行时 API 汇总

方法 路径 / 接口 用途
GET /designer/api/designtime/applications/{appId}/modules/forms/{formId}/fields 设计器加载 MapField 列表(含 formFieldvalueType
POST /runtime/.../views/{viewId}/documents 加载视图全部文档(无分页)
batchRemoveDocuments 信息窗口内删除文档

已知限制与注意事项

  • ArcGIS 分支mapType == 'arcgis' 时 PC 端跳过地图初始化,需单独实现
  • isSateMap:后端与设计器可配置,PC 运行时卫星切换由前端按钮控制
  • 地理编码依赖:未配置 mapDataSourceField 时仍依赖 addresscolumn 文本地址,编码失败则该条数据无标记;PointMarker + mapDataSourceField 模式不依赖地理编码
  • 无分页MapType 一次性加载全部数据,数据量大时可能影响性能
  • 移动端列索引:移动版 getData 中通过 j == 1 硬编码取第二列作为地址,应改为与 PC 一致的 mappingField == "addresscolumn" 判断
  • 打印/PDF:地图视图无专用打印渲染,遵循视图通用行为