bigmap-plugin

基于 BigMap/Cesium (bmgl) 的工程化地图插件。独立 NPM 包,内置全部外部 JS 库、样式与资源,安装即用,支持 2D/3D 地图、点位管理、图形绘制、图层与弹窗管理。
689
Install
npm install bigmap-plugin
Latest Version:1.0.11
Vue:3
License:MIT
Last Updated:Oct 20, 2026
Links: npm
Maintainer: mylee7532

bigmap-plugin

基于 bigemap / bmgl 的地图插件,开箱即用的 Vue3 地图组件。

高性能点位渲染(10 万级)· 交互式绘制 · 实体绘制 · 轨迹回放 · 遮罩反选 · KML 数据加载 · 天气特效 · 3D 自动光源 · 生产底图切换


目录


1. 安装

npm install bigmap-plugin
# 或
yarn add bigmap-plugin

说明:地图运行时所需的外部库(bigemap-gl、plot、circleWave 等)已作为本地资源随包发布在 dist/libs,开发环境默认按 /libs 前缀从应用本地加载,无需额外接入 CDN。


2. 引入组件(快速开始)

2.1 引入入口与样式

在 main.ts 中引入组件统一样式:

// main.ts
import { createApp } from 'vue'
import App from './App.vue'
import 'bigmap-plugin/style.css' // 引入组件统一样式(必须)

createApp(App).mount('#app')

注意:serverUrl(地图资源/瓦片服务器地址)为必填,不配置将无法加载地图。开发环境还需通过构建工具把包内的 dist/libs 静态映射到 /libs(详见 常见问题 FAQ)。

2.2 使用 MapContainer 组件

MapContainer 是唯一需要使用的根组件,一个组件即可加载完整地图与交互面板。

<template>
  <MapContainer
    ref="mapRef"
    :config="mapConfig"
    theme="dark"
    @expose="onExpose"
    @ready="onReady"
  />
</template>

<script setup lang="ts">
import { ref } from 'vue'
import { MapContainer, type MapApi } from 'bigmap-plugin'

const mapConfig = {
  serverUrl: 'http://你的地图服务器:3000', // 必填:地图资源/瓦片服务器地址
  containerId: 'map-container',           // 容器 id(默认 bigmap-container)
  position: { lng: 104.03, lat: 30.48, height: 20000 }, // 初始视角
  mapType: '3d',                          // 初始地图类型:'3d' | '2d'
  showSearch: true,                       // 显示顶部搜索栏
  showControls: true,                     // 显示右侧工具栏
}

const api = ref<MapApi | null>(null)

/** expose 回调:获取地图实例 API */
const onExpose = (mapApi: MapApi) => {
  api.value = mapApi
}

const onReady = () => {
  console.log('地图就绪')
}
</script>

2.3 获取地图实例 MapApi

MapContainer 会把完整的地图实例 API(MapApi)暴露出来,有两种获取方式:

方式一:@expose 事件回调(推荐)

<MapContainer @expose="(mapApi) => (api = mapApi)" />

方式二:模板 ref

<MapContainer ref="mapRef" />
const mapRef = ref()
const api = mapRef.value // expose 完成后访问,即等于 MapApi

拿到 api 后即可调用所有功能,例如:

api.loadPoints(points, undefined, undefined, 'replace') // 加载点位
api.setView(104.03, 30.48, 20000)                       // 飞行定位
api.startDrawing('rectangle')                           // 开始交互式绘制矩形

下文所有功能示例均基于该 api(MapApi)。


3. 配置参数说明

配置优先级(由低到高):默认值 → config 对象 → 显式 props。即组件上逐个传入的 props 会覆盖 config 中的同名项,未配置的项自动回落默认值。

3.1 组件 props 一览

类型 说明
config 统一配置对象,集中管理地图配置
下表其余字段 均既可放入 config 传入,也可作为独立 props 传入(props 优先级更高)
props 类型 默认值 是否必填 说明
config Partial<MapConfig> undefined 否 统一配置对象,见 3.2
theme 'dark' | 'light' 'dark' 否 主题(暗色 / 浅色),作用于全部 UI
popupConfig PopupDisplayConfig undefined 否 点位弹窗展示配置(字段列表 / 主题色),见 4.5
containerId string 'bigmap-container' 否 地图容器 DOM id
serverUrl string 无 是 地图资源 / 瓦片服务器地址
accessToken string 无 否 地图服务访问令牌:配置后写入 bmgl.Config.accessToken,用于底图 / 瓦片鉴权
libsUrl string '/libs' 否 本地库路径前缀
baseLayers string[] ['bigemap.dc-satellite', 'bigemap.dc-street'] 否 底图图层 mapId 列表(按数组顺序自下而上叠加):配置后按配置加载,未配置才用默认底图;传空数组表示不叠加底图图层
position { lng, lat, height } { lng:104.03, lat:30.48, height:20000 } 否 初始相机位置
mapType '2d' | '3d' '3d' 否 初始地图类型
showSearch boolean false 否 是否显示顶部搜索栏
showControls boolean true 否 是否显示右侧工具栏(整体显隐)
showDeleteControls boolean true 否 是否显示"清除绘制"按钮
showStatus boolean false 否 是否显示底部 FPS 状态组件
tools ToolItem[] 内置默认工具集 否 右侧工具栏绘制工具列表等,见 3.2.3
searchDebounceTime number 300 否 搜索输入防抖延迟(ms)
wmtsUrlProvider () => Promise<string> undefined 否 生产底图 WMTS URL 提供器:返回带令牌的 WMTS 请求地址,优先级高于 geoserver,见 3.2.1
geoserver GeoServerSourceConfig undefined 否 生产地图(GeoServer)源配置:提供 baseUrl / layer / token,配置后启用物探/生产底图切换,见 3.2.1
contourConfig Partial<ContourConfig> 内置默认(等高距 150m / 线宽 2px / 内置色带) 否 彩色等高线显示配置(仅 3D),见 4.8
lightingConfig boolean false 否 是否开启 3D 自动光源(按系统时间)

建议:除 theme / popupConfig 外,其余配置统一放入 config 集中管理,代码更整洁。

底图图层(baseLayers 与 mapId 的分工):mapId 是引擎(Viewer)自带的基础影像,baseLayers 是初始化时叠加在其上的底图图层列表。两者都会随「影像 / 生产底图」切换按钮一起生效:切回影像底图时按 baseLayers 重新加载。若只配 mapId、未配 baseLayers,默认的卫星影像 + 街道地名图层会盖在基础影像之上。

3.2 config 统一配置对象

config 的类型为 Partial<MapConfig>,除 3.1 中可独立传入的字段外,还额外支持以下 config 独有字段:

字段 类型 默认值 说明
mapId string 'bigemap.cebjohn0' 基础影像图 mapId
terrainId string 'bigemap.dc-terrain' 地形图 mapId
showLoading boolean 依赖加载态自动管理 是否显示加载动画
extraLibs Record<string, Partial<LibConfig>> {} 自定义扩展库配置(覆盖默认库或新增依赖库,无需改包内代码),见 3.2.2
3.2.1 生产底图切换(wmtsUrlProvider / geoserver)

功能简介:在基础影像图之外,叠加/切换「生产(物探)底图」。开启后,地图右侧工具栏出现生产底图切换按钮。插件核心不耦合业务鉴权:令牌由业务方获取后提供。

启用与优先级规则:

  1. 先判断自定义 wmtsUrlProvider(返回带令牌的 WMTS URL),存在则直接采用;
  2. 否则若配置了 geoserver 源,插件内置调用 createGeoServerWmtsProvider(geoserver) 生成提供器;
  3. 两者均未配置 → 不启用生产底图切换(按钮不显示,地图照常加载)。

wmtsUrlProvider(() => Promise<string>)说明:

