---
title: 瓦片 / 样式
source: https://vjmap.com/guide/service/api/02-tiles-styles.html
---

# 瓦片 / 样式

> 分类代号：C.2  本章共 **10 个接口**（3 个纯 URL 拼装 + 7 个 REST）

vjmap 的瓦片出图有两套机制：

1. **按地图内置默认 layer 出图**  
   `open_map` 之后，可直接用 `raster_tile_url()` / `vector_tile_url()` 拿到 `{z}/{x}/{y}` 占位符 URL，喂给 vjmap。
2. **按自定义 style 出图**  
   先 `create_map_style()` 拿到 `stylename`，把它作为 `layer` 段传给 tile URL，即可得到"按该 style 渲染"的瓦片。  
   后续可用 `cmd_update_style()` 原地修改；用 `cmd_switch_layers()` 临时切换可见图层；用 `slice_layer()` 触发预切片缓存；用 `get_slice_cache_zoom()` 查询当前已缓存到几级；用 `delete_style()` 清理。

WMS 出图走的是独立管线，用 `wms_tile_url()` 构造即可，单图走 `cmd/wms/{mapid}/{version}`，多图叠加走 `/service/wms`。

---

## 快速索引

| 序号 | SDK 方法 | HTTP | URL |
|----:|---------|------|-----|
| 16 | `raster_tile_url` / `rasterTileUrl` | GET | `/api/v1/map/tile/{mapid}/{version}/{layer}/{z}/{x}/{y}` |
| 17 | `vector_tile_url` / `vectorTileUrl` | GET | `/api/v1/map/tile/{mapid}/{version}/{layer}/{z}/{x}/{y}.mvt` |
| 18 | `wms_tile_url` / `wmsTileUrl`（单图） | GET | `/api/v1/map/cmd/wms/{mapid}/{version}` |
| 19 | `wms_tile_url` / `wmsTileUrl`（多图） | GET | `/api/v1/service/wms` |
| 20 | `create_map_style` / `createMapStyle` | POST | `/api/v1/map/cmd/createMapStyle/{mapid}/{version}` |
| 21 | `cmd_switch_layers` / `cmdSwitchLayers` | POST | `/api/v1/map/cmd/switchlayer/{mapid}/{version}` |
| 22 | `cmd_update_style` / `cmdUpdateStyle` | POST | `/api/v1/map/cmd/updateStyle/{mapid}/{version}` |
| 23 | `slice_layer` / `sliceLayer` | POST | `/api/v1/map/cmd/slicelayer/{mapid}/{version}` |
| 24 | `get_slice_cache_zoom` / `getSliceCacheZoom` | POST | `/api/v1/map/cmd/getSliceCacheZoom/{mapid}/{version}` |
| 25 | `delete_style` / `deleteStyle` | POST | `/api/v1/map/cmd/deletestyle/{mapid}/{version}` |

> **注意**：10/21/22/23/24/25 这 6 个是  `cmd` 路由，**POST 必须带非空 JSON body**（即使是 `{"noop":true}`），否则会返回 `500 param error`。SDK 已经替你处理好这点，直接调方法即可。

---

## 16 · 栅格瓦片 URL

**SDK**：`svc.raster_tile_url(mapid?, version?, layer?, fileid?)`

### 请求参数

| 字段 | 类型 | 说明 |
|------|------|------|
| `mapid` | string | 可省，默认为当前 `_cur_map.mapid` |
| `version` | string | 可省，默认 `v1` |
| `layer` | string | 可省，默认 `_`（即图档内置默认 style）。若先调用 `create_map_style`，把返回的 `stylename` 传进来即可 |
| `fileid` | string | 可省。主要用于 tile 缓存破坏。后端不校验，只要 `{mapid,version,layer}` 对，tile 就出得来 |

### 实采示例

