> **本文回答**：Symbol 主题总览 —— 点/图标/文字 WebGL 图层的封装类与原生用法；大数据量下取代 Marker。

# Symbol 主题

Symbol 图层基于 vjmap 的 `symbol` / `circle` 图层类型，完全在 WebGL 上渲染，**远比 DOM Marker 快**。几万点依然流畅。

## 子项索引

| 文件 | 主题 |
|---|---|
| [layer-types](layer-types.md) | circle / symbol / heatmap 图层对比 |
| [circle-symbol](circle-symbol.md) | `vjmap.Circle` 圆点 |
| [icon-symbol](icon-symbol.md) | `vjmap.Symbol` 图标 |
| [text-symbol](text-symbol.md) | 文字 halo / font / 排布 |
| [expression](expression.md) | 样式表达式驱动 symbol |
| [marker-vs-symbol](marker-vs-symbol.md) | DOM vs WebGL 选型，阈值 |

## 最小示例

```js
await map.loadImageEx("pin", "/icons/pin.png");

const symbol = new vjmap.Symbol({
  data: map.toLngLat(featureCollection),   // CAD → LngLat
  iconImage: ["get", "icon"],              // 数据驱动
  iconOffset: [0, -12],
  iconOpacity: ["case", ["to-boolean", ["feature-state", "hover"]], 0.8, 1.0],
  textField: ["get", "name"],
  textFont: ["Arial Unicode MS Regular"],
  textSize: 14,
  textColor: "#FFA0FD",
  textOffset: [0, 0.5],
  textAnchor: "top",
  iconAllowOverlap: false,
  textAllowOverlap: false,
  isHoverPointer: true,        // vjmap 扩展：自动改 cursor
  isHoverFeatureState: true    // vjmap 扩展：自动维护 hover feature-state
});
symbol.addTo(map);

symbol.clickLayer(e => console.log("点了", e.features[0].properties.name));
symbol.hoverPopup(f => `<b>${f.properties.name}</b>`, { anchor: "bottom" });
```

## 主题级 Top 3 陷阱

1. **`data` 必须是 LngLat**：CAD feature 须 `map.toLngLat(featureCollection)`。
2. **图标名必须先 loadImage**：sprite 里没有该图标名，`iconImage` 不显示。
3. **hoverFeatureState 要求 feature 有非 0 id**：封装类不透传 `generateId`（且 generateId 从 0 编号，而 `hoverFeatureState` 忽略 id 0）：FeatureCollection 须自带非 0 `id`；或传 `[{points, properties}]` 形式（自动 `id = 序号 + 1`）；或先自建源（`promoteId`）再传 `sourceId`。