说明项 内容
作用 每次切换生产底图时被调用,返回可直接请求的 WMTS 瓦片 URL;令牌过期可在此动态换取新令牌
返回 Promise<string>:完整 WMTS 地址(含 {TileMatrix} / {TileCol} / {TileRow} 占位符与令牌参数)
适用场景 令牌需实时从登录态/后端获取、或使用自定义鉴权体系

GeoServerSourceConfig 参数表:

字段 类型 默认值 必填 说明
baseUrl string — 是 WMTS 服务地址,形如 http://host:port/geoMap/geoserver/gwc/service/wmts
layer string 'PostGIS:dommap' 否 WMTS 图层名
token string 无 是 访问令牌:由业务方在调用侧获取后传入(与地图插件解耦)

token 与 wmtsUrlProvider 的关系:若已提供 wmtsUrlProvider,则 token 不再参与取址;仅当走 geoserver 内置提供器时,token 会被拼进 WMTS URL(geo-token 参数)。

示例一:静态配置 geoserver(内置提供器)

<MapContainer
  :config="{
    serverUrl: 'http://你的地图服务器:3000',
    geoserver: {
      baseUrl: 'http://10.10.0.8:8080/geoMap/geoserver/gwc/service/wmts',
      layer: 'PostGIS:dommap',
      token: '业务侧获取的令牌', // 必须
    },
  }"
/>

示例二:自定义 wmtsUrlProvider(动态取令牌)

const mapConfig = {
  serverUrl: 'http://你的地图服务器:3000',
  // 每次切换生产底图时动态换取令牌并返回带令牌的 WMTS 地址
  wmtsUrlProvider: async () => {
    const token = await fetchMyToken()
    return (
      `http://10.10.0.8:8080/geoMap/geoserver/gwc/service/wmts` +
      `?layer=PostGIS:dommap&geo-token=${token}&style=&tilematrixset=EPSG%3A3857` +
      `&Service=WMTS&Request=GetTile&Version=1.0.0&Format=image%2Fvnd.jpeg-png` +
      `&TileMatrix=EPSG%3A3857%3A{TileMatrix}&TileCol={TileCol}&TileRow={TileRow}`
    )
  },
}

进阶:包内导出 createGeoServerWmtsProvider(config) 与 buildGeoServerWmtsUrl(config, token),可基于静态配置快速生成提供器 / 拼接地址,无需手写 URL 模板。参考 demo 的 utils/geoserver.ts。

3.2.2 扩展库配置(extraLibs / LibConfig)

功能简介:插件预置了加载地图所需的外部库脚本(bigemap-gl、plot、circleWave 等,见 2.1)。通过 extraLibs 可按库键名覆盖默认库的路径 / 依赖,或新增自有依赖库(如自定义绘图插件),无需修改包内代码。

LibConfig 参数表:

字段 类型 必填 说明
name string 否 库显示名称
path string 是 资源路径:以 /libs/ 开头 → 走 libsUrl;以 / 开头 → 拼接到 serverUrl;其余作完整 URL
isCss boolean 否 是否为 CSS 资源
dependencies string[] 否 依赖的库键名(先加载依赖再加载自身)
const mapConfig = {
  serverUrl: 'http://你的地图服务器:3000',
  extraLibs: {
    'bmgl-plot': { path: '/custom/bmgl-plot.min.js' },        // 覆盖预置库
    'my-plugin': {                                             // 新增自定义库
      name: '我的插件',
      path: '/libs/my-plugin.js',
      dependencies: ['bigemap-3d'],
    },
  },
}
3.2.3 工具栏工具列表(tools / ToolItem)

功能简介:控制右侧工具栏中可用的交互式绘制工具。默认提供 polygon / rectangle / circle / polyline / area / ruler / azimuth / triangle 全量工具;传入 tools 可自定义顺序与范围。

ToolItem 参数表:

字段 类型 必填 说明
icon DrawType 是 绘制工具类型(polygon / rectangle / circle / polyline / area / ruler / azimuth / triangle)
name string 是 工具名称
size number 否 图标尺寸(px)
const mapConfig = {
  serverUrl: 'http://你的地图服务器:3000',
  tools: [
    { icon: 'polygon', name: '多边形', size: 20 },
    { icon: 'circle', name: '圆形', size: 20 },
    { icon: 'ruler', name: '标尺', size: 20 },
  ],
}

3.3 组件事件

MapContainer 通过 @事件名 监听以下事件:

事件 回调参数 触发时机
init — 地图初始化完成
ready — 地图就绪(渲染稳定后触发,晚于 init)
error Error 初始化失败
expose MapApi 暴露地图实例 API
draw-end DrawEventData 绘制 / 编辑图形完成
draw-delete DrawEventData 删除图形
draw-clear DrawEventData 清空绘制图形
point-click PointData 点击点位
clear-button-click — 点击"清除绘制"按钮
clear-draw — 废弃(v2.0 移除),请改用 clear-button-click
<MapContainer
  @expose="onExpose"
  @draw-end="(e) => console.log('绘制结束', e)"
  @point-click="(p) => console.log('点击点位', p)"
/>

3.4 插槽

插槽名 说明
default 默认插槽,覆盖在地图上方的自定义内容
utils-right 搜索栏右侧追加工具区域

4. 功能详解

下面每个模块先给出功能简介与它支持的小功能列表,再针对每个小功能提供参数说明与代码示例。示例基于 api(MapApi);标注「Composable」的小功能不在 MapApi 中,需通过对应 composable 使用(见 第 5 节)。

4.1 点位管理

功能简介:基于 BillboardCollection 管理海量点位,支持流式加载、去重追加、更新、清空与检索,可抗 10 万级数据量。

支持的小功能:

加载点位 loadPoints
loadPoints(points, config?, searchFields?, mode?): Promise<void>
参数 类型 默认值 必填 说明
points Record<string, any>[] — 是 点位数组,元素需含经纬度字段(字段名可用 config.fieldMapping 自定义)
config PointConfig 见下表 否 点位尺寸 / 字段映射
searchFields string[] 忽略 否 预留参数,当前版本不使用
mode 'replace' | 'append' 'append' 否 replace:先清空旧点位再加载(同 id 去重替换);append:追加并去重

PointConfig 参数表:

字段 类型 默认值 说明
width number 20 图标宽度(px)
height number 20 图标高度(px)
fieldMapping.lng string 'lng' 经度字段名
fieldMapping.lat string 'lat' 纬度字段名
fieldMapping.altitude string 'altitude' 高程字段名
fieldMapping.id string 'id' 点 id 字段名(用于去重与更新定位)

点位字段约定:

  • icon(必需):图标载荷。基础图标为 SVG data URL(字符串),合成文字图标为 HTMLCanvasElement。图标由数据层用 iconManager 预生成后随点位传入(见 4.2);缺失 icon 的点位会被跳过渲染。
  • id:缺省时自动生成自增 id,但无法保障后续更新定位。建议通过 fieldMapping.id 提供稳定 id。

示例:

const points = [
  { id: 'p1', lng: 104.03, lat: 30.48, icon: icon1 },
  { id: 'p2', lng: 104.05, lat: 30.5, icon: icon2 },
  { id: 'p3', lng: 104.0, lat: 30.45, icon: icon3 },
]
await api.loadPoints(points, { width: 20, height: 20 }, undefined, 'replace')

流式加载最佳实践(后台分批返回,首批 replace,后续 append):

let isFirst = true
for await (const batch of fetchBatches()) {
  await api.loadPoints(batch, undefined, undefined, isFirst ? 'replace' : 'append')
  isFirst = false
}

核心原则:耗时且与数据绑定的工作(图标生成)放在数据层用 iconManager 完成,渲染层只负责 billboard 构建(毫秒级)。这样渲染 500 个点位仅需毫秒级耗时。图标批量生成见 4.2。

更新点位 updatePoints
updatePoints(points): Promise<void>

按 id 更新已存在点位,支持更新以下字段:

