You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

6.8 KiB

Mapbox 全量替换 maptalks

日期:2026-08-27
范围:MapLayer / mapHelper / config/map + Monitor / Tasks / Replay
状态:待用户确认

1. 背景与目标

现状运行时仍是 maptalks@1.12.1 + 天地图 WMTS。共享层 MapLayer 单例经 commonRefs('map') + mapHelper 暴露;MonitorView / TasksView / ReplayView 直接使用 maptalks Marker / VectorLayer / LineString / setBaseLayer。

目标:

  1. 引擎从 maptalks 全量切到 mapbox-gl
  2. 底图用 Mapbox 官方样式:卫星 / 街道;环境变量 APP_MAPBOX_TOKEN
  3. 保留常驻 MapLayer + commonRefs('map') + mapHelper 薄封装
  4. Monitor / Tasks / Replay 全部改 Mapbox API;删除 maptalks 依赖
  5. Tasks 航线编辑继续 replaceMapContainer / restoreMapContainer 搬迁共享地图容器
  6. 设备点、航点、航迹、绑定线统一用 GeoJSON Source + Layer

非目标:

  • 不做统一 MapService 大门面
  • 不保留天地图 / 双 provider
  • 不改球形总览 Three.js(若已有或后续独立做)
  • 本轮不重做机巢/无人机 pin 图标视觉(可先 circle / 基础 symbol,后续再接 pin)

2. 方案选型

方案 结论
A. 薄封装替换 MapLayer/mapHelper,页面直用 mapbox API 采用
B. 统一 MapService 门面 本轮不做,抽象成本高
C. 每页独立地图实例 与常驻地图 + Tasks 搬迁语义冲突

底图:Mapbox 官方 satellite-streets / streets,不再使用天地图 WMTS。
渲染:GeoJSON Source + Layer(非 DOM Marker 为主路径)。

3. 共享层

3.1 src/config/map.js

  • tokenimport.meta.env.APP_MAPBOX_TOKEN || import.meta.env.VITE_MAPBOX_TOKEN || ''
  • 保留 center / zoom(现有 APP_MAP_CENTER_* / APP_MAP_ZOOM
  • 导出:
export const MAP_STYLES = {
  satellite: 'mapbox://styles/mapbox/satellite-streets-v12',
  street: 'mapbox://styles/mapbox/streets-v12',
}
  • 删除 createTiandituLayerOptions / createTiandituBaseLayer

3.2 src/layout/MapLayer.vue

  • 引入 mapbox-gl 与 CSS
  • mapboxgl.accessToken = mapConfig.token
  • 缺 token:打错误日志,commonRefs.setRef('map', null),不抛崩
  • 有 token:
map = new mapboxgl.Map({
  container: 'map',
  style: MAP_STYLES.satellite,
  center: mapConfig.center, // [lng, lat]
  zoom: mapConfig.zoom,
  minZoom: 3,
  attributionControl: false,
})
  • commonRefs.setRef('map', map) + mapHelper.setMap(map)
  • onUnmountedmap.remove(),清 ref / helper

3.3 src/core/mapHelper.js

保留对外方法,内部改 Mapbox:

方法 行为
setMap / getMap 持有 mapboxgl.Map
toggleMapMode({ is2D, is3D }) 2D:setPitch(0) setBearing(0),关闭 dragRotate/pitch;3D:pitch≈45,开启旋转/倾角
replaceMapContainer(newParent) 保存 view → 把 #map DOM 挪到 newParentmap.resize()
restoreMapContainer() 移回原父节点 → 恢复 center/zoom/pitch/bearing → map.resize()

去掉 maptalks checkSize;一律 resize()

3.4 依赖与 env

  • package.json:增加 mapbox-gl;删除 maptalks
  • .env.example / .env.development / .env.production
    • 增加 APP_MAPBOX_TOKEN=
    • 删除或降级 APP_TIANDITU_TOKEN 说明(本轮不再使用)
    • 保留中心/缩放变量
  • CSS:去掉 .maptalks-wrapper 特例;Tasks 宿主适配 #map / .mapboxgl-map

4. 页面层

坐标约定:统一 [lng, lat]
map.setStyle(...) 会清掉自定义 source/layer —— 切换样式后必须在 style.load 重建业务层并回填数据

4.1 MonitorView

能力 Mapbox 落地
设备点 source monitor-devices + circle(或基础 symbol)+ 可选 symbol 文本层
选中态 feature-state 或按 selectedId 重写 properties / paint
绑定虚线 source monitor-binding + lineline-dasharray);仅「选中机巢 + 其飞行中无人机」或「选中飞行无人机 + 所属机巢」
卫星/地图 map.setStyle(MAP_STYLES[mode])style.load 后重建 devices/binding 层
fitAll fitBounds;清选中回 overview
选中飞向 flyTo / easeTo
比例尺 保留现有 zoom→米估算,或挂 ScaleControl(二选一,UI 位置对齐现工具条)
点击选中 queryRenderedFeatures 命中设备层

离开 Monitor:移除本页 source/layer 与事件,避免污染 Tasks/Replay。

4.2 TasksView

  • 进入编辑:mapHelper.replaceMapContainer(host)resize()toggleMapMode({ is2D: true })
  • 航线:source task-route(LineString)+ task-waypoints(Point features,可带序号属性)
  • 地图点击加点:map.on('click', ...)e.lngLat
  • 离开:清业务层 → restoreMapContainer()

4.3 ReplayView

  • source replay-traj line + 起/终/当前点(可同一 points source 不同 layer filter)
  • fitBounds 包住轨迹
  • 离开清层

5. 数据流与生命周期

flowchart LR
  MainContainer --> MapLayer
  MapLayer -->|"commonRefs + mapHelper"| Pages
  Pages --> Monitor
  Pages --> Tasks
  Pages --> Replay
  Tasks -->|"replace/restore DOM"| MapLayer
  1. 登录后壳层挂载 → MapLayer 初始化 Mapbox → 写入 ref
  2. 业务页 await commonRefs.getRef('map') 拿到实例后加自己的 source/layer
  3. 路由离开必须卸本页图层与监听;Tasks 额外 restore 容器
  4. 无 token:地图不初始化,业务页需容忍 map == null(空态/提示,不白屏)

6. 风险与处理

风险 处理
setStyle 清空业务层 统一 style.load 重建 + 数据回填函数
Tasks 搬迁后尺寸为 0 replace/restore 后立刻 resize();必要时 requestAnimationFrame 再 resize
token 无效/缺省 跳过 init + 日志;页面降级
旧文档按 maptalks/天地图写 本 spec 为准;相关旧计划标注过时,不在本轮改文
包体变大 可接受;不引入 maptalks.mapboxgl 双引擎

7. 验收

  • 配置有效 APP_MAPBOX_TOKEN 后登录可见 Mapbox 卫星底图
  • 缺 token 不白屏崩,有明确控制台错误
  • Monitor:卫星↔街道切换后点/线仍在;选中飞向;fitAll;绑定虚线条件正确;比例尺可见
  • Tasks:编辑器内地图可点加点、航线/航点绘制;离开恢复主壳地图位置
  • Replay:航迹线 + fitBounds
  • package.jsonmaptalks;源码无 import ... maptalks
  • 1920×1080 冒烟:Monitor 主路径可用

8. 实现顺序(计划阶段细化)

  1. 依赖与 env / config/map / MapLayer / mapHelper
  2. Monitor 点线与底图切换 / fit / 绑定线
  3. Replay 航迹
  4. Tasks 搬迁 + 航线编辑交互
  5. 删 maptalks 残留 CSS/引用;冒烟验收