# API

> `@its-cool/simple-map` **2.2.27** · 基于 OpenLayers **10**  
> 本文档风格参考 [Vue 2 API](https://v2.cn.vuejs.org/v2/api/)：每个条目标明**类型 / 参数 / 返回值 / 用法示例**。  
> Playground 在线查看：[`/docs`](/docs) · Markdown 源文件：`playground/docs/API.md`

---

## 标注约定

| 标注 | 含义 |
|------|------|
| **自定义** | 本库新增的类、方法、属性或选项 |
| **OL** | OpenLayers 原生 API（继承、透传或直接调用） |
| **融合** | 同一对象上同时存在自定义字段与 OL 行为（挂载、混入 options、继承后再扩展） |

---

## 全局说明 · 项目结构

`simple-map` 是一层业务 GIS 引擎：对外提供 `Map` / 工具类；对内用 OpenLayers 完成渲染与交互。

### 模块解耦关系

```
@its-cool/simple-map（包入口 src/simpleMap.js）
│
├── Map（src/core/Map.js）          ← 业务门面（自定义）
│   ├── this.map : ol/Map           ← 渲染内核（OL）
│   ├── this.layers{}               ← 按 code 索引的业务图层字典（自定义）
│   ├── this.businessLayers{}       ← 业务图层配置（自定义）
│   └── prototype mixins
│       ├── baseMethods             视图 / 底图 / 测量 / 点数据
│       ├── layerMethods            建层 / 显隐 / 高亮 / 云图层
│       ├── analysisMethods         绘制查询 / 管网分析 / 统计
│       ├── toolMethods             Track / Inspection / Profile 工厂
│       └── internalMethods         点查、WFS、ArcGIS（内部）
│
├── Tools（src/tools/*）            可独立 new，也可由 Map 方法创建
├── Layers（src/layers/*）          未从包入口导出，由 Map._getLayer 创建
├── Sources（src/sources/*）        底图瓦片源，配合 TileLayer
└── transformCoord / mapTools       无地图依赖或弱依赖工具
```

### 运行时对象关系（融合核心）

```
业务 Map 实例
  ├─ map ──────────────► ol/Map
  │                        └─ .business ──► 指回业务 Map（点击事件反查）
  ├─ layers.baseLayers     底图组 { osm: [TileLayer…], gaode: […] }
  ├─ layers.highlight      高亮 VectorLayer
  ├─ layers[code]          业务图层（多为 extends ol/layer/*）
  ├─ overview?             ol/control/OverviewMap + .baseLayers（自定义挂载）
  └─ measureTool / drawSearchTool / track …
```

### 设计原则

1. **业务入口走 `Map` 方法**：如 `displayLayer`、`drawPoint`，会同步维护 `layers` 字典与 WMS `LAYERS` 参数。
2. **渲染细节走 `map.map`（OL）**：如临时监听 `pointermove`、取 `getView().getResolution()`。
3. **图层类多采用「继承 OL + `Object.assign(this, options)`」**：同一实例上既有 `setVisible()`（OL），也有 `addGraphics()`（自定义）。

### 包入口导出

```js
import {
  Map,
  transformCoord,
  Draw, Measure, Tip, WriteServer, DrawSearch, Track, Inspection, Profile,
  mapTools
} from '@its-cool/simple-map';
import '@its-cool/simple-map/style.css';
```

| 导出 | 类型 | 说明 |
|------|------|------|
| `Map` | `class` | 业务地图 |
| `transformCoord` | `Function` | 坐标转换 |
| `Draw` / `Measure` / `DrawSearch` | `class` | 绘制系（extends `ol/layer/Vector`） |
| `WriteServer` / `Inspection` / `Profile` | `class` | 编辑 / 巡检 / 剖面（extends Vector） |
| `Track` / `Tip` | `class` | 轨迹 / 提示（组合 OL Layer，非业务门面必需） |
| `mapTools` | `Object` | 独立工具函数 |
| `default` | `Object` | 上述聚合 |

> `Layers` / `Sources` **未**从包入口导出。

---

## 安装与快速开始

### 安装

* **类型**：环境要求
* **用法**：

```bash
npm install @its-cool/simple-map
```

Node `>=14.18.0`。`ol` / `proj4` / `turf` 已打入产物，一般无需再装。

### 快速开始

示例页：[`/basic`](/basic)

```js
import { Map } from '@its-cool/simple-map';
import '@its-cool/simple-map/style.css';

const map = new Map('map', {
  centerX: 13528430,
  centerY: 3676466,
  zoom: 11,
  wkid: 3857,
  initBaseLayer: 'osm',
  baseLayers: {
    osm: [{ type: 'OSMLayer', layerType: 'org' }]
  },
  callback: {
    layersReadyCallback() {
      console.log('图层初始化完成');
    },
    clickCallback(features) {
      console.log(features);
    }
  }
});

map.initLayers({});
```

```html
<div id="map" style="width:100%;height:500px;"></div>
```

---

## 全局配置 · `Map` 构造函数

### new Map(domId, options)

* **类型**：`constructor`
* **归属**：自定义（内部创建 **OL** `Map` / `View`）
* **参数**：
  * `{string} domId` — 地图容器元素的 `id`（传给 `ol/Map` 的 `target`）
  * `{Object} options` — 见下方选项表。**融合**：会 `Object.assign` 进 `ol/View`，因此 OL View 合法字段（如 `maxZoom`）也可直接传入
* **返回值**：`Map` 业务实例
* **用法**：

```js
const map = new Map('map', {
  centerX: 116.4,
  centerY: 39.9,
  zoom: 12,
  wkid: 3857,
  maxZoom: 18,          // 同时作为 OL View 选项
  overview: true,
  callback: { layersReadyCallback() {} }
});
```

* **融合说明**：
  * `this.map = new ol/Map(...)`
  * `this.map.business = this`（事件反查）
  * `viewOptions = Object.assign({ center, constrainResolution, enableRotation, maxZoom }, options)`

#### options 选项

##### centerX / centerY

* **类型**：`number`
* **必填**：是（常规用法）
* **说明**：初始中心坐标，写入 View 的 `center: [centerX, centerY]`。在 `wkid: 3857` 下一般为 Web 墨卡托米制坐标。

##### zoom

* **类型**：`number`
* **归属**：融合（OL View）
* **说明**：初始缩放级别。

##### wkid

* **类型**：`number | string`
* **默认值**：业务侧通常传 `3857`
* **说明**：
  * `3857`：Web 墨卡托，不注册自定义投影
  * `4326` / `4490` / `4549`：内置 proj4 定义，注册为 `custom`
  * 其它：当作 proj4 定义串使用
* **用法**：

```js
new Map('map', { centerX: 120.1, centerY: 30.2, zoom: 10, wkid: 4326 });
```

##### origin

* **类型**：`number[]`
* **说明**：自定义投影下瓦片原点，挂到 `projection.origin`，供 ArcGIS 切片等使用。

##### maxZoom / minZoom / constrainResolution / enableRotation / …

* **类型**：见 [OL View](https://openlayers.org/en/latest/apidoc/module-ol_View-View.html)
* **归属**：OL（经 `Object.assign` 传入）
* **默认值**：本库默认 `constrainResolution: true`、`enableRotation: false`、`maxZoom: 18`

##### baseLayers

* **类型**：`{ [baseKey: string]: Array<BaseLayerOption> }`
* **说明**：底图分组。每个 `BaseLayerOption` 至少含 `type`（如 `OSMLayer`、`GaodeLayer`、`TDTLayer`）。
* **用法**：

```js
baseLayers: {
  osm: [{ type: 'OSMLayer', layerType: 'org' }],
  gaode: [{ type: 'GaodeLayer', layerType: 'raster' }]
},
initBaseLayer: 'osm'
```

##### initBaseLayer

* **类型**：`string`
* **说明**：初始可见的底图组 key，对应 `baseLayers` 的键名。

##### fixedLayers / fixedLayerCodes

* **类型**：`Array<Object>` / `Array<string>`
* **说明**：固定叠加层及其初始可见 code 列表。

##### overview

* **类型**：`boolean | string`
* **默认值**：不启用
* **说明**：为真时创建 **OL** `OverviewMap`；若为字符串，追加到 CSS class。实例挂在 `map.overview`，并带自定义 `overview.baseLayers`。

##### callback

* **类型**：`Object`
* **说明**：业务回调集合，见下一节。

##### codeField

* **类型**：`string`
* **默认值**：`'objCode'`
* **说明**：要素业务主键字段名，点查 / 高亮 / 编辑共用。

##### allFields

* **类型**：`boolean | string`
* **默认值**：`false`
* **说明**：
  * `true`：点查返回全部字段
  * `false`：仅查 `codeField`
  * `string`：作为 WFS `propertyName`

##### imageBase

* **类型**：`string`
* **说明**：图标等静态资源基路径。

##### postGIS

* **类型**：`boolean`
* **说明**：写服务 / GeoServer 相关行为开关。

##### refreshLayers

* **类型**：`boolean`
* **说明**：为真时，分辨率变化清空矢量瓦片 source（`initLayers` 内绑定）。

---

### callback 选项

业务回调挂在构造函数 `options.callback` 上。

#### layersReadyCallback

* **类型**：`Function`
* **参数**：无
* **说明**：`initLayers` 完成建层、创建测量/绘制工具后调用。
* **用法**：

```js
callback: {
  layersReadyCallback() {
    map.showLayers(['pipe', 'valve']);
  }
}
```

#### clickCallback

* **类型**：`Function`
* **参数**：
  * `{Array} features` — 命中的业务要素摘要（实现依赖内部 `_clickFun`）
* **说明**：地图点击查询到要素后回调（需 `clickMap === true`）。

#### extentChangeCallback

* **类型**：`Function`
* **说明**：若提供，则监听 View `change`，视野变化时触发。

---

## 实例属性

以下属性在 `new Map` 之后可用。

### map

* **类型**：`ol/Map`
* **归属**：OL
* **说明**：底层 OpenLayers 地图。完整 OL API 均可通过它调用。
* **用法**：

```js
const view = map.map.getView();
map.map.on('moveend', () => console.log(view.getZoom()));
```

* **注意**：直接 `map.map.addLayer(layer)` **不会**写入 `map.layers`，业务方法可能找不到该层。业务图层请用 `initLayers` / `addLayer`。

### layers

* **类型**：`Object`
* **归属**：自定义
* **说明**：图层字典。常见键：
  * `baseLayers`：`{ [type]: ol/layer/Layer[] }`
  * `highlight`：高亮层
  * `geoserver` / `arcgis`：聚合服务层
  * `[layerCode]`：业务图层实例
* **用法**：

```js
map.layers['valve'].setVisible(true); // OL 方法挂在自定义图层实例上
```

### businessLayers

* **类型**：`Object | undefined`
* **说明**：`initLayers` 之后按 `code` 存储的业务配置（含 `type`、`serviceAddress`、`parameter` 等）。

### projection

* **类型**：`proj4.Proj | undefined`
* **归属**：融合
* **说明**：`wkid !== 3857` 时存在；可能带自定义 `origin`。

### overview

* **类型**：`ol/control/OverviewMap | undefined`
* **归属**：融合
* **说明**：鹰眼控件；另有自定义 `overview.baseLayers`。

### initView

* **类型**：`{ center: number[], zoom: number }`
* **说明**：初始视图，供 `resetMap()` 使用。

### codeField / allFields / imageBase / postGIS / refreshLayers

* **类型**：见构造选项
* **说明**：构造时写入的实例配置。

### clickMap

* **类型**：`boolean`
* **默认值**：`true`
* **说明**：为 `false` 时抑制地图点查（绘制/分析过程中常被临时关闭）。

### callback

* **类型**：`Object`
* **说明**：构造传入的回调引用。

### measureTool / drawSearchTool

* **类型**：`Measure` / `DrawSearch`
* **说明**：`initLayers` 后创建。

### track / pipeInspectionTool

* **类型**：`Track` / `Inspection | undefined`
* **说明**：对应工厂方法创建后挂载。

---

## Map 方法 · 视图与生命周期

示例页：[`/controls`](/controls)

### changeGisConfig(options)

* **类型**：`Function`
* **归属**：自定义
* **参数**：
  * `{Object} options`
    * `{number} [options.centerX]` — 新中心 X
    * `{number} [options.centerY]` — 新中心 Y
    * `{number} [options.zoom]` — 新级别
    * `{Array<string>} [options.fixedLayerIds]` — 要显示的固定层 code；未列出的固定层隐藏
* **返回值**：无
* **相关 OL**：`View.setCenter` / `setZoom`；`layer.setVisible`
* **用法**：

```js
map.changeGisConfig({
  centerX: 13528430,
  centerY: 3676466,
  zoom: 14,
  fixedLayerIds: ['boundary']
});
```

### destroy()

* **类型**：`Function`
* **归属**：自定义
* **参数**：无
* **返回值**：无
* **相关 OL**：`map.dispose()`
* **用法**：

```js
// Vue beforeUnmount
map.destroy();
map = null;
```

### zoomIn()

* **类型**：`Function`
* **参数**：无
* **返回值**：无
* **说明**：当前级别 +1（动画）。
* **用法**：

```js
map.zoomIn();
```

### zoomOut()

* **类型**：`Function`
* **参数**：无
* **返回值**：无
* **说明**：当前级别 -1（动画）。
* **用法**：

```js
map.zoomOut();
```

### resetMap()

* **类型**：`Function`
* **参数**：无
* **返回值**：无
* **说明**：动画回到 `initView`。
* **用法**：

```js
map.resetMap();
```

### setExtent(extent)

* **类型**：`Function`
* **参数**：
  * `{number[]} extent` — `[minX, minY, maxX, maxY]`，地图投影坐标
* **返回值**：无
* **相关 OL**：`View.fit(extent, { duration: 1000 })`
* **用法**：

```js
map.setExtent([13520000, 3670000, 13530000, 3680000]);
```

### getCenterAndZoom()

* **类型**：`Function`
* **参数**：无
* **返回值**：`{ x: number, y: number, zoom: number }`
* **用法**：

```js
const { x, y, zoom } = map.getCenterAndZoom();
console.log(x, y, zoom);
```

### offset(zoom, param)

* **类型**：`Function`
* **参数**：
  * `{number|null} zoom` — 目标级别；可不改级别
  * `{Object} param` — 传给内部 `_locateTo`，常用 `{ offset: [dx, dy] }`（像素或逻辑偏移，由实现解释）
* **返回值**：无
* **用法**：

```js
map.offset(null, { offset: [0, -80] }); // 视野上移，露出底部面板
```

### locateTo(x, y, zoom, param?)

* **类型**：`Function`
* **归属**：自定义
* **参数**：
  * `{number} x` — 目标点 X（地图投影）
  * `{number} y` — 目标点 Y
  * `{number} [zoom]` — 目标级别
  * `{Object} [param]`
    * `{boolean} [param.symbol]` — 是否打定位符号（默认相关逻辑见 `_locateTo`）
    * `{Array} [param.offset]` — 中心偏移
* **返回值**：无
* **说明**：先清空高亮层，再定位。
* **用法**：

```js
map.locateTo(13528430, 3676466, 16, { symbol: true });
```

### locateToPolygon(data)

* **类型**：`Function`
* **参数**：
  * `{Array<number[]>} data` — 折线/环坐标序列 `[[x,y], …]`；若存在自定义 `projection` 会先转到 3857
* **返回值**：无
* **相关 OL**：`View.fit(new LineString(data))`
* **用法**：

```js
map.locateToPolygon([
  [13528000, 3676000],
  [13529000, 3676000],
  [13529000, 3677000]
]);
```

### locateByLngLat(lng, lat)

* **类型**：`Function`
* **参数**：
  * `{number} lng` — WGS84 经度
  * `{number} lat` — WGS84 纬度
* **返回值**：无
* **说明**：转为墨卡托，在高亮层打 `type:'mark'` 点并居中。
* **用法**：

```js
map.locateByLngLat(120.15, 30.28);
```

### locateToCurrentPosition(lng, lat, zoom?, from?, to?)

* **类型**：`Function`
* **参数**：
  * `{number} lng`
  * `{number} lat`
  * `{number} [zoom]`
  * `{string} [from]` — 源坐标系名，见 `Transform`（如 `'wgs84'`、`'gcj02'`）
  * `{string} [to]` — 目标坐标系名（如 `'webmercator'`、`'map'`）
* **返回值**：无
* **说明**：调用 `changeCurrentPosition` 后 `setCenter` / 可选 `setZoom`。
* **用法**：

```js
map.locateToCurrentPosition(120.15, 30.28, 15, 'wgs84', 'webmercator');
```

### changeCurrentPosition(lng, lat, from?, to?)

* **类型**：`Function`
* **参数**：同 `locateToCurrentPosition` 的坐标与坐标系参数
* **返回值**：`number[]` — 转换后的地图坐标 `[x, y]`
* **说明**：更新高亮层中 `type:'current'` 的定位点，**不**强制改 zoom。
* **用法**：

```js
const coord = map.changeCurrentPosition(120.15, 30.28, 'gcj02', 'map');
```

---

## Map 方法 · 底图与鹰眼

示例页：[`/baselayer`](/baselayer)

### changeBaseLayer(type)

* **类型**：`Function`
* **参数**：
  * `{string} type` — `baseLayers` 的键，如 `'osm'`、`'gaode'`
* **返回值**：无
* **说明**：仅该组底图 `setVisible(true)`，其它组隐藏；若有鹰眼则同步。
* **用法**：

```js
map.changeBaseLayer('gaode');
```

### displayOverview()

* **类型**：`Function`
* **参数**：无
* **返回值**：无
* **相关 OL**：`overview.setCollapsed(!overview.getCollapsed())`
* **用法**：

```js
map.displayOverview();
```

---

## Map 方法 · 测量与坐标

示例页：[`/measure`](/measure)、[`/transform`](/transform)

### measure(type)

* **类型**：`Function`
* **参数**：
  * `{string} type` — `'length'`（或其它非 `area`）测距；`'area'` 测面
* **返回值**：无
* **说明**：先 `cancelMeasure`，再调用 `measureTool.measure`。需已 `initLayers`。
* **用法**：

```js
map.measure('length');
map.measure('area');
```

### cancelMeasure()

* **类型**：`Function`
* **参数**：无
* **返回值**：无
* **说明**：取消当前测量交互。

```js
map.cancelMeasure();
```

### clearMeasure()

* **类型**：`Function`
* **参数**：无
* **返回值**：无
* **说明**：清空测量图形与结果。

```js
map.clearMeasure();
```

### transformCoordinate(data, from, to, projectionCode?)

* **类型**：`Function`
* **参数**：
  * `{number[]} data` — `[x, y]` 或 `[lng, lat]`
  * `{string} from` — 源坐标系：`'wgs84'` | `'gcj02'` | `'webmercator'` | `'map'` 等
  * `{string} to` — 目标坐标系
  * `{string|proj4.Proj} [projectionCode]` — `to === 'map'` 或自定义投影时使用
* **返回值**：`number[]` — 转换后坐标
* **用法**：

```js
const merc = map.transformCoordinate([120.15, 30.28], 'wgs84', 'webmercator');
const wgs = map.transformCoordinate(merc, 'webmercator', 'wgs84');
```

### getNavigationCoord(x, y)

* **类型**：`Function`
* **参数**：
  * `{number} x` — Web 墨卡托 X
  * `{number} y` — Web 墨卡托 Y
* **返回值**：`number[]` — WGS84 `[lng, lat]`
* **用法**：

```js
const [lng, lat] = map.getNavigationCoord(13528430, 3676466);
```

---

## Map 方法 · 服务编辑入口

### writeServer(options?)

* **类型**：`Function`
* **归属**：自定义（返回 **融合** 类 `WriteServer`）
* **参数**：
  * `{Object} [options]`
    * `{string} [options.addType]` — `'geoserver'` | `'arcgis'`
    * `{string[]} [options.layerCodes]` — 参与编辑的业务图层 code
    * `{string} [options.serviceAddress]` — 服务地址 / workspace
    * `{string[]} [options.queryLayerCodes]` — ArcGIS 查询子层 code（会映射为 layerId）
    * `{string} [options.codeField]` — 覆盖实例默认主键
    * 其它字段原样传给 `WriteServer` 构造
* **返回值**：`WriteServer`
* **说明**：自动注入 `postGIS`、当前 `geoserver` 图层、`vectorTileLayers`、`codeField` 等。
* **用法**：

```js
const editor = map.writeServer({
  addType: 'geoserver',
  layerCodes: ['pipe', 'valve']
});
editor.insertFeature('Point', { objCode: 'V001', name: '阀门1' });
```

---

## Map 方法 · 点与告警数据

### drawPoint(data, clear?)

* **类型**：`Function`
* **参数**：
  * `{Object<string, Array<Object>>} data` — key 为 `layerCode`，value 为点属性数组。点对象常用字段：
    * `{string|number} objCode` — 主键
    * `{number} gpsX` / `{number} gpsY` 或几何相关字段（由 CloudLayer 解析）
    * `{number} [alarm]` — 告警等级
    * 其它业务属性、飘窗 HTML 等
  * `{boolean} [clear]` — 为 `true` 时先 `clear` 该层再添加
* **返回值**：无
* **说明**：图层必须已在 `businessLayers` / `layers` 注册；关联图层（热力/聚合等）会 `setData`。
* **用法**：

```js
map.drawPoint({
  hydrant: [
    { objCode: 'H1', gpsX: 13528430, gpsY: 3676466, alarm: 0, name: '栓1' },
    { objCode: 'H2', gpsX: 13528500, gpsY: 3676500, alarm: 1 }
  ]
}, true);
```

### clearPoint()

* **类型**：`Function`
* **参数**：无
* **返回值**：无
* **说明**：清空所有 `type === '1'`（云点层）的图形。

```js
map.clearPoint();
```

### removePoint(data)

* **类型**：`Function`
* **参数**：
  * `{Object<string, Array>} data` — 每层要移除的图形标识列表（交给 `removeGraphics`）
* **返回值**：无
* **用法**：

```js
map.removePoint({ hydrant: ['H1', 'H2'] });
```

### drawInspectionPoint(layerCode, data)

* **类型**：`Function`
* **参数**：
  * `{string} layerCode`
  * `{Object<string, Array<Object>>} data` — key 为要素 id；`data[id][0]` 含 `gpsX`/`gpsY` 等
* **返回值**：无
* **相关 OL**：`Feature` / `Point` / `source.addFeature` / `setGeometry`
* **用法**：

```js
map.drawInspectionPoint('patrol', {
  P1: [{ gpsX: 13528430, gpsY: 3676466 }]
});
```

### refreshAlarm(data)

* **类型**：`Function`
* **参数**：
  * `{Object<string, Array|Object>} data` — `{ [layerCode]: alarmPayload }`
* **返回值**：无
* **用法**：

```js
map.refreshAlarm({ hydrant: ['H1', 'H2'] });
```

### refreshPoint(data)

* **类型**：`Function`
* **参数**：
  * `{Object<string, *>} data` — 交给各层 `refreshData`
* **返回值**：无

```js
map.refreshPoint({ hydrant: updatedList });
```

### refreshGridPoint(data, polygon)

* **类型**：`Function`
* **参数**：
  * `{Object} data` — 网格点数据
  * `{Object|Array} polygon` — 网格范围
* **返回值**：无
* **说明**：若配置了 `relateLayerCodes`，会一并传入关联层。

---

## Map 方法 · 图层管理

### initLayers(businessLayers, tagLayers?, alarmList?)

* **类型**：`Function`
* **归属**：自定义（内部大量 **OL** 建层）
* **参数**：
  * `{Object|Array} businessLayers` — 业务图层配置表（常来自 GIS_LAYER_CONFIG）。每一项关键字段：
    * `{string} code` — 图层唯一编码
    * `{string} type` — 见下方 type 表（`'1'`…`'15'` 或字面量如 `'CloudLayer'`）
    * `{string} [serviceAddress]` — 服务名 / URL
    * `{number} [serviceSublayerIndex]` — 子层顺序
    * `{string|Object} [parameter]` — JSON 字符串或对象，会 merge 进配置
    * `{string|Object} [label]` — 标注配置
    * `{string} [style]` — WMS 样式名等
    * `{boolean} [visible]`
  * `{Array<Object>} [tagLayers]` — 标注层配置
  * `{Array<{value, color}>} [alarmList]` — 告警等级配色
* **返回值**：无
* **副作用**：写入 `businessLayers`、`layers`；创建 `drawSearchTool`、`measureTool`；调用 `callback.layersReadyCallback()`
* **用法**：

```js
map.initLayers({
  pipe: {
    code: 'pipe',
    type: '5',
    serviceAddress: 'water',
    serviceSublayerIndex: 0,
    parameter: JSON.stringify({ queryable: true })
  },
  hydrant: {
    code: 'hydrant',
    type: '1',
    minZoom: 12,
    label: { minZoom: 14, field: 'name' }
  }
});
```

#### businessLayers.type 一览

| type | 含义 | 底层 |
|------|------|------|
| `1` / `CloudLayer` | 点 + 飘窗 | CloudLayer → `ol/layer/Vector` |
| `2`/`3` | ArcGIS 动态 | `ImageArcGISRest` + `ImageLayer` |
| `4` | ArcGIS 切片 | 自定义 Source + `TileLayer` |
| `5` | GeoServer WMS 聚合 | `ImageWMS`（字典键常为 `geoserver`） |
| `6` | 矢量瓦片 | VectorTileLayer |
| `7` | SuperMap WMS | WMS |
| `9` / `WMTSLayer` | WMTS | `ol/source/WMTS` |
| `11` / `GLayer` | 通用矢量 | GLayer |
| `12` / `ClusterLayer` | 聚合 | ClusterLayer |
| `13` / `ContourLayer` | 等值 | ContourLayer |
| `14` / `EchartsLayer` | ECharts | ol-echarts |
| `15` / `HeatmapLayer` | 热力 | `ol/layer/Heatmap` |

### addLayer(options)

* **类型**：`Function`
* **参数**：
  * `{Object} options` — 至少含 `code`、`type`；其它同 `initLayers` 单项；支持 `parameter` / `label` JSON 字符串
* **返回值**：`Object|null` — 图层实例；缺 `code` 时返回 `null`
* **用法**：

```js
map.addLayer({
  code: 'tempPoint',
  type: 'CloudLayer',
  minZoom: 10
});
map.drawPoint({
  tempPoint: [{ objCode: 'T1', gpsX: 13528430, gpsY: 3676466 }]
});
```

### removeLayer(layerCode)

* **类型**：`Function`
* **参数**：
  * `{string} layerCode`
* **返回值**：无
* **相关 OL**：`map.removeLayer`
* **用法**：

```js
map.removeLayer('tempPoint');
```

### displayLayer(layerCode, bool)

* **类型**：`Function`
* **归属**：融合
* **参数**：
  * `{string} layerCode`
  * `{boolean} bool` — 是否显示
* **返回值**：无
* **说明**：按图层 type 分支：WMS/ArcGIS 会改 source `params`；矢量层调用 `setVisible`。
* **用法**：

```js
map.displayLayer('pipe', true);
map.displayLayer('hydrant', false);
```

### showLayers(layerCodes)

* **类型**：`Function`
* **参数**：
  * `{string[]} layerCodes` — 要显示的 code 列表；未列出的业务层隐藏
* **返回值**：无
* **用法**：

```js
map.showLayers(['pipe', 'valve', 'hydrant']);
```

### showTagLayers(layerCodes, tagTypes)

* **类型**：`Function`
* **参数**：
  * `{string[]} layerCodes`
  * `{string[]} tagTypes` — 标注类型
* **返回值**：无
* **用法**：

```js
map.showTagLayers(['pipe'], ['diameter', 'material']);
```

### displayPartInLayer(data)

* **类型**：`Function`
* **参数**：
  * `{Object<string, string|string[]|null>} data` — 每层要显示的 `objCode` 列表；`null` 可恢复
* **返回值**：无
* **用法**：

```js
map.displayPartInLayer({
  hydrant: ['H1', 'H3'],
  pipe: ['P100']
});
```

### displayPartByCondition(data)

* **类型**：`Function`
* **参数**：
  * `{Object} data` — 每层条件：数组走 `displayPart`；对象则写 CQL / 样式条件（依 type）
* **返回值**：无
* **用法**：

```js
map.displayPartByCondition({
  pipe: { caliber: 'DN200' },
  hydrant: [{ field: 'alarm', value: 1 }]
});
```

### changeLayerStatus(layerCode, status)

* **类型**：`Function`
* **参数**：
  * `{string} layerCode`
  * `{*} status` — 状态值（点图层样式切换）
* **返回值**：无

```js
map.changeLayerStatus('hydrant', 1);
```

### changeLayerScope(data)

* **类型**：`Function`
* **参数**：
  * `{Object} data` — 范围过滤数据
* **返回值**：无

---

## Map 方法 · 云图层（飘窗）

飘窗基于 **OL** `Overlay`；本库扩展了 `Overlay.prototype.setVisible`（融合）。

### addCloud(layerCode, cloudData)

* **类型**：`Function`
* **参数**：
  * `{string} layerCode`
  * `{Object|Array} cloudData` — 飘窗数据（含定位与 DOM/HTML）
* **返回值**：无

```js
map.addCloud('hydrant', {
  objCode: 'H1',
  content: '<div class="cloud">栓体信息</div>'
});
```

### addCloudLayer(options)

* **类型**：`Function`
* **参数**：`{Object} options` — 云图层配置
* **返回值**：无

### hideCloud(layerCode, objCode) / showCloud(layerCode, objCode)

* **类型**：`Function`
* **参数**：
  * `{string} layerCode`
  * `{string|number} objCode`
* **返回值**：无

```js
map.hideCloud('hydrant', 'H1');
map.showCloud('hydrant', 'H1');
```

### hideAllClouds(layerCode) / showAllClouds(layerCode, hideClouds?)

* **类型**：`Function`
* **参数**：
  * `{string} layerCode`
  * `{Array} [hideClouds]` — `showAllClouds` 时仍保持隐藏的 code 列表
* **返回值**：无

### clearCloudLayer(layerCode)

* **类型**：`Function`
* **参数**：`{string} layerCode`
* **返回值**：无

### addHighlightCloud(data) / destroyHighlightCloud(objCode)

* **类型**：`Function`
* **说明**：高亮专用飘窗的添加与销毁。

---

## Map 方法 · 高亮

### clearHighlight()

* **类型**：`Function`
* **参数**：无
* **返回值**：无

```js
map.clearHighlight();
```

### highlightList(data, param?)

* **类型**：`Function`
* **参数**：
  * `{Array|Object} data` — 待高亮列表
  * `{Object} [param]` — 样式 / 是否定位等
* **返回值**：无

```js
map.highlightList([
  { objCode: 'P1', objX: 13528430, objY: 3676466 },
  { objCode: 'P2', objXStart: 13528400, objYStart: 3676400, objXEnd: 13528500, objYEnd: 3676500 }
]);
```

### triggerHighlight(index, type, cloudData?, options?, lineData?)

* **类型**：`Function`
* **参数**：
  * `{number} index` — 列表项索引
  * `{string} type` — 高亮类型
  * `{*} [cloudData]` — 飘窗
  * `{Object} [options]`
  * `{*} [lineData]` — 线高亮数据
* **返回值**：无

```js
map.triggerHighlight(0, 'point', { html: '当前选中' });
```

### resetHighlight() / hideHighlight() / showHighlight()

* **类型**：`Function`
* **参数**：无
* **返回值**：无

### highlightGraphicInLayer(layerCode, objCode, noFeature?)

* **类型**：`Function`
* **参数**：
  * `{string} layerCode`
  * `{string|number} objCode`
  * `{boolean} [noFeature]` — 是否不依赖已有 Feature
* **返回值**：无

```js
map.highlightGraphicInLayer('hydrant', 'H1');
```

---

## Map 方法 · GLayer / 等值线

### addGLayer(options)

* **类型**：`Function`
* **参数**：`{Object} options` — 含 `code` 等，type 为 GLayer
* **返回值**：图层实例相关（内部 `_addLayer`）

```js
map.addGLayer({ code: 'sketch', type: 'GLayer' });
map.layers.sketch.addPoint([13528430, 3676466], { fill: '#f00' }, 'A');
```

### displayGLayer(layerCode, bool)

* **类型**：`Function`
* **参数**：`{string} layerCode`，`{boolean} bool`
* **返回值**：无

### addContour(options) / cancelContour()

* **类型**：`Function`
* **参数**：`addContour` 接收等值配置（采样点、分级色带等，见 ContourLayer）
* **返回值**：无

```js
map.addContour({ /* 点值与样式 */ });
map.cancelContour();
```

---

## Map 方法 · 分析与查询

示例页：[`/draw`](/draw)、[`/advanced`](/advanced)

### drawSearch(callback, param?)

* **类型**：`Function`
* **参数**：
  * `{Function} callback` — 查询完成回调
  * `{Object} [param]` — 绘制类型、过滤图层等
* **返回值**：无（无有效 callback 则直接 return）

```js
map.drawSearch((results, num) => {
  console.log('命中', num, results);
}, { type: 'Polygon' });
```

### cancelDrawing() / clearDrawing()

* **类型**：`Function`
* **参数**：无
* **返回值**：无

```js
map.cancelDrawing();
map.clearDrawing();
```

### getDrawResult(callback)

* **类型**：`Function`
* **参数**：
  * `{Function} callback(results, resultsNum)`
* **返回值**：无

```js
map.getDrawResult((results, num) => console.log(results, num));
```

### circleSearch(data, callback, radius?, options?)

* **类型**：`Function`
* **归属**：融合（内部创建 **OL** VectorLayer 画圆）
* **参数**：
  * `{Object} data` — 至少含 `objX`、`objY`（圆心，地图坐标）
  * `{Function} [callback]` — 返回命中 code 列表
  * `{number} [radius]` — 缓冲半径（公里级，turf buffer；默认约 `0.01`）
  * `{Object} [options]`
    * `{string} [options.layerCode]` — 仅在该云图层的 `turfGeometries` 上本地相交
    * `{string} [options.color]` — 命中要素临时样式色
* **返回值**：无
* **用法**：

```js
map.circleSearch(
  { objX: 13528430, objY: 3676466 },
  (codes) => console.log(codes),
  0.05,
  { layerCode: 'hydrant', color: '#f00' }
);
```

### cancelCircleSearch()

* **类型**：`Function`
* **说明**：当前为空实现占位。

### analysis(type, options)

* **类型**：`Function`
* **参数**：
  * `{string} type` — 分析模式，见下表
  * `{Object} options`
    * `{string[]} options.analysisLayerCodes` — 参与查询的图层
    * `{Function} options.finishCallback` — 结束回调，参数随 type 变化
    * `{Array} [options.data]` — 结果回显数据（`result` / `closeValveResult` 等）
* **返回值**：无
* **用法**：

```js
map.analysis('crossSection', {
  analysisLayerCodes: ['pipe'],
  finishCallback(objCodes, distances) {
    console.log(objCodes, distances);
  }
});
```

#### analysis type

| type | 交互 | finishCallback 典型参数 |
|------|------|-------------------------|
| `slope` | 绘面 | `(objCodes)` |
| `crossSection` | 绘线 | `(objCodes, distance[])` |
| `verticalSection` | 两点选管线 | `(results[])` |
| `verticalSectionResult` | 无交互，画结果线 | — |
| `flowDirection` | 绘面 | `(objCodes)` |
| `result` | 用 `options.data` 画流动画 | — |
| `trace` / `traceSource` / `connectedness` | 点选管线 | `(objCodes)` |
| `closeValve` | 点选 | `(objCodes)` |
| `closeValveResult` | 画关阀结果 | — |
| `point` | 点选管点 | `(objCodes)` |

### cancelAnalysis()

* **类型**：`Function`
* **参数**：无
* **返回值**：无

```js
map.cancelAnalysis();
```

### statistics(layerCodes, options?)

* **类型**：`Function`
* **参数**：
  * `{string[]} layerCodes`
  * `{Object} [options]` — 传给 `layer.changeStyle`；省略则 `layer.resume()`
* **返回值**：无

```js
map.statistics(['pipe'], { /* 分级样式 */ });
map.statistics(['pipe']); // 恢复
```

### statisticsByField(callback, options)

* **类型**：`Function`
* **参数**：
  * `{Function} callback(result)` — `result` 为 `{ [layerCode]: AggregationResults }`
  * `{Object} options` — 可含 `layerCodes` 过滤，以及统计字段等（并入 `_statistics`）
* **返回值**：无
* **说明**：用户绘面后对 GeoServer 图层做聚合统计。

```js
map.statisticsByField((result) => {
  console.log(result);
}, { layerCodes: ['pipe'] });
```

### isPointInRange(data, coordinates)

* **类型**：`Function`
* **参数**：
  * `{Object} data` — 含 `objX`、`objY`
  * `{number[][]} coordinates` — 多边形环；若不闭合会自动闭合
* **返回值**：`boolean`

```js
const inside = map.isPointInRange(
  { objX: 13528430, objY: 3676466 },
  [[x1,y1],[x2,y2],[x3,y3],[x1,y1]]
);
```

### getPointsInRange(data, coordinates)

* **类型**：`Function`
* **参数**：
  * `{Array<Object>} data` — 点列表（含 `objX`/`objY`/`objCode`）
  * `{number[][]} coordinates` — 多边形环
* **返回值**：`Array` — 落在范围内的 `objCode` 列表

```js
const codes = map.getPointsInRange(list, ring);
```

---

## Map 方法 · 工具工厂

示例页：[`/advanced`](/advanced)

### addTrack(callback, options?)

* **类型**：`Function`
* **参数**：
  * `{Function} callback` — 播放过程回调
  * `{Object} [options]`
    * `{string} [options.lineColor]` — 默认 `'green'`
    * `{number} [options.lineWidth]` — 默认 `6`
    * `{string} [options.passedLineColor]` — 默认 `'#0ff'`
    * `{boolean} [options.showLine]` — 默认 `true`
    * `{Array} [options.list]` — 初始轨迹点（含 `gpsX`/`gpsY`/`uploadTime`）
    * `{number} [options.lineZIndex]` / `{number} [options.markerZIndex]`
* **返回值**：`Track`
* **说明**：若已有 `this.track` 会先 `destroy`。
* **用法**：

```js
const track = map.addTrack((index) => console.log('play', index), {
  lineColor: '#22c55e',
  list: [
    { gpsX: 13528400, gpsY: 3676400, uploadTime: '2024-01-01 10:00:00' },
    { gpsX: 13528500, gpsY: 3676500, uploadTime: '2024-01-01 10:05:00' }
  ]
});
track.play(0);
```

### pipeInspection(callback, options)

* **类型**：`Function`
* **参数**：
  * `{Function} callback`
  * `{Object} options`
    * `{string[]} [options.cloudLayerCodes]` — 参与缓冲的云图层
    * 其它 Inspection 选项
* **返回值**：`Inspection`
* **说明**：自动注入 `layers.geoserver` 的 title 与云图层 features。

```js
const insp = map.pipeInspection((msg) => console.log(msg), {
  cloudLayerCodes: ['hydrant']
});
```

### historyDispatch(options)

* **类型**：`Function`
* **参数**：
  * `{Object} options`
    * `{string[]} options.layerCodes` — 调度点所在云图层
    * 其它 HistoryDispatch 选项
* **返回值**：`HistoryDispatch`

```js
const hd = map.historyDispatch({ layerCodes: ['vehicle'] });
hd.play(0);
```

### pipeProfile(callback, options)

* **类型**：`Function`
* **参数**：
  * `{Function} callback` — 必填
  * `{Object} options`
    * `{string} options.pipeLayerCode` — 管线层
    * `{string} options.flowLayerCode` — 流向/流量相关层
    * `{*} [options.offset]`
* **返回值**：`Profile | undefined`（callback 非法时无返回）

```js
const profile = map.pipeProfile((data) => console.log(data), {
  pipeLayerCode: 'pipe',
  flowLayerCode: 'flow'
});
```

---

## 全局 API · transformCoord

### transformCoord(data, from, to, projectionCode?)

* **类型**：`Function`
* **归属**：自定义
* **参数**：
  * `{number[]} data` — `[x, y]`
  * `{string} from` — `'wgs84'` | `'gcj02'` | `'webmercator'` | `'map'` …
  * `{string} to` — 同上
  * `{string|Object} [projectionCode]` — 自定义投影
* **返回值**：`number[]`
* **说明**：内部 `new Transform(...)`。`from/to` 为 `'map'` 时依赖当前 `context` 中的 Map。
* **用法**：

```js
import { transformCoord } from '@its-cool/simple-map';

const gcj = transformCoord([120.15, 30.28], 'wgs84', 'gcj02');
const merc = transformCoord(gcj, 'gcj02', 'webmercator');
```

示例页：[`/transform`](/transform)

---

## 全局 API · mapTools

### mapTools.pipeInspection(options)

* **类型**：`Function`
* **参数**：
  * `{Object} options`
    * `{number} options.wkid` — `3857` 时会把坐标 `toWgs84`
    * `{Array<{x,y}>} options.list` — 轨迹折线
    * `{string} options.layerIds` — WFS typeName
    * `{Function} options.callback(featuresProps[])` — 结果回调
    * `{Object} [options.cql]` — 额外 CQL 条件键值
* **返回值**：无（异步 `fetch`）
* **用法**：

```js
import { mapTools } from '@its-cool/simple-map';

mapTools.pipeInspection({
  wkid: 3857,
  list: [{ x: 13528400, y: 3676400 }, { x: 13528500, y: 3676500 }],
  layerIds: 'water:pipe',
  callback(rows) {
    console.log(rows);
  }
});
```

---

## Tools · Draw

* **归属**：融合 — `class Draw extends ol/layer/Vector`
* **说明**：构造时 `main.map.addLayer(this)`，并 `Object.assign(this, options)`。

### new Draw(main, options?)

* **参数**：
  * `{Map} main` — 业务地图
  * `{Object} [options]` — 传给 VectorLayer 的 OL 选项 + 自定义字段（如 `style`、`removeFun`）
* **用法**：

```js
import { Draw } from '@its-cool/simple-map';
const draw = new Draw(map, {
  style: [{ 'stroke-color': '#f00', 'stroke-width': 2 }]
});
```

### cancel() / clear() / remove(item) / destroy()

* **类型**：`Function`
* **说明**：取消交互 / 清空图形 / 移除单项 / 销毁图层与交互。

> 内部 `_draw(callback, options)` 不建议业务直接调用；由 Measure、DrawSearch、analysis 使用。`options.type`：`Point` / `Line` / `Polygon` 等。

---

## Tools · Measure

* **归属**：融合 — `extends Draw`

### new Measure(main)

* **参数**：`{Map} main`
* **说明**：`initLayers` 后也可通过 `map.measureTool` 访问。

### measure(type)

* **参数**：
  * `{string} type` — `'area'` → 多边形测面；其它 → 线测距
* **用法**：

```js
map.measureTool.measure('area');
// 等价
map.measure('area');
```

---

## Tools · DrawSearch

* **归属**：融合 — `extends Draw`

### draw(searchCallback, param?)

* **参数**：
  * `{Function} searchCallback`
  * `{Object} [param]`
* **实例属性**：`results`、`resultsNum`

```js
map.drawSearchTool.draw((res, num) => console.log(res, num));
```

### cancel() / clearFun()

取消 / 清理绘制查询。

---

## Tools · Tip

* **归属**：自定义

### new Tip(main, text)

* **参数**：
  * `{Map} main`
  * `{string} text`
* **方法**：
  * `changeText(text)` — 改文案
  * `destroy()` — 移除 DOM

```js
import { Tip } from '@its-cool/simple-map';
const tip = new Tip(map, '请点击地图');
tip.changeText('请双击结束');
tip.destroy();
```

---

## Tools · WriteServer

* **归属**：融合 — `extends ol/layer/Vector`
* **推荐创建**：`map.writeServer(options)`

### 常用方法

#### insertFeature(type, attributes)

* **参数**：
  * `{string} type` — 几何类型（点/线等，内部归一化）
  * `{Object} attributes` — 业务属性
* **用法**：

```js
editor.insertFeature('Point', { objCode: 'N1', name: '新点' });
```

#### editFeature(type)

* **参数**：`{string} type` — 进入对应编辑模式

#### updateFeature(properties, type, editType)

* **参数**：
  * `{Object} properties`
  * `{string} type`
  * `{string} editType`

#### deleteFeature(properties, type) / deleteFeatures(objCodes) / deleteEditFeature()

删除单个 / 批量 / 当前编辑要素。

#### save(properties?)

* **参数**：`{Object} [properties]` — 附加提交属性
* **说明**：提交 WFS 事务。

#### clearFeature() / clear() / deactivate()

清理要素或交互。

#### importData(data) / updateProperties(objCodes, properties)

导入与批量改属性。

#### selectFromLayer(layerCode, objCodes)

从业务层选中要素进入编辑。

#### getEditFeatures() / setEditFeatures(features)

读写当前编辑要素集合。

#### unionFeaturs()

合并要素（方法名保持源码拼写）。

```js
const editor = map.writeServer({ addType: 'geoserver', layerCodes: ['valve'] });
editor.insertFeature('Point', { objCode: 'V9' });
// 用户改完几何后
editor.save();
```

---

## Tools · Track

* **归属**：自定义（内部创建两条 **OL** VectorLayer）

### 实例方法摘要

| 方法 | 参数 | 说明 |
|------|------|------|
| `drawTrackLine(list)` | `Array<{gpsX,gpsY,uploadTime}>` | 绘制轨迹 |
| `drawSegmentedTrackLine(list)` | `Array<Array<point>>` | 分段轨迹 |
| `setMarkers(startCoord, endCoord)` | `number[]`, `number[]` | 起终点标记 |
| `play(index)` | `number` | 播放到进度索引 |
| `setMovePoint(bool)` | `boolean` | 移动点显隐 |
| `getSource()` | — | 线图层 `VectorSource` |
| `destroy()` | — | 移除图层 |

```js
const track = map.addTrack(() => {});
track.drawTrackLine([
  { gpsX: 13528400, gpsY: 3676400, uploadTime: '2024-01-01 10:00:00' },
  { gpsX: 13528600, gpsY: 3676600, uploadTime: '2024-01-01 10:10:00' }
]);
track.setMarkers([13528400, 3676400], [13528600, 3676600]);
track.play(0);
```

---

## Tools · Inspection

* **归属**：融合 — `extends VectorLayer`
* **创建**：`map.pipeInspection(callback, options)`

| 方法 | 说明 |
|------|------|
| `play(index)` | 巡检播放 |
| `addTrack(list)` / `addTrackLine(list)` | 添加轨迹 |
| `trackSearch(list, data, noLine?)` | 轨迹缓冲查管网；`data`：1 管网巡检点 / 2 关键巡检点 |
| `circleSearch(coord)` | 圆形搜索 |
| `moveCenter(coord)` | 移动中心 |
| `addScope(options)` | 添加范围 |
| `updatePipeDate(list)` | 更新管线数据 |
| `destroy()` | 销毁 |

```js
const insp = map.pipeInspection(console.log, { cloudLayerCodes: ['hydrant'] });
insp.addTrackLine([{ x: 13528400, y: 3676400 }, { x: 13528500, y: 3676500 }]);
```

---

## Tools · Profile

* **归属**：融合 — `extends VectorLayer`

| 方法 | 说明 |
|------|------|
| `addStartPoint()` | 起点 |
| `addMidPoints(data)` | 中间点 |
| `addEndPoint()` | 终点 |
| `addLines(data)` | 剖面线 |

```js
const profile = map.pipeProfile(console.log, {
  pipeLayerCode: 'pipe',
  flowLayerCode: 'flow'
});
profile.addStartPoint();
```

---

## Layers（内部模块）

路径 `src/layers/`。由 `_getLayer` 按 `type` 创建。下列为高频 API。

### CloudLayer

* **归属**：融合 — `extends ol/layer/Vector` + `Object.assign(this, options)`

#### 构造 options 常用字段

| 字段 | 类型 | 说明 |
|------|------|------|
| `code` | `string` | 图层编码 |
| `minZoom` | `number` | 点可见最小级别 |
| `label` | `Object` | `{ minZoom, field, hidden… }` |
| `cloudMinZoom` | `number` | 飘窗最小级别 |
| `cloudDirection` | `string` | 如 `'bottom-center'` |
| `cloudOffset` | `number[]` | 像素偏移 |
| `cloudHover` | `boolean` | 悬停显示（会注册 pointermove） |
| `alarmColor` / `alarmColors` | `string` / `Object` | 告警色 |
| `cloudClass` | `string` | 飘窗 CSS 类 |

#### 方法

| 方法 | 参数 | 说明 |
|------|------|------|
| `addGraphics(data)` | `Array<Object>` | 加点 |
| `removeGraphics(data)` | `Array` | 删点 |
| `refreshData(data)` | `*` | 刷新 |
| `refreshAlarm(objCodes)` | `Array` | 告警 |
| `showGraphics(codes)` | `Array` | 仅显示指定 code |
| `displayPart(data)` | `Array\|Object` | 条件显示 |
| `addCloud(cloudData)` | `Object` | 飘窗 |
| `hideCloud` / `showCloud` | `objCode` | 单个飘窗 |
| `hideClouds` / `showClouds` | — / `objCodes` | 批量 |
| `removeCloud` / `removeAllClouds` | `objCode?` | 移除飘窗 |
| `changeStatus(status)` | `*` | 状态样式 |
| `clear` / `clearGraphics` | — | 清空 |
| `setVisible(bool)` | `boolean` | 显隐（扩展 OL） |

```js
const layer = map.layers.hydrant;
layer.addGraphics([{ objCode: 'H1', gpsX: 13528430, gpsY: 3676466 }]);
layer.setVisible(true);
```

### ClusterLayer / HistoryDispatch / GLayer / ContourLayer / HeatmapLayer / VectorTileLayer / EchartsLayer

| 类 | 基类 | 要点方法 |
|----|------|----------|
| ClusterLayer | CloudLayer | `addGraphics`、`setVisible`、`displayPart`、`changeStatus` |
| HistoryDispatch | CloudLayer | `play(index)`、`setData(data)`、`destroy()` |
| GLayer | Vector | `addPoint` / `addPoints` / `addPolyline(s)` / `addPolygon` / `setData` / `clear` |
| ContourLayer | Vector | `update`、`setData`、`setGridData` |
| HeatmapLayer | ol/layer/Heatmap | `setData`、`refreshData` |
| VectorTileLayer | ol/layer/VectorTile | `addFilters`、`changeStyle`、`resume`、`refreshData`、`changeScope` |
| EchartsLayer | ol-echarts | `setData`、`appendTo(olMap)` |

#### GLayer 加点示例

```js
map.layers.sketch.addPoints(
  [
    { x: 13528430, y: 3676466, text: 'A' },
    { x: 13528500, y: 3676500, text: 'B' }
  ],
  { fill: '#2563eb', radius: 6 }
);
```

---

## Sources（内部模块）

路径 `src/sources/`。均 **extends** `ol/source/XYZ`（或本库 `XYZSource`）。

| 类 | 用途 | 典型配合 type |
|----|------|----------------|
| `XYZSource` | 通用 XYZ | 自定义瓦片 |
| `cacheSource` / `agscacheSource` | 缓存瓦片 | `cacheLayer` / `agscacheLayer` |
| `BaiduSource` | 百度 | `BaiduLayer` |
| `GaodeSource` | 高德 | `GaodeLayer` |
| `TengxunSource` | 腾讯 | `TengxunLayer` |
| `TDTSource` | 天地图 | `TDTLayer` |
| `TSZSource` | 定制 XYZ | `TSZLayer` |
| `OSMSource` | OSM | `OSMLayer` |
| `ArcGISTiledMapServiceSource` | ArcGIS 切片 | `ArcGISTiledMapServiceLayer` |

业务侧一般不直接 `new`，而是在 `baseLayers` / `initLayers` 里写 `type`。

```js
baseLayers: {
  gaode: [{ type: 'GaodeLayer', layerType: 'raster' }],
  tdt: [{ type: 'TDTLayer', layerType: 'vec' }]
}
```

---

## 可直接使用的 OL API

通过 `map.map` 使用 OpenLayers，文档见 [OL API](https://openlayers.org/en/latest/apidoc/)。

### 常用

```js
const olMap = map.map;
const view = olMap.getView();

view.animate({ zoom: 14, duration: 300 });
olMap.once('rendercomplete', () => {});
olMap.getCoordinateFromPixel([100, 200]);
olMap.updateSize(); // 容器从 hidden→显示后调用
```

| API | 说明 |
|-----|------|
| `getView()` | 视图 |
| `on` / `un` / `once` | 事件 |
| `addLayer` / `removeLayer` / `getLayers` | 图层集合 |
| `getSize` / `getCoordinateFromPixel` / `getPixelFromCoordinate` | 坐标换算 |
| `dispose` | 销毁（业务请优先 `map.destroy()`） |

图层上：`setVisible`、`getSource`、`setOpacity`、`set` / `get`。  
Source 上：`updateParams`、`clear`、`addFeature`、`getFeatureById`。

### 融合注意

1. 不要覆盖 `map.map.business`。
2. 业务显隐优先 `displayLayer` / `showLayers`，避免 WMS `LAYERS` 与字典不同步。
3. `Overlay.setVisible` 已被扩展。
4. Draw / WriteServer 等已是 Layer，请用其自定义方法管理 interaction。

---

## 附录 · 内部方法（不推荐业务调用）

来源：`internalMethods.js`。以下划线开头。

| 方法 | 作用 |
|------|------|
| `_clickFun` / `_extentChangeFun` / `_pointerMoveFun` | 事件 |
| `_locateTo` | 定位动画 |
| `_addBaseLayer` / `_addLayer` / `_getLayer` | 建层 |
| `_setCustomParametersToGeoserverLayer` | 更新 WMS LAYERS/STYLES |
| `_searchByGeometry` | 几何查询入口 |
| `_identifyArcgisServer` / `_queryArcgisServer` | ArcGIS |
| `_requestGeoserver` / `_requestGeoserverOws` | GeoServer |
| `_statistics` | 字段统计请求 |
| `_getFields` / `_createTip` / `_destroyTip` | 辅助 |

`_getLayer` 是 type → OL Layer/Source 的映射中枢。

---

## Playground 示例对照

| 主题 | 路由 |
|------|------|
| 基础地图 | [`/basic`](/basic) |
| 底图切换 | [`/baselayer`](/baselayer) |
| 视图控制 | [`/controls`](/controls) |
| 测量 | [`/measure`](/measure) |
| 绘制 | [`/draw`](/draw) |
| 坐标转换 | [`/transform`](/transform) |
| 管线压力测试 | [`/pipe`](/pipe) |
| Pinia 点击 | [`/pinia`](/pinia) |
| 高级工具 | [`/advanced`](/advanced) |
| 本文档 | [`/docs`](/docs) |

---

## 版本与许可

* 包名：`@its-cool/simple-map`
* OpenLayers：`^10`（构建打入产物）
* 许可：MIT