字段 说明
icon 更换图标(传重新合成的新 HTMLCanvasElement)
width / height 更新图标尺寸
lng / lat / altitude 更新位置(会同步网格索引,保持搜索一致)
name 更新名称(仅同步缓存;名称视觉显示需配合更新 icon)

示例:

await api.updatePoints([
  { id: 'p1', lng: 104.02, lat: 30.46, icon: newIcon }, // 更新位置 + 图标
  { id: 'p2', width: 40, height: 40 }, // 仅更新尺寸
])
清空点位 clearPoints
await api.clearPoints() // 移除全部点位
文本搜索 searchByText
searchByText(config): PointData[]
参数 类型 默认值 必填 说明
field string | string[] — 是 搜索字段,多字段任一命中即返回
keyword string — 是 搜索关键字(模糊匹配)
limit number 10 否 返回条数上限
caseSensitive boolean false 否 是否区分大小写

示例:

const results = api.searchByText({ field: ['name', 'id'], keyword: '桩号', limit: 20 })
形状搜索 searchByShape
searchByShape(shape): PointData[]
形状 类型 说明
矩形 { type:'rectangle', coordinates: [[lng,lat],...] } 取外接矩形范围,直接按网格筛选
圆形 { type:'circle', center:[lng,lat], radius:米 } 按中心 + 半径精确筛选
多边形 { type:'polygon', coordinates: [[lng,lat],...] } 射线法精确筛选
三角形 { type:'triangle', coordinates: [[lng,lat],...] } 按多边形规则精确筛选

示例:

const inside = api.searchByShape({
  type: 'circle',
  center: [104.03, 30.48],
  radius: 500, // 米
})

4.2 图标批量创建

功能简介:iconManager(单例)负责生成「基础 SVG 图标」与「图标 + 文字」的合成图标,针对海量点位提供批处理 API,自动按「颜色 + 名称」去重缓存,并通过主线程 canvas 直传合成(无 PNG 编码),性能极高。

支持的小功能:

初始化管理器 initialize

在页面初始化时调用一次,注入基础 SVG 模板与默认配置:

import { iconManager } from 'bigmap-plugin'

iconManager.initialize(rawSvg, {
  iconSize: 32,          // 图标尺寸 px(默认 32)
  textConfig: {          // 文字样式(可选,默认见下表)
    fontSize: 12,
    textColor: '#FFFFFF',
    textBgColor: 'rgba(0,0,0,0.6)',
    padding: 4,
    rounded: true,
    borderRadius: 4,
  },
  maxIconCache: 8000,    // 缓存上限(默认 8000)
})
参数 类型 默认值 说明
rawSvg string — 基础 SVG 模板字符串(含可替换颜色的占位,如 fill="#ff0000")
config.iconSize number 32 图标尺寸(px)
config.maxIconCache number 8000 图标缓存条目上限(LRU 淘汰)
config.textConfig.fontSize number 12 文字字号(px)
config.textConfig.textColor string '#FFFFFF' 文字颜色
config.textConfig.textBgColor string 'rgba(0,0,0,0.6)' 文字背景色
config.textConfig.padding number 4 文字内边距(px)
config.textConfig.rounded boolean true 是否圆角背景
config.textConfig.borderRadius number 4 背景圆角半径(px)
批量创建点位图标 batchCreatePointIcons

(推荐) 面向海量点位,智能按「颜色 + 合成文字」去重,相同配置的点位共享同一图标引用,结果原地回填 icon / width / height,可直接传给 loadPoints。

const withIcons = await iconManager.batchCreatePointIcons(pointItems)
await api.loadPoints(withIcons, { width: 20, height: 20 }, undefined, 'replace')

pointItems 每项(PointIconItem)参数表:

字段 类型 必填 说明
id string | number 否 点位标识(用于结果回填定位)
color string 否 直接指定图标颜色(优先于 status 映射)
status string | number 否 业务状态:未传 color 时按状态色映射取色
name string 否 点位名称
showName boolean 否 是否将名称合成进图标(文字在上、图标在下);为 true 且 name 非空时生效
svg string 否 覆盖本点位使用的基础 SVG 模板(支持同一任务内多个基础图标)

完整示例(10 万点位 + 名称合成):

import { iconManager } from 'bigmap-plugin'

iconManager.initialize(rawSvg, { iconSize: 32 })

const rawPoints = Array.from({ length: 100000 }, (_, i) => ({
  id: i,
  lng: 104.0 + (i % 100) * 0.001,
  lat: 30.4 + ((i / 100) | 0) * 0.001,
  name: `桩号-${String(i).padStart(6, '0')}`,
  status: i % 28,   // 28 种状态色
  showName: true,   // 将名称合成进图标
}))

const withIcons = await iconManager.batchCreatePointIcons(rawPoints)
await api.loadPoints(withIcons, { width: 20, height: 20 }, undefined, 'replace')

10 万点位 / 5000 唯一名称场景下,图标生成总耗时可降至毫秒级。

批量创建图标 batchCreateIcons

按「状态 + 文字」批量创建,适用于非点位场景(如图标集)。

const iconMap = await iconManager.batchCreateIcons([
  { status: 0, text: '正常' },
  { status: 1, text: '告警' },
  { status: 2 }, // 无文字 → 仅基础图标
])
// iconMap 为 Map<string, IconResult>,键为 `${status}_${text}`

每项(IconBatchItem)参数表:

字段 类型 必填 说明
status string | number 是 状态 / 颜色标识
text string 否 显示文字(缺省仅基础图标)
id string | number 否 可选标识
单图标创建 createIcon
const result = await iconManager.createIcon(status, text?)        // 按状态取色
const result2 = await iconManager.createIconByColor('#0a84ff', text?) // 按直接颜色

IconResult 返回说明:

字段 说明
icon 图片载荷:基础图标为 SVG data URL(字符串);文字图标为 HTMLCanvasElement
width / height 图标尺寸
type 'base'(基础)或 'text'(带文字)
text 若带文字则包含文字内容
任务级缓存 beginIconTask() / endIconTask()

包裹整个流式加载周期,任务期间图标缓存不触发 LRU 淘汰,保证首批生成的图标被后续批次复用,任务结束自动回落上限并裁剪缓存、回收内存。务必备成对调用(建议 try/finally)。

iconManager.beginIconTask()
try {
  let isFirst = true
  for await (const batch of streamedBatches()) {
    const withIcons = await iconManager.batchCreatePointIcons(batch)
    await api.loadPoints(withIcons, undefined, undefined, isFirst ? 'replace' : 'append')
    isFirst = false
  }
} finally {
  iconManager.endIconTask()
}
状态颜色映射 updateStatusColorMap

注册「状态 → 颜色」的纯色映射,更新后自动清空相关缓存并重建:

import { iconManager } from 'bigmap-plugin'
iconManager.updateStatusColorMap({ 0: '#0a84ff', 1: '#ff3b30', default: '#999' })

4.3 实体绘制

功能简介:程序化绘制几何实体(多边形 / 线段 / 圆形 / 矩形 / 点),适合不依赖鼠标的自动绘制场景。在组件式用法中,drawEntity / deleteEntity 可直接通过 api 调用;updateEntity / getCurrentEntityId 需使用 useMapEntity composable。

支持的小功能:

绘制实体 drawEntity
drawEntity(options): Promise<string | null>

成功返回创建的实体 id,失败返回 null。options 为 EntityOptions:

字段 类型 必填 适用类型 说明
type 'polygon' | 'line' | 'circle' | 'rectangle' | 'point' 是 全部 实体类型
id string 否 全部 实体 id(缺省自动生成)
name string 否 全部 名称
visible boolean 否 全部 是否可见(默认 true)
coordinates Coordinate[] 是 多边形 / 矩形 顶点序列 [{lng,lat},...]
lineCoordinates number[] 是 线段 线坐标(平铺数组)
center Coordinate 是 圆形 圆心
radius number 是 圆形 半径
point Coordinate 是 点 点坐标
pixelSize number 否 点 点像素大小
pointColor string 否 点 点颜色
fillColor string 否 面 填充色
fillAlpha number 否 面 填充透明度
strokeColor string 否 全部 边框 / 线颜色
strokeAlpha number 否 全部 边框 / 线透明度
strokeWidth number 否 全部 边框 / 线宽