```json
"http://127.0.0.1:27660/api/v1/map/tile/sys_zp/v1/_/{z}/{x}/{y}?tag=c47be46a2ad2&token=<jwt>"
```

### Python

```python
from vjmap import Vjmap, MapOpenWay

svc = Vjmap("http://127.0.0.1:27660/api/v1", TOKEN)
svc.open_map(mapid="sys_zp", version="v1", mapopenway=MapOpenWay.GeomRender)
print(svc.raster_tile_url())
```

### Node.js

```javascript
import { Vjmap, MapOpenWay } from './sdk/nodejs/vjmap.js';

const svc = new Vjmap('http://127.0.0.1:27660/api/v1', TOKEN);
await svc.openMap({ mapid: 'sys_zp', version: 'v1', mapopenway: MapOpenWay.GeomRender });
console.log(svc.rasterTileUrl());
```

---

## 17 · 矢量瓦片 URL（MVT）

**SDK**：`svc.vector_tile_url(...)`，参数与 `raster_tile_url` 完全一致，区别是 URL 末尾多了 `.mvt` 后缀。

### 实采示例

```json
"http://127.0.0.1:27660/api/v1/map/tile/sys_zp/v1/main/{z}/{x}/{y}.mvt?tag=c47be46a2ad2&token=<jwt>"
```

`{layer}` 默认是 `main`（内置 MVT 默认名），不是 `_`。

### 用法

MVT 非常适合作为 vjmap `vector` source：

```javascript
map.addSource('vj', {
  type: 'vector',
  tiles: [svc.vectorTileUrl()],
  minzoom: 0,
  maxzoom: 22,
});
map.addLayer({ id: 'vj-line', source: 'vj', 'source-layer': 'default', type: 'line' });
```

---

## 18 / 19 · WMS 瓦片 URL

**SDK**：`svc.wms_tile_url(mapid, version?, *, layer?, width?, height?, bbox?, srs?, backcolor?, mvt?)`

### 参数规则

- `mapid`: 可以是字符串，也可以是 `list[str]`
  - **单图** → 走 `/api/v1/map/cmd/wms/{mapid}/{version}`
  - **多图** → 走 `/api/v1/service/wms?mapid=a;b;c&version=v1;v1;v1`
- `bbox`: 默认 `{bbox-epsg-3857}` 占位符。如果你直接用 如Leaflet，就保留占位符交给前端去替换。SDK 刻意**不对 `bbox` 做 percent-encode**。
- `srs`: 坐标系，默认 `EPSG:3857`。
- `mvt=True`: URL 末尾加 `.mvt`，输出矢量。
- `backcolor`: 背景色，十进制 RGB（0 = 黑/透明）。
- `layer`: 可选，指定某个 stylename 渲染。

### 实采示例

单图：

```json
"http://127.0.0.1:27660/api/v1/map/cmd/wms/sys_zp/v1?bbox={bbox-epsg-3857}&srs=EPSG%3A3857&width=512&height=512&token=<jwt>"
```

多图：

```json
"http://127.0.0.1:27660/api/v1/service/wms?bbox={bbox-epsg-3857}&mapid=sys_zp&version=v1&srs=EPSG%3A3857&width=256&height=256&token=<jwt>"
```

### Python

```python
url = svc.wms_tile_url("sys_zp", "v1", width=512, height=512)
url_multi = svc.wms_tile_url(["sys_zp", "other"], ["v1", "v1"])
```

### Node.js

```javascript
const url = svc.wmsTileUrl({ mapid: 'sys_zp', version: 'v1', width: 512, height: 512 });
const urlMulti = svc.wmsTileUrl({ mapid: ['sys_zp', 'other'], version: ['v1', 'v1'] });
```

---

## 20 · 创建地图样式 `createMapStyle`

**URL**：`POST /api/v1/map/cmd/createMapStyle/{mapid}/{version}`  
**SDK**：`svc.create_map_style(mapid, version, *, layeron, layeroff, backcolor, clipbounds, expression, lineweight, is_geom_layer=True, name)`  

