Skip to content

AGENTS.md — AI / 协作者开发指南

本文面向 AI 编码助手 与人类贡献者,说明 @m-tech/gis-core 的架构、代码风格与扩展方式。
改代码前先读本文;新增能力时按「扩展清单」落地,并同步 demo / 文档导出。


1. 项目定位

  • 是什么:Cesium 二次封装的三维 GIS 核心 SDK(npm 包 @m-tech/gis-core)。
  • 不是什么:不是完整业务应用;Vue 业务组件在 packages/biz,演示在 apps/demo
  • 目标用户:平台业务前端、大屏、工具站,通过 Viewer + Layer + Overlay 快速搭三维场景。
  • 技术栈:TypeScript(部分 material 仍为 JS)、Vite 库模式、Cesium 1.x、Turf / proj4 / wellknown 等。

工作区若在 monorepo 根:packages/core 即本包。当前包版本见 package.json


2. 架构心智模型

2.1 对象关系

Position / Color          # 基础值对象

Overlay ──► Layer ──► Viewer (extends Cesium.Viewer)
Effect  ───────────► Viewer
Widget  ───────────► Viewer
Analysis / Measure / Plot  构造注入 Viewer,内部自建临时 Layer 或 Entity
概念职责挂载方式
Viewer场景中枢:缓存 Layer/Effect/Widget,事件总线,相机与底图new Viewer(container, options)
Layer一组 Overlay 的容器;_delegate 多为 DataSource / PrimitiveCollection / ImageryLayerlayer.addToViewer(viewer)
Overlay单个图元;_delegate 多为 Entity / Primitiveoverlay.addToLayer(layer)
Effect后处理等场景特效effect.addToViewer(viewer)
WidgetDOM UI 控件widget.addToViewer(viewer)
Analysis分析算法 + 可视化new XxxAnalysis(viewer, options)

2.2 生命周期与事件

  1. 构造:创建 _delegate,设置 type,注册内部 ADD/REMOVE 监听。
  2. 挂载:addTo* → 触发事件 → _addHandler / _mountedHook / _addedHook
  3. 卸载:remove_removeHandler / _removedHook,清理缓存与监听。

状态常量见 event/EventEnums.tsStateinitialized / added / removed …)。

事件基类 event/Event.tson / off / fire / once / clear,内部是 Cesium.Event 字典。

常用事件枚举(均从包入口导出或经 event 模块):

  • MouseEventType:CLICK、RIGHT_CLICK、MOUSE_OVER …
  • ViewerEventType:ADD_LAYER、REMOVE_LAYER、ADD_EFFECT …
  • LayerEventType / OverlayEventType / SceneEventType / PrimitiveOverlayEventType

2.3 坐标与 Transform

  • 对外 API 一律优先 Position,不要直接让业务传裸 Cartesian3(内部再转)。
  • utils/convertor/Transform.tscartographicToCartesian / cartesianToCartographic 等。
  • Position:经纬度为度;setter 的 heading/pitch/roll 入参是,内部存弧度,getter 再转回度。
  • 数组视角:defaultView: [lng, lat, alt, heading, pitch, roll]

2.4 单例工具 liteUtils

CameraUtil / LayerUtil / ImageryUtil / EntityUtil 在 Viewer 构造时 new XxxUtil(this) 初始化,后续静态方法操作当前 Viewer。扩展时注意 destroy / 重绑,避免多 Viewer 场景串台。

2.5 导出入口

index.ts唯一公共 API 表面

  • 新增 public 类 → 在对应模块 index.ts 导出 → 再写入根 index.ts 的 import 与 export 列表
  • 未在根 index.ts 导出的类视为内部实现(如部分 Effect、CacheDB、WKTLayer2)。

3. 目录职责(改哪里)

目录何时改
viewer/Viewer 选项、相机模式、图层/特效缓存、全局行为
base/Position、Color、帧循环 Loop
overlay/entity/Entity 类图元(点线面体…)
overlay/primitive/Primitive / 3D Tiles / 水面等
overlay/html/DOM 叠加
layer/新图层类型、影像/地形 Provider
material/MaterialProperty + 与 effects/shader 联动
effects/ + effects/shader/后处理、天气、扫描;GLSL 放 shader/
analysis/空间分析
geomatics/量测、标绘、拾取
widget/地图周边 UI
event/新事件类型、事件基类
utils/纯工具、坐标转换、Suggestion
liteUtils/面向 Viewer 的快捷 API
assets/css/控件与覆盖物样式
plugin/可选插件(如 CacheDB)