示例:

const polygonId = await api.drawEntity({
  type: 'polygon',
  coordinates: [
    { lng: 104.0, lat: 30.4 },
    { lng: 104.1, lat: 30.4 },
    { lng: 104.1, lat: 30.5 },
    { lng: 104.0, lat: 30.5 },
  ],
  fillColor: '#0a84ff',
  fillAlpha: 0.3,
})

await api.drawEntity({ type: 'point', point: { lng: 104.05, lat: 30.45 }, pixelSize: 12 })
更新实体 updateEntity(Composable)
updateEntity(entityId, updates): Promise<boolean>

更新实体的样式 / 坐标 / 可见性;若 updates.type 与当前不同会自动迁移类型。仅 useMapEntity 提供,用法见 第 5 节。

示例:

const { updateEntity } = useMapEntity(map)
await updateEntity(polygonId, { fillColor: '#ff3b30', visible: true })
删除实体 deleteEntity
api.deleteEntity()    // 删除全部实体
api.deleteEntity(id)  // 删除指定实体
获取当前实体 id getCurrentEntityId(Composable)
const { getCurrentEntityId } = useMapEntity(map)
const id = getCurrentEntityId() // 最近绘制 / 选中的实体 id

4.4 交互式绘制

功能简介:通过鼠标在地图上交互绘制图形,支持 8 种类型,由右侧工具栏点击或 API 调用进入绘制模式。

支持的类型(DrawType):

DrawType 图形
polygon 多边形
rectangle 矩形
circle 圆形
polyline 线段
area 面积
ruler 标尺
azimuth 方位角
triangle 三角形

支持的小功能:

开始绘制 startDrawing
api.startDrawing('rectangle') // 进入绘制模式

绘制完成后通过 draw-end 事件(DrawEventData)获取结果,其中 operation 为 'draw' 或 'edit'。

<MapContainer @draw-end="(e) => console.log('绘制结果', e.data)" />

DrawEventData 字段说明:

字段 类型 说明
type DrawType 绘制类型
operation 'draw' | 'edit' | 'select' | 'cancel' | 'delete' | 'clear' 操作类型
id string 图形 id
data any 绘制结果数据
rawData any 原始数据
count number 清空操作时携带被清除的图形数量
停止绘制 stopDrawing
api.stopDrawing() // 取消当前绘制
清除全部绘制 clearDrawings
api.clearDrawings() // 移除所有已绘制图形
移除指定绘制 removeDrawing
api.removeDrawing(drawId) // 移除指定图形

4.5 点位弹窗

功能简介:基于 bmgl div.DivLayer 展示点位信息弹窗,支持自定义展示字段与主题色。在组件用法中,点击点位会自动弹出弹窗,只需配置 popupConfig;程序化触发 / 移除弹窗使用 useMapPopup composable。

支持的小功能:

配置自动弹窗 popupConfig

点击点位后自动弹出弹窗,内容与主题色由 popupConfig 控制:

<MapContainer
  :popupConfig="{
    fields: [
      { key: 'name', label: '名称' },
      { key: 'status', label: '状态' },
      { key: 'lng', label: '经度', format: 'lng' },
      { key: 'lat', label: '纬度', format: 'lat' },
      { key: 'altitude', label: '高程', format: 'altitude' },
    ],
    themeColor: '#0a84ff',
  }"
/>

PopupDisplayConfig 参数表:

字段 类型 说明
fields PopupFieldConfig[] 展示字段列表(未配置时使用内置点位字段)
fields[].key string 字段 key(取点位数据属性)
fields[].label string 显示标签
fields[].format 'default' | 'lng' | 'lat' | 'altitude' | (value,data)=>string 值格式化
themeColor string 弹窗主题色(顶部色条 / 详情按钮)
程序化弹窗 showPointPopup(Composable)
const { showPointPopup } = useMapPopup(map)
await showPointPopup({ lng: 104.03, lat: 30.48, altitude: 0, name: '点位1' })
移除弹窗 removePopup(Composable)
const { removePopup } = useMapPopup(map)
removePopup() // 隐藏当前弹窗

4.6 圆形波动特效

功能简介:在指定位置添加向外扩散的圆形波纹,常用于搜索结果定位、告警提示。useMapCircleWave composable 提供。

支持的小功能:

添加波纹 addWave
const { addWave } = useMapCircleWave(map)

const waveId = addWave({
  position: [104.03, 30.48, 0],  // [lng, lat, altitude]
  config: { color: '#0a84ff', radius: 100, duration: 3000, ttl: 0 },
})

参数表:

参数 类型 默认值 必填 说明
position [number, number, number] — 是 [lng, lat, altitude]
config.color string '#0a84ff' 否 波纹颜色
config.radius number 100 否 波纹半径(m)
config.duration number 3000 否 单次波动动画时长(ms)
config.ttl number 0 否 生命周期(ms),到期自动移除;0 表示不自动过期
移除波纹 removeWave
const { removeWave } = useMapCircleWave(map)
removeWave(waveId)

4.7 图层管理

功能简介:管理影像图层与 WMTS 图层,支持增删与显隐 / 透明度控制。useMapLayers composable 提供。

支持的小功能:

添加影像图层 addImageryLayer
const { addImageryLayer } = useMapLayers(map)
addImageryLayer('bigemap.dc-street') // 按 BigMap mapId 添加
添加 WMTS 图层 addWmtsLayer
const { addWmtsLayer } = useMapLayers(map)
addWmtsLayer(wmtsUrl, 'layer-name')
参数 类型 默认值 必填 说明
url string — 是 WMTS 服务地址
layerName string 'wmts-layer' 否 图层名
移除图层 removeLayer
const { removeLayer, removeAllLayers } = useMapLayers(map)
removeLayer('bigemap.dc-street')      // 支持名称或图层实例
removeAllLayers()                      // 移除全部图层
图层控制 setLayerVisible / setLayerOpacity
const { setLayerVisible, setLayerOpacity, getAllLayers } = useMapLayers(map)
setLayerVisible('bigemap.dc-street', false) // 隐藏图层
setLayerOpacity('wmts-layer', 0.5)          // 设置透明度
const layers = getAllLayers()               // 获取全部图层

4.8 等高线显示

功能简介:通过替换地表材质,在 3D 模式 下叠加彩色等高线(黑色描边 + 彩色主线 + 高程色带),并在开启时自动在等高线上标注高程数字(形如 1,500 m)。2D 模式自动关闭。

等高线渲染由随包发布的 BigemapElevationContourLayer 完成,仅在首次开启等高线时动态加载,地图初始化不加载该脚本。

支持的小功能:

切换等高线 setContourVisible
await api.setContourVisible(true) // 开启彩色等高线(仅 3D 生效)
api.setContourVisible(false)      // 关闭

首次开启时需先加载等高线库,因此返回 Promise;库加载失败时开关自动回退为关闭状态。

开启后会自动加载并显示当前视区的高程数字(形如 1,500 m,标注间隔 = 等高距 × labelEvery)。若此刻地形瓦片尚未加载完成,会每 500ms 自动重试,最长约 10s;关闭等高线或切换 2D 会立即终止重试。

关闭等高线时会同步清除已显示的高程数字(不只是隐藏),重新开启后按当前视区重新采样,因此不会出现「等高线关了、数字还留在图上」的残留。切换 2D / 3D 同理:切到 2D 清除,切回 3D 自动恢复。

