> **本文回答**：vjmap 各图层类型（fill / line / circle / symbol / raster / fill-extrusion / heatmap / hillshade / background）常用属性。

## 一、background

```js
{
  id: "bg", type: "background",
  paint: {
    "background-color": "#fff",
    "background-opacity": 1.0,
    "background-pattern": "sprite-name"    // 可选：平铺（不是拉伸）图片，图宽高须为 2 的幂
  }
}
```

## 二、fill

```js
{
  id: "bldg", type: "fill", source: "src", "source-layer": "buildings",
  paint: {
    "fill-color": "#abc",
    "fill-opacity": 0.8,
    "fill-outline-color": "#333",
    "fill-pattern": "sprite-name",
    "fill-translate": [0, 0],
    "fill-antialias": true
  }
}
```

## 三、line

```js
{
  id: "roads", type: "line", source: "src", "source-layer": "roads",
  layout: {
    "line-cap": "round",      // butt / round / square
    "line-join": "round",     // miter / bevel / round
    "line-miter-limit": 2
  },
  paint: {
    "line-width": 2,
    "line-color": "#0af",
    "line-opacity": 0.9,
    "line-gap-width": 0,       // 双线中间沟宽
    "line-offset": 0,
    "line-dasharray": [2, 2],
    "line-blur": 0,
    "line-pattern": "sprite-name"
  }
}
```

## 四、circle

```js
{
  id: "pts", type: "circle", source: "markers",
  paint: {
    "circle-radius": 6,
    "circle-color": "#f00",
    "circle-opacity": 0.8,
    "circle-stroke-width": 2,
    "circle-stroke-color": "#fff",
    "circle-blur": 0,
    "circle-pitch-alignment": "map"  // "viewport"
  }
}
```

## 五、symbol（图标 + 文字）

```js
{
  id: "poi", type: "symbol", source: "markers",
  layout: {
    "icon-image": "marker-15",
    "icon-size": 1,
    "icon-rotate": 0,
    "icon-anchor": "center",
    "icon-allow-overlap": false,
    "text-field": ["get", "name"],
    "text-font": ["Arial Unicode MS Regular"],   // 官方示例用的 fontstack；中文默认由浏览器本地字体绘制，与此无关
    "text-size": 12,
    "text-offset": [0, 1],
    "text-anchor": "top",
    "text-allow-overlap": false,
    "text-max-width": 8
  },
  paint: {
    "icon-opacity": 1,
    "icon-color": "#000",          // 只对 SDF 图标有效
    "icon-halo-color": "#fff",
    "icon-halo-width": 2,
    "text-color": "#000",
    "text-halo-color": "#fff",
    "text-halo-width": 1,
    "text-opacity": 1
  }
}
```

## 六、raster

```js
{
  id: "tile", type: "raster", source: "raster-src",
  paint: {
    "raster-opacity": 1,
    "raster-hue-rotate": 0,
    "raster-brightness-min": 0,
    "raster-brightness-max": 1,
    "raster-saturation": 0,
    "raster-contrast": 0,
    "raster-fade-duration": 300
  }
}
```

## 七、fill-extrusion（3D 拉伸）

见 [extrusion-3d](extrusion-3d.md)。

```js
{
  id: "bldg-3d", type: "fill-extrusion", source: "buildings",
  paint: {
    "fill-extrusion-color": ["get", "color"],
    "fill-extrusion-height": ["get", "h"],
    "fill-extrusion-base": ["get", "h0"],
    "fill-extrusion-opacity": 0.9,
    "fill-extrusion-translate": [0, 0],
    "fill-extrusion-pattern": "sprite-name"
  }
}
```

## 八、heatmap

```js
{
  id: "heat", type: "heatmap", source: "pts",
  paint: {
    "heatmap-weight": ["get", "weight"],
    "heatmap-intensity": 1,
    "heatmap-radius": 30,
    "heatmap-color": [
      "interpolate", ["linear"], ["heatmap-density"],
      0,   "rgba(0, 0, 255, 0)",
      0.5, "rgba(0, 255, 0, 0.5)",
      1,   "rgba(255, 0, 0, 1)"
    ],
    "heatmap-opacity": 1
  }
}
```

## 九、hillshade（地形阴影）

```js
{
  id: "hs", type: "hillshade", source: "dem",
  paint: {
    "hillshade-exaggeration": 0.5,
    "hillshade-illumination-anchor": "viewport",
    "hillshade-illumination-direction": 335,
    "hillshade-shadow-color": "#000",
    "hillshade-highlight-color": "#fff",
    "hillshade-accent-color": "#000"
  }
}
```

需要 `type: raster-dem` 的 source。

## 十、vjmap 封装类（替代 addLayer）

vjmap 提供了以下高级类，内部都是 addLayer/addSource 的简便包装：

| 类 | 类型 |
|---|---|
| `Marker` | DOM marker（不属于 Layer 体系） |
| `Popup` | DOM popup |
| `Polyline` | type: line |
| `Polygon` | type: fill |
| `CircleFill` | type: fill（几何成圆） |
| `EllipseFill` | 椭圆 fill |
| `Text` | DOM text marker |
| `Heatmap` | type: heatmap |
| `FillExtrusion` | type: fill-extrusion |
| `DeckLayer` | Deck.GL |
| `PolylineArrow` | 带箭头折线 |
| `DivOverlay` | 跟随缩放的 div/svg |
| `BackgroundLayer` | type: background |

## 十一、常见坑

1. **line-offset 太大导致拐角变形**：尽量别用大于线宽的 offset。
2. **symbol 文字叠压**：默认 `text-allow-overlap: false`，挤不下会消失；打开 allow-overlap 可硬显示。
3. **circle 在高 pitch 下椭圆化**：`circle-pitch-alignment: "map"` 会贴地，"viewport" 始终正圆。
4. **icon-color 没效果**：必须是 SDF 格式（单色模板图标）。
5. **`map.toggle(layer)` 不是真翻转**：MapGlUtils 的 `toggle(layer, state)` 实现为 `state ? "visible" : "none"`，**不读当前可见性**——`toggle(layer)` 无参恒隐藏。要翻转需自读 `getLayoutProperty(layer,"visibility")` 再取反。
6. **常用图层/源工具面（MapGlUtils mixin，均挂在 `map` 上）**：`hide/show/setVisibility`、`hideSource/showSource/toggleSource`、`layersBySource(sourceId)`、`removeSourceEx(sourceId)`（先删依赖层再删源，规避 "source cannot be removed while layer is in use"）、`setFilterEx`、`setLayerSource(layerId, sourceId)`（换源且保层序）、`setData(sourceId, data?)`（无 data 参默认空 FeatureCollection）。

7. **Map 级类型化存取器的 getter 返数组包装值**：`map.setFillColor(id,"#f00")`/`setLineWidth(id,4)`/`setCircleRadius(id,9)` 等 setter 收裸值，但对应 `getFillColor(id)`→`["#ff0000"]`、`getLineWidth(id)`→`[4]`、`getLineDasharray(id)`→`[[2,2]]`、`getFillOpacity(id)`→`[0.5]`——**全部 paint getter 返回数组包装形态**（与 r33 BackgroundLayer 结论同型，是系统性行为不是个别实现）。比较时先 `v?.[0]` 或 `Number(v)` 归一；`getFillColor` 对不存在图层抛 `Cannot read properties of undefined`。**`map.repaint` 是 boolean 旗标不是方法**（d.ts `repaint: boolean`），`map.repaint()` 抛 `TypeError`——要强制重绘用 `map.triggerRepaint()`。`queryTerrainElevation` 无地形源时返 `null` 不抛。