不要把业务 Vue 组件、接口请求写进 core;那属于 packages/bizapps/*


4. 代码风格与约定

4.1 命名

类别约定示例
PascalCaseEntityLayer, ViewShed
实例私有字段_ 前缀_delegate, _viewer, _style
钩子_xxxHook / _xxxHandler / _xxxCallback_mountedHook
类型枚举对象模块内常量 + registerTypeOverlay.registerType('point')
文件与主类同名Point.tsexport default Point
模块出口index.ts 具名 re-exportexport { default as Point } from '...'

4.2 类模板(Overlay 子类)

参考 overlay/entity/Point.ts

ts
// 1. import Cesium 类型/类、Position、Util、Transform、父类
// 2. interface OPT extends CesiumXxx.ConstructorOptions { id?: string | number }
// 3. const DEF_OPT: OPT = { ...defaults }
// 4. class Xxx extends Overlay {
//      constructor(position|positions, options = DEF_OPT) {
//        校验参数 → super(options.id)
//        this._options = { ...DEF_OPT, ...options }
//        this._delegate = new Entity({ ... })
//        this.setStyle(this._options)
//        this.type = Overlay.getOverlayType('xxx')
//      }
//      set/get position(s)
//      _mountedHook() { 写 position;Util.merge(this._delegate.xxx, this._style) }
//      setStyle(style) { merge;return this }
//      static fromEntity?(entity) { ... }
//    }
// 5. Overlay.registerType('xxx')
// 6. export default Xxx

必须遵守:

  • 构造参数非法时 throw new Error('...')(中英文均可,与邻近文件一致)。
  • setStyle 删除不应进 style 的字段(如 position),Util.merge 合并到 _delegate 对应图形属性,return this
  • 文件末尾 Overlay.registerType('snake_or_lower'),与 getOverlayType 使用同一字符串。
  • JSDoc 写清 @public、参数、示例(demo 里可抄);利于 TypeDoc。

4.3 Layer 子类要点

参考 layer/EntityLayer.ts / layer/Layer.ts

  • super(options) 后设置 this._delegate(CustomDataSource / PrimitiveCollection 等)。
  • this.type = LayerType.XxxLayerType 字典需同步增加键)。
  • 通过 layerEvent 的 ADD/REMOVE 挂到 Viewer;Viewer 用 _layerCache[type][id] 索引。
  • Overlay 加入:Entity 走 entities.add,Primitive 走 collection.add(见 Overlay._addHandler)。

4.4 Effect / Analysis / Widget

  • Effect:继承 effects/Effect.ts_prepareDelegate 创建 postProcessStageaddToViewer
  • Analysis:继承 analysis/Analysis.ts;构造函数 (viewer, options);资源销毁方法尽量提供 destroy/clear
  • Widget:继承 widget/Widget.ts;实现 _init / install;需要跟随屏幕坐标时设 _positionChangeAble

4.5 Material(历史 JS)

  • material/ 仍以 JavaScript 为主,基类 MaterialProperty.js
  • 新材质:继承 MaterialProperty,实现 getType / getValue / equals,在 material/index.js 注册,GLSL 可放 effects/shader/
  • 若改为 TS,保持与现有 Property 接口一致,避免破坏 Material 命名空间导出。

4.6 类型与 any

  • 历史代码大量 any新代码尽量写清接口(options、style),至少补全 public 方法参数。
  • 允许 @ts-ignore 仅用于 Cesium 私有 API(如 globe shader),需简短注释原因。
  • 不引入与现有风格冲突的严格 eslint 大重构,除非任务明确要求。

4.7 注释与语言

  • 对外 API 注释:中文为主(与现有文件一致)。
  • 复杂算法可中英混合;避免无意义注释。

4.8 链式 API

公共变更方法尽量 return thisaddToLayer / addToViewer / setStyle / on 等。


5. 扩展清单(Checklist)

新增 Overlay

  1. overlay/entity|primitive|html/ 新建类文件(按 4.2 模板)。
  2. Overlay.registerType('name')
  3. overlay/index.ts 导出。
  4. index.ts import + export。
  5. apps/demo/src/overlay/... 增加演示页并挂路由/菜单。
  6. apps/docs/core/overlay/... 增加 md(可选但推荐)。
  7. pnpm run core:lib 确认类型与打包通过。

新增 Layer

  1. 继承 Layer,设置 _delegateLayerType
  2. layer/index.ts + 根 index.ts
  3. demo + docs。
  4. 若依赖新 Provider,注意异步 _addHandler(参考 TerrainLayer)。

新增 Analysis

  1. 继承 Analysis,文件放 analysis/
  2. analysis/index.ts + 根 index.ts
  3. 注意:分析类通常走 Layer 缓存,自行管理 Entity/Primitive,并在销毁时释放。

新增 Effect

  1. 继承 Effect,shader 放 effects/shader/
  2. effects/index.ts 导出;若需对外公开再写入根 index.ts(当前仅部分 Effect 对外导出)。

新增 Widget

  1. 继承 Widget,样式放 assets/css/
  2. widget/index.ts + 根 index.ts
  3. 需要默认随 Viewer 创建时改 viewer/Viewer.ts / config.ts(谨慎)。

修改 Viewer 默认行为

  • 默认 options 只改 viewer/config.tsDEF_OPTS
  • 构造副作用写在 Viewer 构造函数或 _init,保持幂等与可配置开关。

6. 依赖与构建注意

  • Cesium:由 monorepo 根 dependencies 提供;core 的 vite 构建会 打进包(未 external),并 copy cesiumStatic
  • 运行时:index.tsimport 'cesium/.../widgets.css'assets/css/index.scss,并尝试 globalThis.Cesium = Cesium
  • 新依赖:写入 packages/core/package.json;优先精确版本(与仓库习惯一致)。
  • 脚本:
    • pnpm run lib / 根目录 pnpm run core:lib:构建
    • pnpm run checkvue-tsc
    • typedoc:build:API 文档
  • 包导出字段:main UMD、module ES、typesstyleexports["."] 指向 ES + types。

SuperMap

superMap/ 为可选静态集成,经 exports["./superMap/*"] 与构建 copy 提供,不要与 Cesium 主路径强耦合逻辑混写,除非任务明确要求。


7. 测试与验证

  • 当前 几乎无自动化单测;验证手段:
    1. pnpm run core:lib 构建成功
    2. pnpm run demo:serve 手测对应页面
    3. 开发模式 Viewer 挂到 globalThis.viewer / Store.viewer,便于控制台调试
  • 新增复杂算法(分析、转换)时,鼓励补最小单测或 demo 可复现步骤;不要只改实现不给验证路径。

8. 反模式(不要做)

  1. 在 Overlay 里直接 viewer.entities.add,绕过 Layer。
  2. 业务侧到处使用 Cartesian3 而不用 Position
  3. 忘记 registerType / 忘记根 index.ts 导出导致「写了却 import 不到」。
  4. 在 core 内引入 element-plus、axios 业务接口、Vue 组件。
  5. 删除或改名 public API 而不做兼容说明(semver:破坏性变更应升版本并在 monorepo changelog/changeset 体现)。
  6. 大范围格式化无关文件、无关重构与任务混在同一提交。
  7. 把密钥、内网 token 写进仓库;影像 key 走配置/环境变量。

9. 常用代码锚点

需求先读
改默认底图/控件viewer/config.ts, viewer/Viewer.ts
新点线面overlay/entity/Point.ts
3D Tilesoverlay/primitive/Tileset.ts
图层基类layer/Layer.ts
事件枚举event/EventEnums.ts
坐标转换utils/convertor/Transform.ts
材质material/MaterialProperty.js, material/index.js
公共导出index.ts
演示写法apps/demo/src/**

10. 提交与协作建议

  • monorepo 使用 pnpm workspace + changesets;core 发包脚本 pub 指向私有 registry。
  • 文档三件套:
    • README.md — 人类快速上手
    • AGENTS.md — AI/协作者扩展约定(本文)
    • TODO.md — 已知缺口与规划

完成功能后自检:导出?demo?类型?销毁路径?是否破坏现有链式 API?

MGis 地理三维库