高程数字依赖「当前视区」的地形,且不会随相机自动跟随,因此相机停止移动后会自动重算(防抖 400ms,两次重算最小间隔 1200ms,避免连续拖动时高频采样地形);移动结束后地形瓦片才补齐的场景也会在地形加载完成时补算。可通过 refreshOnMove: false 关闭,改为自行调用 loadContourLabels。

每次重算都是整体替换:先清空上一视区的数字,再按当前视区重新采样。因此从山区拖动到平原(当前视区没有等高线)时,原来的数字会一并移除,不会残留。

高程数字的生成规则:数字只出现在「地形高度跨越 等高距 × labelEvery 整数倍」的位置。默认标注间隔为 150m,若当前视区地形起伏小于该间隔,视区内不会出现任何数字,控制台会给出 no-results 提示。例如插件默认视角(成都市区上空 20km、近乎垂直俯视)可见地形高程仅 465~555m,起伏 90m < 150m,因此打开等高线后既没有等高线也没有数字——这与地形图在平原区不出现等高线是同一原因。将地图移动到有起伏的山区 / 丘陵即可看到数字,或调小 contourSpacing / labelEvery。

加载高程标签 loadContourLabels

手动刷新当前视区的高程数字(开启等高线时已自动加载一次,相机停稳后也会自动重算;需要立即刷新时可主动调用)。

const result = await api.loadContourLabels()
// { status, labelCount, error? }
status 含义
success 加载成功,labelCount 为标签数量
no-results 当前视区未找到可标注的等高线
terrain-loading 地形尚未加载完成,稍后重试
unsupported 当前 SDK 不支持高程标签集合
hidden 等高线未开启
busy 上一次加载尚未完成
error 加载异常,error 为原始错误对象
移除高程标签 clearContourLabels
const result = api.clearContourLabels()
// { status: 'cleared' | 'empty' | 'busy' | 'destroyed', labelCount: 0 }
高程图例 getContourLegend

返回绘制 HTML 图例所需的数据副本(未开启等高线时返回 null):

const legend = api.getContourLegend()
// { minHeight, maxHeight, legendColorStep, colorStops: [{ height, color }, ...] }
等高线状态 contourState
api.contourState.value
// { enabled, labelsLoading, labelCount, contourSpacing, labelSpacing, contourWidth, outlineWidth }
等高线配置 contourConfig
字段 类型 默认值 说明
contourSpacing number 150 等高距(m)
contourWidth number 2 彩色主线宽度(px)
outlineWidth number 2 黑色描边宽度(px)
labelEvery number 1 每隔多少条等高线显示一个高程数字(标注间隔 = 等高距 × 该值)
maxLabels number 50 当前视区最多显示的高程数字数量
labelMinDistance number 140 标签之间的最小屏幕间距(px)
labelOutlineWidth number 3 标签文字描边宽度(px)
sampleStep number 80 高程采样步长(px)
scanStep number 120 视口扫描步长(px)
viewportMargin number 48 视口边缘留白(px)
legendColorStep number 500 图例色阶间隔(m)
refreshOnMove boolean true 相机停止移动后是否自动重算高程数字;关闭可省去移动后的地形采样开销
minHeight number 取色带首节点 色带最低高程(m)
maxHeight number 取色带末节点 色带最高高程(m)
colorStops ContourColorStop[] 内置 20 级色带 高程颜色节点 { height, color };配置后默认按首尾节点推导高程范围
<MapContainer :config="{
  contourConfig: {
    contourSpacing: 100,
    contourWidth: 2,
    outlineWidth: 2,
    labelEvery: 2,
    colorStops: [
      { height: 0, color: '#0066FF' },
      { height: 3000, color: '#FF8A00' },
      { height: 6000, color: '#00F078' }
    ]
  }
}" />

4.9 轨迹回放

功能简介:加载采样点序列并播放轨迹动画,支持变速、跳转、暂停 / 停止,2D / 3D 通用(模式切换自动重建可视化)。基于自研 rAF 时间引擎驱动,性能开销极低。

支持的小功能:

加载轨迹 loadTrajectory
api.loadTrajectory(track, config?)

track 每项(TrackPoint)参数表:

字段 类型 必填 说明
lng number 是 经度
lat number 是 纬度
altitude number 否 高程
time number 否 相对起点的秒数;缺省按 config.interval 等间隔推断

config(TrajectoryConfig)参数表:

字段 类型 默认值 说明
autoPlay boolean false 加载后自动播放
speed number 1 播放速度倍率
loop boolean false 循环播放(到终点回起点继续)
follow boolean false 相机垂直跟随标记
followHeight number 2000 跟随相机高度(m)
trailTime number 10 已走过尾迹时长(s);0 保留起点到当前整段
duration number 0(自动推算) 总时长覆盖(s)
interval number 1 无 time 字段时点间间隔(s)
markerColor string '#ff3b30' 移动标记颜色
markerSize number 12 移动标记大小(px)
markerIcon string 空(圆点) 移动标记图片 URL
lineColor string '#0a84ff' 路径线颜色
lineWidth number 4 路径线宽(px)
maxPoints number 20000 折线抽稀上限(点数过多按等距步长抽稀)

示例:

const track = [
  { lng: 104.0, lat: 30.4, time: 0 },
  { lng: 104.01, lat: 30.41, time: 1 },
  { lng: 104.02, lat: 30.42, time: 2 },
]
api.loadTrajectory(track, { speed: 2, markerIcon: '/marker-pin.png', follow: true })
api.playTrajectory()
播放 / 暂停 / 停止
api.playTrajectory()   // 开始 / 继续播放
api.pauseTrajectory()  // 暂停
api.stopTrajectory()   // 停止并回到起点
调整速度 setTrajectorySpeed
api.setTrajectorySpeed(2) // 2 倍速
跳转指定时间 jumpTrajectoryTo
api.jumpTrajectoryTo(5) // 跳转到第 5 秒(范围 0 ~ duration)
清除轨迹 clearTrajectory
api.clearTrajectory() // 移除轨迹可视化并复位状态
轨迹状态 trajectoryState

响应式状态 api.trajectoryState:

字段 类型 说明
status 'idle' | 'playing' | 'paused' | 'ended' 回放状态
currentTime number 当前已播放秒
duration number 总时长(s)
progress number 播放进度(0 ~ 1)
pointCount number 有效采样点数

4.10 遮罩反选

功能简介:以指定区域边界为「洞」,在其外部铺满半透明遮罩,突出显示区域内部(搜救 / 高亮场景常用)。2D / 3D 通用,模式切换自动重建。

支持的小功能:

设置遮罩 setMask
api.setMask(boundary, config?)

boundary:保留区域边界环,Coordinate[]([{ lng, lat }, ...])。

config(MaskConfig)参数表:

字段 类型 默认值 说明
fillColor string '#000000' 遮罩填充色
fillAlpha number 0.8 遮罩透明度(0 ~ 1)
outlineColor string '#44d5ff' 边界发光线颜色
outlineAlpha number 1 边界发光线透明度
outlineWidth number 4 边界发光线宽(px)
showOutline boolean true 是否绘制边界发光线
outerRing Coordinate[] 自动外扩推导 遮罩覆盖外环(可显式指定含全球)

示例:

api.setMask([
  { lng: 104.0, lat: 30.4 },
  { lng: 104.05, lat: 30.45 },
  { lng: 104.0, lat: 30.5 },
], { fillAlpha: 0.6, outlineColor: '#ff3b30' })
切换显隐 setMaskVisible
api.setMaskVisible(false) // 隐藏遮罩(保留边界数据)
api.setMaskVisible(true)  // 重新显示
清除遮罩 clearMask
api.clearMask() // 移除遮罩并复位状态
遮罩状态 maskState

响应式状态 api.maskState,字段:visible(是否显示)、hasMask(是否已设置边界)、boundaryCount(边界顶点数)。


4.11 天气特效