### 请求参数

| 字段 | 类型 | 说明 |
|------|------|------|
| `geom` | bool | `true` 几何渲染（默认）；`false` 栅格渲染 |
| `name` | string | style 名字，可自动生成 |
| `layeron` | string / 数组 | 可见图层；数组传入时 SDK 会自动转成 `(0,1,2)` 格式 |
| `layeroff` | string / 数组 | 隐藏图层 |
| `backcolor` | int | 背景色（0=黑色，常用于暗色底图） |
| `clipbounds` | string | 裁剪范围 JSON 字符串 |
| `expression` | string | Cesium 风格的颜色表达式 |
| `lineweight` | int[] | 线宽缩放 `[默认,最小,最大]` |

### 响应（实采）

```json
{
  "stylename": "sfbd35705c"
}
```

返回的 `stylename` 就是后续作为瓦片 URL 中 `{layer}` 段的值。

### Python

```python
style = svc.create_map_style("sys_zp", "v1", layeron="*", backcolor=0)
tile_url = svc.raster_tile_url(layer=style["stylename"])
```

### Node.js

```javascript
const style = await svc.createMapStyle({ mapid: 'sys_zp', version: 'v1', layeron: '*', backcolor: 0 });
const tileUrl = svc.rasterTileUrl({ layer: style.stylename });
```

### curl

```bash
curl -X POST "http://127.0.0.1:27660/api/v1/map/cmd/createMapStyle/sys_zp/v1?token=$TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"geom":true,"layeron":"*","backcolor":0}'
```

---

## 21 · 切换可见图层 `switchlayer`

**URL**：`POST /api/v1/map/cmd/switchlayer/{mapid}/{version}`  
**SDK**：`svc.cmd_switch_layers(visible_layers, *, expression?, dark_mode?, mapid?, version?)`

### 请求参数

| 字段 | 类型 | 说明 |
|------|------|------|
| `visibleLayer` | string[] | 要可见的图层 id 列表 |
| `expression` | string | 颜色表达式（与 createMapStyle 同） |
| `darkMode` | bool | 是否暗色（可在 openMap 时也指定） |

### 响应（实采）

```json
{
  "layerid": "s24d720029"
}
```

与 `createMapStyle` 的 `stylename` 相似，`layerid` 指向新的内部 style（后端按参数 hash 复用，不会无限增长）。

### Python

```python
res = svc.cmd_switch_layers(["0"])
print(res["layerid"])
```

### Node.js

```javascript
const res = await svc.cmdSwitchLayers(["0"]);
console.log(res.layerid);
```

---

## 22 · 原地修改样式 `updateStyle`

**URL**：`POST /api/v1/map/cmd/updateStyle/{mapid}/{version}`  
**SDK**：`svc.cmd_update_style(*, name, layeron, layeroff, backcolor, clipbounds, expression, lineweight, mapid?, version?)`

与 `createMapStyle` 最大的区别：**它可以修改已有 style（传同名 name）**，而不是每次新建。

### 响应（实采）

```json
{
  "bounds": "[587227463.27, 3103509765.63, 588006538.39, 3104288840.75]",
  "boundsChange": false,
  "layerid": "m765111cb4"
}
```

`boundsChange` = false 表示裁剪范围没变；若 `clipbounds` 修改了，`bounds` 与 `boundsChange` 会反映出来。

### Python

```python
svc.cmd_update_style(
    mapid="sys_zp", version="v1",
    name="nb_style_1",
    layeron="*",
    backcolor=0,
)
```

### Node.js

```javascript
await svc.cmdUpdateStyle({
  mapid: 'sys_zp', version: 'v1',
  name: 'nb_style_1',
  layeron: '*',
  backcolor: 0,
});
```

---

## 23 · 触发预切片缓存 `slicelayer`