功能简介:基于全屏后处理着色器(PostProcessStage)实现雨天 / 雪天,2D / 3D 通用,无需额外 Canvas 层。

支持的小功能:

切换天气 setWeather
api.setWeather('rain', { opacity: 0.5 })
api.setWeather('snow')
api.setWeather('clear') // 关闭特效

WeatherType:'clear' | 'rain' | 'snow'。config 参数表:

字段 类型 默认值 说明
opacity number 雨 0.5 / 雪 0.3 特效混合强度(0 ~ 1)
清除天气 clearWeather
api.clearWeather()
天气状态 weatherState

响应式状态 api.weatherState,字段:type(当前天气类型)、active(是否有特效运行)。


4.12 3D 自动光源

功能简介:依据当前系统时间自动判定周期(白天 / 黄昏 / 夜晚)并切换场景光源,仅 3D 模式生效,2D 模式自动还原。

支持的小功能:

开关光源 setLightingEnabled
api.setLightingEnabled(true)  // 开启(默认按系统时间自动判定周期)
api.setLightingEnabled(false) // 关闭并还原开启前光照
设置周期 setLightingPeriod
api.setLightingPeriod('auto')  // 按系统时间自动判断
api.setLightingPeriod('day')   // 强制白天
api.setLightingPeriod('dusk')  // 强制黄昏
api.setLightingPeriod('night') // 强制夜晚

LightingPeriod:'day' | 'dusk' | 'night'。

通过 config.lightingConfig: true 可在初始化时开启;如需自定义昼夜边界(dayStartHour / duskStartHour / nightStartHour),用 useMapLighting(见 第 5 节)。

光源状态 lightingState

响应式状态 api.lightingState:enabled(是否开启)、mode('auto' | 'manual')、period(当前周期)、hour(判定小时)。


4.13 主题切换

功能简介:全局浅色 / 暗色主题切换,作用于地图 UI 与弹窗等所有组件。

api.setTheme('light') // 切换到浅色
api.setTheme('dark')  // 切换到暗色

4.14 视图与地图

功能简介:地图视角控制与基础状态。

支持的小功能:

视角定位 setView
api.setView(lng, lat, height?)
参数 类型 必填 说明
lng number 是 经度
lat number 是 纬度
height number 否 高度(缺省用默认高度)
api.setView(104.03, 30.48, 20000)

2D / 3D 切换、重置视角由工具栏触发;如需 API 化调用可组合 useMap(见 第 5 节)。

地图名称注记 setMapNameVisible
api.setMapNameVisible(true)  // 显示地图名称注记
api.setMapNameVisible(false) // 隐藏
地图状态 state

响应式状态 api.state:

字段 类型 说明
isReady boolean 是否就绪
isLoading boolean 是否加载中
mapType '2d' | '3d' 当前地图类型
cameraPosition CameraPosition 相机位置与姿态
bounds Bounds | null 当前视野范围
error Error | null 错误信息

4.15 KML 数据加载

功能简介:加载 KML 数据并渲染为地图要素,支持两种数据输入方式:远程地址(loadKmlFromUrl)与直接传入 KML 文本(loadKmlFromText)。自动解析 Placemark 的点 / 线 / 面(含 MultiGeometry 展开与内环「洞」)、共享样式(Style / styleUrl / StyleMap,含内联样式覆盖)与 ExtendedData 属性;2D / 3D 通用,模式切换自动重建。加载失败时给出中文提示,可通过状态直接展示,也可 await + try/catch 捕获。

支持的小功能:

地址加载 loadKmlFromUrl
const result = await api.loadKmlFromUrl(url, config?)
参数 类型 必填 说明
url string 是 KML 文件地址,支持绝对地址(http(s)://...)与相对地址(如 /chengdu.kml);仅支持 http/https/blob/data 协议
config KmlConfig 否 本次加载的配置,覆盖初始化时的默认配置

返回值 KmlLoadResult:featureCount(要素数)、polygonCount / lineCount / pointCount(各几何数量)、features(解析后的要素,含 properties 属性,可供弹窗等二次消费)等。

示例:

try {
  const { featureCount } = await api.loadKmlFromUrl('/chengdu.kml')
  console.log('已加载要素数:', featureCount)
} catch (error) {
  // 无效地址 / 网络失败 / HTTP 异常 / 解析失败 等均在此捕获
  console.warn((error as Error).message)
}
文本加载 loadKmlFromText
const result = await api.loadKmlFromText(text, config?)
参数 类型 必填 说明
text string 是 KML 格式的 XML 文本内容,不能为空
config KmlConfig 否 本次加载的配置,覆盖初始化时的默认配置

示例:

const response = await fetch('/chengdu.kml')
const text = await response.text()
const { featureCount } = await api.loadKmlFromText(text, { autoFlyTo: false })

config(KmlConfig)参数表:

字段 类型 默认值 说明
fillColor string '#3d8bff' 面默认填充色(KML 未声明 PolyStyle 时使用)
fillAlpha number 0.35 面默认填充透明度(0 ~ 1)
strokeColor string '#ffffff' 线 / 面轮廓默认颜色
strokeAlpha number 1 线 / 面轮廓默认透明度(0 ~ 1)
strokeWidth number 2 线 / 面轮廓默认线宽(px)
pointColor string '#ff3b30' 点默认颜色
pointPixelSize number 8 点默认像素大小
showLabel boolean true 是否显示要素名称标签(每个要素在代表点生成 1 个标签,随要素显隐)
labelColor string '#ffffff' 标签文字颜色
labelFontSize number 13 标签字号(px)
labelOutlineColor string '#000000' 标签文字描边颜色
fillPalette string[] [] 按要素顺序轮换取色的调色板;非空时覆盖 KML 自身颜色(用于区分相邻区域),为空则不覆盖
useKmlStyle boolean true 是否采用 KML 内联样式;false 时统一使用上述默认配色
showFill boolean true 是否填充面(与 KML PolyStyle.fill 为「与」关系,两者同时为真才填充)
showOutline boolean true 是否绘制面外轮廓(与 KML PolyStyle.outline 为「与」关系)
extractProperties boolean true 是否解析 ExtendedData 到要素属性
autoFlyTo boolean true 加载成功后是否自动飞行定位到数据范围
timeout number 15000 远程加载超时(ms),仅地址加载有效
KML XML 结构规范

插件内置解析器按标签名(localName)匹配,不区分命名空间前缀(<kml> 与 <kml:kml> 均可),因此只需保证标签名与层级正确。支持的标签子集如下:

标签 出现位置 必需 说明
<kml> 根节点 是 根节点名必须是 kml,否则报 PARSE_FAILED
<Document> / <Folder> 可任意层级嵌套 否 用于分组,仅影响遍历;Placemark 会被递归收集,与嵌套深度无关
<Placemark> Document / Folder 内 是(至少一个) 一个要素;文档内无任何可渲染几何时报 NO_FEATURES
<name> Placemark 内 否 要素名,缺省时回退为 Placemark 的 id;同时作为地图上名称标签的文字
<visibility> Placemark 内 否 值为 0 时该要素默认隐藏(整体显隐不会强制显示它)
<styleUrl> Placemark 内 否 引用样式 id,写法 #styleId
<Style id> Document 内(任意层级均可被收集) 否 样式定义;写在 Placemark 内时作为内联样式,覆盖 styleUrl 引用的结果
<LineStyle> Style 内 否 含 <color>(aabbggrr)与 <width>(px),作用于线与面轮廓
<PolyStyle> Style 内 否 含 <color>、<fill>(0/1)、<outline>(0/1)
<IconStyle> Style 内 否 含 <color>、<scale>、<Icon><href>
<StyleMap id> Document 内 否 取 normal 分支的 styleUrl(可穿透引用,自动解引用到目标 Style)
<Point><coordinates> Placemark 内 否 单个坐标
<LineString><coordinates> Placemark 内 否 至少 2 个坐标,不足则跳过该几何
<Polygon> Placemark 内 否 外环 <outerBoundaryIs><LinearRing><coordinates> 至少 3 个坐标;洞用 <innerBoundaryIs> 表达,可多个
<MultiGeometry> Placemark 内 否 其内部几何会被展开为多个几何,一个 Placemark 可产出多个面
<ExtendedData> Placemark 内 否 支持 <SchemaData><SimpleData name="...">值</SimpleData> 与 <Data name="..."><value>值</value></Data> 两种写法,结果进入 features[].properties
<Schema> Document 内 否 仅作声明用,解析属性时不依赖它,可省略

四条必须遵守的编码规则:

  1. 颜色是 aabbggrr,不是 #rrggbb:8 位十六进制,字节序为「alpha、蓝、绿、红」,与 CSS 的 #rrggbb 正好相反,且 alpha 在前。
    • 例:CSS #4d90fe(蓝)配 50% 透明度 → 50fe904d(50 = alpha,fe = 蓝,90 = 绿,4d = 红)
    • 换算:alpha 字节 = round(透明度 × 255) 的两位十六进制,其后依次拼 bb、gg、rr
    • 也兼容 6 位 rrggbb(按不透明处理),非法值回退为默认配色
  2. 坐标格式为 经度,纬度[,高程]:多个坐标元组之间用空白(空格或换行)分隔;高程省略时按 0 处理,非数字的元组会被跳过。
  3. 环必须首尾闭合:LinearRing 的最后一个坐标应重复第一个坐标;洞(innerBoundaryIs)同样需要闭合。
  4. 无效几何只跳过自身:不足 3 点的面、不足 2 点的线会被丢弃,不影响同文档其他要素;若整个文档一个可渲染几何都没有,则报 NO_FEATURES。

配色两种做法,二选一:

  • 在 KML 里写 <Style> + <styleUrl>,由数据自身决定每个要素的颜色(适合颜色有业务含义的场景,见下方生成示例);
  • 不在 KML 里写样式,改用配置项 fillPalette 让插件按要素顺序轮换取色(适合只想区分相邻区域的场景,无需生成样式)。
生成 KML XML 并加载

下面的 buildKml 是一段自包含的生成函数(不依赖本库任何导出),把业务数据拼成 KML 文本,再交给 loadKmlFromText 加载。

/** #rrggbb + 透明度(0~1) → KML 的 aabbggrr */
function toKmlColor(hex: string, alpha: number): string {
  const r = parseInt(hex.slice(1, 3), 16)
  const g = parseInt(hex.slice(3, 5), 16)
  const b = parseInt(hex.slice(5, 7), 16)
  const h2 = (v: number): string => v.toString(16).padStart(2, '0')
  return `${h2(Math.round(alpha * 255))}${h2(b)}${h2(g)}${h2(r)}`
}

/** XML 文本转义(名称等业务字段可能含 & < > " ') */
function escapeXml(value: string): string {
  return value
    .replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;')
    .replace(/"/g, '&quot;').replace(/'/g, '&apos;')
}

interface Region {
  /** 区域名称:会作为地图上的名称标签文字 */
  name: string
  /** 区域颜色 #rrggbb */
  color: string
  /** 外环坐标(可不闭合,生成时会自动补首点) */
  ring: Array<{ lng: number; lat: number }>
}

function buildKml(regions: Region[]): string {
  const lines: string[] = [
    '<?xml version="1.0" encoding="UTF-8"?>',
    '<kml xmlns="http://www.opengis.net/kml/2.2">',
    '  <Document id="root_doc">'
  ]

  // 1) 每个区域一条 Style,Placemark 通过 styleUrl 引用
  regions.forEach((region, i) => {
    lines.push(
      `    <Style id="style_${i}">`,
      `      <LineStyle><color>${toKmlColor(region.color, 1)}</color><width>2</width></LineStyle>`,
      `      <PolyStyle><color>${toKmlColor(region.color, 0.35)}</color></PolyStyle>`,
      '    </Style>'
    )
  })

  // 2) 每个区域一个 Placemark:名称 + 属性 + 面
  regions.forEach((region, i) => {
    const name = escapeXml(region.name)
    const ring = [...region.ring]
    const first = ring[0]
    const last = ring[ring.length - 1]
    // 规则 3:环首尾闭合,末点补首点
    if (first && last && (first.lng !== last.lng || first.lat !== last.lat)) {
      ring.push(first)
    }

    lines.push(
      `    <Placemark id="region_${i + 1}">`,
      `      <name>${name}</name>`,
      `      <styleUrl>#style_${i}</styleUrl>`,
      '      <ExtendedData>',
      '        <SchemaData schemaUrl="#region.schema">',
      `          <SimpleData name="BM_Name">${name}</SimpleData>`,
      `          <SimpleData name="Code">R${String(i + 1).padStart(3, '0')}</SimpleData>`,
      '        </SchemaData>',
      '      </ExtendedData>',
      '      <Polygon>',
      '        <outerBoundaryIs><LinearRing><coordinates>',
      ...ring.map((p) => `          ${p.lng},${p.lat},0`),
      '        </coordinates></LinearRing></outerBoundaryIs>',
      '      </Polygon>',
      '    </Placemark>'
    )
  })

  lines.push('  </Document>', '</kml>')
  return lines.join('\n')
}

用法一:生成后直接加载(推荐,不落地文件、无网络请求)

const kmlText = buildKml([
  {
    name: '一号作业区',
    color: '#3d8bff',
    ring: [
      { lng: 104.05, lat: 30.65 },
      { lng: 104.12, lat: 30.65 },
      { lng: 104.12, lat: 30.72 }
    ]
  },
  {
    name: '二号作业区',
    color: '#ff9f0a',
    ring: [
      { lng: 104.14, lat: 30.65 },
      { lng: 104.21, lat: 30.65 },
      { lng: 104.21, lat: 30.72 }
    ]
  }
])

const { features } = await api.loadKmlFromText(kmlText)
features[0].name        // '一号作业区'(即 <name>,也是地图上的标签文字)
features[0].properties  // { BM_Name: '一号作业区', Code: 'R001' }(来自 <ExtendedData>)

用法二:生成为 Blob URL 后按地址加载

loadKmlFromUrl 支持 blob: 协议,因此无需部署静态文件也能走地址加载链路:

const blob = new Blob([kmlText], { type: 'application/vnd.google-earth.kml+xml' })
const objectUrl = URL.createObjectURL(blob)
try {
  await api.loadKmlFromUrl(objectUrl)
} finally {
  URL.revokeObjectURL(objectUrl)
}

用法三:落地为 .kml 文件后由静态服务提供

把 kmlText 存成文件(如 public/regions.kml),再 api.loadKmlFromUrl('/regions.kml')。适合数据量较大、需被多次复用或由后端直接下发的场景。

关于名称标签:<name> 的内容会渲染为地图上的名称标签,落点取面的包围盒中心(MultiGeometry 取面积最大的那个面;线取中点、点取自身坐标),文字默认白字黑描边。showLabel 默认为 true,不需要标签时加载传 { showLabel: false } 即可;字号与颜色可经 labelFontSize / labelColor / labelOutlineColor 调整。

切换显隐 setKmlVisible
api.setKmlVisible(false) // 隐藏全部 KML 要素(保留数据)
api.setKmlVisible(true)  // 重新显示

整体显隐与 KML 要素自身 visibility 叠加生效:KML 中 visibility=0 的要素不会被整体显隐强制显示。

清除数据 clearKml
api.clearKml() // 移除实体、清空数据并复位状态
加载状态 kmlState

响应式状态 api.kmlState,字段如下:

字段 类型 说明
status 'idle' | 'loading' | 'success' | 'error' 加载状态
source 'url' | 'text' | null 数据来源
url string 数据来源地址(source 为 url 时有效)
featureCount number 要素(Placemark)数量
polygonCount number 面(Polygon)数量
lineCount number 线(LineString)数量
pointCount number 点(Point)数量
visible boolean 是否显示中
error string | null 错误提示(status 为 error 时有效)

错误提示说明:加载失败时统一抛出 KmlError(含 code 与中文 message),并将提示写入 kmlState.error,两种方式可任选:

// 方式一:直接绑定状态渲染提示(无需 try/catch)
api.loadKmlFromUrl(url).catch(() => {})

// 方式二:捕获异常按错误码分支处理
import { KmlError, KmlErrorCode } from 'bigmap-plugin'
try {
  await api.loadKmlFromText(text)
} catch (error) {
  if (error instanceof KmlError && error.code === KmlErrorCode.PARSE_FAILED) {
    console.warn('KML 格式有误:', error.message)
  }
}
错误码 KmlErrorCode 触发场景
INVALID_URL 地址为空、非字符串或不支持的协议
INVALID_TEXT 文本为空或非字符串
PARSE_FAILED XML 格式错误或根节点不是 <kml>
NO_FEATURES 解析成功但无任何可渲染几何(如空文档)
NETWORK_FAILED 请求发起失败或读取响应内容失败
HTTP_ERROR 服务器返回非 2xx 状态码
TIMEOUT 远程加载超时
MAP_NOT_READY 地图尚未初始化完成
LOAD_FAILED 其他异常的统一兜底

5. Composable 独立使用

除通过 MapContainer 组件使用外,也可在自定义 <script setup> 中直接组合 composable,获得更细粒度的控制。所有 composable 均通过具名导出引入:

import {
  useMap,
  useMapPoint,
  useMapEntity,
  useMapDraw,
  useMapPopup,
  useMapCircleWave,
  useMapLayers,
  useMapContour,
  useMapTrajectory,
  useMapMask,
  useMapKml,
  useMapWeather,
  useMapLighting,
} from 'bigmap-plugin'

Composable 一览表:

Composable 用途 常用方法
useMap(config) 地图核心(初始化 / 视角 / 模式 / 事件) initMap / setView / toggleMapType / destroy / on / emit
useMapPoint(map) 点位管理 loadPoints / updatePoints / clearPoints / searchByText / searchByShape
useMapEntity(map) 实体管理 drawEntity / updateEntity / deleteEntity / redrawAllEntities / getCurrentEntityId
useMapDraw(map, config?) 交互绘制 startDrawing / cancelDrawing / removeDrawing / clearAllDrawings / setCallback / getIsDrawing
useMapPopup(map, event?, options?) 点位弹窗 showPointPopup / removePopup / isPopupVisible / getCurrentPopupData
useMapCircleWave(map) 圆形波动 addWave / removeWave
useMapLayers(map) 图层管理 addImageryLayer / addWmtsLayer / removeLayer / removeAllLayers / setLayerVisible / setLayerOpacity
useMapContour(map, config?, deps?) 彩色等高线 setContourVisible / loadLabels / clearLabels / getLegendData / reapply / remove
useMapTrajectory(map, config?, deps?) 轨迹回放 load / play / pause / stop / setSpeed / jumpTo / clear / reapply / destroy
useMapMask(map, config?) 遮罩反选 setMask / setVisible / clear / reapply / remove / destroy
useMapKml(map, config?) KML 数据加载 loadFromUrl / loadFromText / getFeatures / setVisible / flyTo / remove / clear / reapply / destroy
useMapWeather(map, config?) 天气特效 setWeather / clear / destroy
useMapLighting(map, config?, options?) 3D 光源 setEnabled / setPeriod / apply / destroy

完整示例(自定义组合地图能力):

<template>
  <div id="map-container"></div>
</template>

<script setup lang="ts">
import { onMounted, ref } from 'vue'
import {
  useMap,
  useMapPoint,
  useMapDraw,
  useMapTrajectory,
  useMapMask,
  useMapWeather,
} from 'bigmap-plugin'

const map = ref(null) // 地图实例 Ref(供各 composable 使用)

const {
  initMap, setView, toggleMapType, state,
} = useMap({
  containerId: 'map-container',
  serverUrl: 'http://你的服务器:3000',
  position: { lng: 104.03, lat: 30.48, height: 20000 },
})

const { loadPoints, clearPoints } = useMapPoint(map)
const { startDrawing } = useMapDraw(map)
const trajectory = useMapTrajectory(map)
const mask = useMapMask(map)
const weather = useMapWeather(map)

onMounted(async () => {
  await initMap() // 初始化后 map.value 会被赋值
})

const load = async () => {
  await loadPoints([{ id: '1', lng: 104, lat: 30.4, icon: someIcon }], {}, undefined, 'replace')
}
</script>

6. 常见问题 FAQ

Q1:地图不显示 / 白屏?

serverUrl 为必填,需指向可用的地图资源 / 瓦片服务器。并确认 containerId 对应 DOM 已存在、libsUrl(默认 /libs)下能访问随包发布的 dist/libs 资源。开发环境需通过构建工具把 node_modules/bigmap-plugin/dist/libs 静态映射到 /libs(vite 示例参考 demo)。

Q2:点位加载很慢,如何优化?

  • 点位 icon 用 iconManager.batchCreatePointIcons 批量预生成(自动去重缓存)后再传给 loadPoints;
  • 用 beginIconTask() / endIconTask() 包裹整个流式加载流程;
  • 渲染层只做 billboard 构建(毫秒级),把图标生成这类耗时工作放数据层。

Q3:点位不显示?

loadPoints 会跳过缺少 icon 的点位。请确认数据层已为每个点位生成 icon(或调用 batchCreatePointIcons 回填)。

Q4:updatePoints 不生效?

updatePoints 按点位 id 定位。请确保 fieldMapping.id 映射正确,且点位提供了稳定 id;否则自动自增 id 无法精确定位。

Q5:等高线 / 3D 光源不生效?

两者仅 3D 模式有效,切到 2D 会自动关闭 / 还原。等高线还需确认等高线库可访问:首次开启时会从 libsUrl(默认 /libs)加载 libs/bigemap/BigemapElevationContourLayer.js,若该资源不可达则开关会自动回退为关闭,控制台会输出加载失败日志。

Q6:轨迹加载后不动?

先调用 api.playTrajectory()(或设置 config.autoPlay: true)。若相机一直跟随,可关闭 config.follow。

Q7:遮罩没有变暗(只有边框)?

若默认自动外扩仍异常,可显式传入 config.outerRing。若地图跨越 180° 经线,建议显式指定外环避免三角剖分问题。

Q8:图标显示为色块?

个别基于图片解码的合成在资源未就绪时会产生临时色块(该结果不会写入缓存,下次会自动重试)。

Q9:如何更新状态颜色?

import { iconManager } from 'bigmap-plugin'
iconManager.updateStatusColorMap({ 0: '#0a84ff', 1: '#ff3b30', default: '#999' })

Q10:程序化搜索定位波纹如何做?

import { useMapCircleWave } from 'bigmap-plugin'
const { addWave } = useMapCircleWave(map)
addWave({ position: [104.03, 30.48, 0], config: { color: '#0a84ff', ttl: 5000 } })

License

MIT

Related Packages

b-map-viewer

面向 Vue 3 应用的 Cesium 地理信息可视化 SDK

808 10
ctmap

A Vue.js project

6,274
wz-cesium-v3

飞行与3d地图整合,支持react和vue3

4,868
@akuno/vue-cesium

Vue 2.x components for CesiumJS.

968 1,917
agile-cesium

Vue 2.x components for CesiumJS.

420

Version History

Version Released Vue License
1.0.11 ^3.2.0 MIT
1.0.10 ^3.2.0 MIT
1.0.9 ^3.2.0 MIT
1.0.8 ^3.2.0 MIT
1.0.7 ^3.2.0 MIT