**URL**：`POST /api/v1/map/cmd/slicelayer/{mapid}/{version}`  
**SDK**：`svc.slice_layer(*, layer, zoom, ismvt, iscancel, is_all_cancel, batch_num?, idle_batch_sleep_ms?, busy_batch_sleep_ms?, mapid?, version?)`

### 请求参数

| 字段 | 类型 | 说明 |
|------|------|------|
| `layer` | string | 要预切的 layer id（即 stylename） |
| `zoom` | int / int[] / string | 要切的 zoom 层级。单个或数组 |
| `ismvt` | bool | true 切 MVT，false 切栅格 |
| `iscancel` | bool | 取消本次任务 |
| `isAllCancel` | bool | 取消该地图所有正在进行的切片任务 |
| `batchnum` | int | 批处理大小 |
| `idle_batch_sleepms` | int | 空闲批间隔毫秒 |
| `busy_batch_sleepms` | int | 忙时批间隔毫秒 |

### 响应（实采）

取消切片：

```json
{}
```

即空对象。真实触发切片时后端会流式推进度（`{progress:0.5,total:...}`），这里我们的 SDK 只取第一响应。

### Python

```python
svc.slice_layer(layer="s24d720029", zoom=[0, 1, 2, 3], ismvt=False)
```

### Node.js

```javascript
await svc.sliceLayer({ layer: 's24d720029', zoom: [0,1,2,3], ismvt: false });
```

---

## 24 · 查询已缓存的切片级别 `getSliceCacheZoom`

**URL**：`POST /api/v1/map/cmd/getSliceCacheZoom/{mapid}/{version}`  
**SDK**：`svc.get_slice_cache_zoom(*, layer, ismvt, mapid?, version?)`

### 响应（实采）

```json
{
  "sliceCacheZoom": 0
}
```

`sliceCacheZoom` = 当前已稳定缓存到的最大 zoom。若 = 0 通常表示还没跑过预切片。

### Python / Node

```python
print(svc.get_slice_cache_zoom(layer="s24d720029", ismvt=False))
```

```javascript
console.log(await svc.getSliceCacheZoom({ layer: 's24d720029', ismvt: false }));
```

---

## 25 · 删除自定义样式 `deletestyle`

**URL**：`POST /api/v1/map/cmd/deletestyle/{mapid}/{version}`  
**SDK**：`svc.delete_style(stylename, *, mapid?, version?)`

### 请求参数

| 字段 | 类型 | 说明 |
|------|------|------|
| `stylename` | string | 要删除的 style 名（即 `create_map_style` 返回的 `stylename`） |

### 响应（实采）

即便 stylename 不存在也返回空对象（幂等）：

```json
{}
```

### Python / Node

```python
svc.delete_style("sfbd35705c", mapid="sys_zp", version="v1")
```

```javascript
await svc.deleteStyle('sfbd35705c', { mapid: 'sys_zp', version: 'v1' });
```

---

## 组合示例：从开图到看地图

```python
from vjmap import Vjmap, MapOpenWay

svc = Vjmap("http://127.0.0.1:27660/api/v1", TOKEN)
svc.open_map(mapid="sys_zp", version="v1", mapopenway=MapOpenWay.GeomRender)

# 1. 自定义一个黑底白线风格
style = svc.create_map_style(
    "sys_zp", "v1",
    layeron="*",
    backcolor=0,
    expression="gOutColorRed:=255;gOutColorGreen:=255;gOutColorBlue:=255;gOutColorAlpha:=255;",
)

# 2. 拿 tile URL 给 vjmap
raster = svc.raster_tile_url(layer=style["stylename"])

# 3. 预切前 4 级，加快首屏
svc.slice_layer(layer=style["stylename"], zoom=[0,1,2,3], ismvt=False)

# 4. 不用了，清掉
svc.delete_style(style["stylename"], mapid="sys_zp", version="v1")
```

