---
title: 样式规范
source: https://vjmap.com/guide/styleSpec.html
---

# 样式规范

样式规范是定义地图视觉外观的文档：绘制哪些数据，绘制顺序以及绘制数据时如何设置数据样式。

一个样式有以下根属性： 
- 描述信息：`version`, `metadata`
- 地图状态：`center`, `bearing`, `pitch`
- 地图要素：`sources`, `layers`
- 其他：`sprite`, `glyphs`, `light`, `transition`

``` js
{
  'version': number, // 版本号
  'name': 'string', // 样式名称
  'sprite': 'string', // 雪碧图
  'glyphs': '***/{fontstack}/{range}.pbf', // 字体
  'sources': {}, // 数据源
  'layers': [] // 图层
}
```

## 数据源
> `sources`
> 
数据源类型由 `type` 指定，并且必须是 `vector`, `raster`, `raster-dem`, `geojson`, `image`, `video` 之一。
::: tip 提示
另外，还有一个 `canvas` 类型，是 `image` 的扩展：[CanvasSource](/doc/#canvassource)
:::

### vector
使用 `vector` 数据源的图层必须指定 `source-layer` 。
``` js
'sources': {
  '{source-id}': {
    'type': 'vector',
    'tiles': [
      'http://a.example.com/tiles/{z}/{x}/{y}.pbf'
    ],
    'bounds': [-180, -85.051129, 180, 85.051129]
  },
  '{source-id}': {
    'type': 'vector',
    'url': 'http://api.example.com/tilejson.json'
  },
  '{source-id}', {
    'type': 'vector',
    'url': 'xxx'
  },
}
```
### raster
``` js
'sources': {
  '{source-id}': {
    'type': 'raster',
    'tiles': [
      'http://xxx&x={x}&y={y}&l={z}&tk={key}',
      'http://xxx&x={x}&y={y}&l={z}&tk={key}'
    ],
    'tileSize': 256
  },
}
```
### raster-dem
栅格 DEM 数据源，可使用 [rio-rgbify](https://github.com/mapbox/rio-rgbify) 生成。

``` sh
# fill no data
gdalwarp -t_srs EPSG:3857 -dstnodata None -co TILED=YES -co COMPRESS=DEFLATE -co BIGTIFF=IF_NEEDED E:\xxx.tif  E:\xxxx.tif

# conver to rgb
rio rgbify -b -10000 -i 0.1 E:\xxxx.tif E:\test\xxx.tif
```

### geojson
GeoJSON 数据源，必须提供 `data` 属性。可设置 `cluster`， `filter` 等。
``` js
'sources': {
  // inline GeoJSON
  'geojson-marker': {
    'type': 'geojson',
    'data': {
      'type': 'Feature',
      'geometry': {
        'type': 'Point',
        'coordinates': [-77.0323, 38.9131]
      },
      'properties': {
        'title': 'xxx',
        'marker-symbol': 'monument'
      }
    }
  },
  // url
  'geojson-lines': {
    'type': 'geojson',
    'data': './lines.geojson'
  }
}
```
### image & video
见[数据/栅格](/guide/data.html#raster)。

### GeoServer



#### TMS
> 标准：[Tile Map Service](https://wiki.osgeo.org/wiki/Tile_Map_Service_Specification)

Tile Map Service（瓦片地图服务），简称 `TMS`。TMS 的切片坐标系统和组织方式可参考下图：
<div align="center">
  <img :src="$withBase('/assets/images/TMS切片坐标系统和组织方式.png')" width="400" />
</div>

在加载 TMS 服务时，需要设置 `scheme` 属性为 `tms`。`scheme` 属性影响瓦片坐标 `y` 轴的方向。`scheme` 有两个值可选：`xyz`（默认）和 `tms`。其中 `xyz` 代表常用的切片规则，即 `OGC` 标准，切片源点在左上角。`tms` 是 `OSGeo` 标准，切片源点是左下角。

加载示例：
``` js
// 矢量
'source-id': {
  'type': 'vector',
  'tiles': [
    'https://xxx@pbf/{z}/{x}/{y}.pbf'
  ],
  'scheme': 'tms'
}
// 栅格
'source-id': {
  'type': 'raster',
  'tiles': [
    'https://xxx@png/{z}/{x}/{y}.png'
  ],
  'tileSize': 256,
  'scheme': 'tms'
}
```

<!-- <ClientOnly>
  <common-code-view name="service-tms"/>
</ClientOnly> -->

#### WMS
> 标准：[Web Map Service](http://www.opengeospatial.org/standards/wms)

Web Map Service（Web 地图服务），简称 `WMS`。WMS 标准定义了允许用户通过 HTTP 对空间数据进行渲染出图等操作。WMS 服务中包括以下3个操作：
1. GetCapabilities（获取服务中的要素类及支持的操作）
2. GetMap（获取地图）
3. GetFeatureInfo（根据地图上的像素点获取更详细的要素信息，类似Identify功能）

利用 `GetMap` 操作和指定地图边框范围（`bbox`）和输出格式（`format`）即可使用。

加载示例（image/png 格式）：

``` js
'source-id': {
  'type': 'raster',
  'tiles': [
    'https://xxx?service=WMS&version=1.3.0&request=GetMap&layers=china:bj&bbox={bbox-epsg-3857}&width=512&height=512&srs=EPSG:3857&format=image/png&TRANSPARENT=TRUE'
  ]
}
```

注意url中的 `bbox` 参数值 `"{bbox-epsg-3857}"`。地图会自动计算地图范围替换该值，获取地图。这也是与下面WMTS同样用栅格格式，WMS不会模糊的原因。

<!-- <ClientOnly>
  <common-code-view name="service-wms"/>
</ClientOnly> -->

#### WMTS
> 标准：[Web Map Tile Service](http://www.opengeospatial.org/standards/wmts)

Web Map Tile Service（Web地图瓦片服务），简称 `WMTS`。WMTS 标准定义了一些操作允许用户访问瓦片地图。WMTS 服务中包括以下 3 个操作：
1. GetCapabilities（获取服务的元信息）
2. GetTile（获取切片）
3. GetFeatureInfo（可选，获取点选的要素信息）

WMTS的切片坐标系统和组织方式可参考下图：
<div align="center">
  <img :src="$withBase('/assets/images/WMTS切片坐标系统和组织方式.png')" />
</div>

利用 `GetTile` 操作和指定输出格式即可在中使用。

加载示例（image/png格式）：
``` js
'source-id': {
  'type': 'raster',
  'tiles': [
    'https://xxx/service/wmts?REQUEST=GetTile&SERVICE=WMTS&VERSION=1.0.0&LAYER=buildings:Chongqing&STYLE=&TILEMATRIX=EPSG:900913:{z}&TILEMATRIXSET=EPSG:900913&FORMAT=image/png&TILECOL={x}&TILEROW={y}'
    // 或 geoserver rest 服务
    // 'https:/xxx/wmts/rest/buildings:Chongqing/EPSG:900913/EPSG:900913:{z}/{y}/{x}?format=image/png'
  ]
}
```

::: warning 注意
这种方式请求栅格格式（如 `image/png`）数据会有些模糊，设置 `'tileSize': 256` 会好很多。但是实际 WMTS 请求返回的图片格式是清晰的。模糊的原因是地图的缩放是无极缩放，也就是 `zoom` 可以是小数，而 WMTS 的 `z` 值是整数，在渲染过程中有缩放，所以模糊了。

前面提到加载 wms 也不会模糊，但是 wms 实际上是根据请求范围实时渲染，加载速度不如瓦片服务。
:::

加载示例
``` js
'source-id': {
  'type': 'vector',
  'tiles': [
    // geoserver rest 服务
    // 'https://xxx/wmts/rest/buildings:Chongqing/EPSG:900913/EPSG:900913:{z}/{y}/{x}
  ]
}
```

<!-- <ClientOnly>
  <common-code-view name="service-wmts"/>
</ClientOnly> -->

#### WFS
> 标准：[Web Feature Service](http://www.opengeospatial.org/standards/wfs)

Web Feature Service（Web 要素服务），简称 WFS。WFS 标准定义了一些操作允许用户通过 HTTP 对空间数据进行查询、编辑等操作。WFS 服务中常用的操作包括：
1. GetCapabilities（获取服务中的要素类及支持的操作）
2. DescribeFeatureType（描述要素类的信息）
3. GetFeature（获取要素）
4. Transaction（创建、更新、删除数据的事务操作）

利用 `GetFeature` 操作和指定输出格式即可在使用。

加载示例（application/json 格式）：

``` js
'source-id': {
  'type': 'geojson',
  'data': `https://xxx?service=WFS&version=2.0.0&request=GetFeature&typeName=buildings:cq_point&outputFormat=application/json`
}
```

::: tip 提示
- wfs会请求全部数据，不适用于大量数据。但是支持空间查询和属性查询，也会经常用到。
- 文档：[wfs/wms filter](https://docs.geoserver.org/latest/en/user/filter/index.html#filtering)
  :::
<!-- <ClientOnly>
  <common-code-view name="service-wfs"/>
</ClientOnly> -->

## 图层
> `layers`

图层属性配置如下：
| 属性 | 类型 | 必须 | 描述 |
| :-- | :--: | :--: | :-- |
| **`id`** | string | 是 | 图层唯一标识 |
| **`type`** | string | 是 | 图层类型 |
| **`source`** | string | 否 | 数据源名称，图层类型除 `background` 外必须 |
| **`source-layer`** | string | 否 | 图层名，矢量瓦片源（vector）必须，其他类型不可用 |
| **`minzoom`** | number | 否 | 图层最小缩放级别 |
| **`maxzoom`** | number | 否 | 图层最大缩放级别 |
| **`filter`** | expression | 否 | 过滤器 |
| **`layout`** | object | 否 | 图层布局属性 |
| **`paint`** | object | 否 | 图层绘制属性 |
| **`metadata`** | any | 否 | 任意属性，对跟踪图层很有用，不影响渲染 |

图层示例：
``` js
'layers': [
  {
    'id': 'road',
    'type': 'line',
    'source': 'your source',
    'source-layer': 'road',
    'minzoom': 7,
    'maxzoom': 18,
    'layout': {
      'visibility': 'visible'
    },
    'paint': {
      'line-color': 'hsl(55, 1%, 20%)'
    },
    'filter': ['==', '$type', 'LineString']
    'metadata': {
      'type': 'base'
    }
  }
]
```

::: tip 提示
- **`"type"`** 属性必须是 `background`, `fill`, `line`, `symbol`, `raster`, `circle`, `fill-extrusion`, `heatmap`, `hillshade` 之一。
- 除 `background` 外的图层都需要引用一个源（source），图层从源获取数据、过滤要素和渲染。
- **`layout`** 属性都有 **`visibility`** 属性，可设置 `"visible"`（默认） 和 `"none"` 。
- 颜色支持 `十六进制`, `RGB`, `RGBA`, `HSL`, `HSLA`, `HTML 预定义颜色名称` 格式。
  :::


## 表达式
> 更详细的介绍请参考：[expressions](/guide/expression.html)

任何 `layout` 属性、`paint` 属性或 `filter` 的值都可以是表达式。示例：
``` js
{
  "circle-radius": [
    "interpolate", ["linear"], ["zoom"],
    // when zoom is 0, set each feature's circle radius to the value of its "rating" property
    0, ["get", "rating"],
    // when zoom is 10, set each feature's circle radius to four times the value of its "rating" property
    10, ["*", 4, ["get", "rating"]]
  ]
}
```

::: warning 注意
在表达式中， `layout` 属性和 `paint` 属性有一个很重要的区别。`paint` 属性，只要缩放级别发生变化，都会重新计算 `paint` 属性，即使是小数变化，比如在 4.1 - 4.6 之间。而 `layout` 属性只在整数缩放级别时计算，在 4.1 - 4.6 之间不会发生变化，只有在高于 5 或小于 4 时计算。
:::

### Types
表达式拥有强大的类型系统，并支持转换和检测。比如，表达式的输入和输出数据类型需和样式规范中的类型一致，在计算表达式时会自动检测，如果检测到错误，会在控制台输出错误提示。
### Feature data
- feature-state：要素状态，要素状态不是数据的某一属性，需要对通过要素 `id` 设置，如给要素设置 `hover` 状态：`map.setFeatureState({source: 'states', id: hoveredStateId}, {hover: false})`，然后在表达式中即可使用：`['feature-state', 'hover']`


### Lookup
- get：获取要素属性，如获取 `name` 属性：`['get', 'name']`
### Decision
在表达式中，可使用常用的条件逻辑，比如：`"if/then/else"` 的逻辑可使用 `'case'` 表达式，如需将输入的特定值映射不同的输出，可使用 `'match'` 表达式。
### Ramps, scales, curves
- interpolate：插值，支持 `linear`、`exponential` 和 `cubic-bezier`
- step：分段
### Variable binding
- let 绑定变量
- var 引用 `let` 绑定的变量
### String
- downcase
- upcase
### Color
- rgb
- rgba
### Math
支持基本的数学运算，如
``` js
['/', ['get', 'gdp'], 1000]
```

### Zoom
获取当前缩放级别，仅用于 `step` 或 `interpolate` 表达式的输入。
``` js
['zoom']: number 
```
```
{
      "id": "road",
      "type": "line",
      "source": "a",
      "paint": {
        "line-width": 10,
        "line-pattern": [
          "step", ["zoom"],
          "generic_icon", /*小于2级时用这个线型符号*/
          2,
          "generic_metro" /*大小或等于2级时用这个线型符号*/
        ]
      }
    }
```
### Heatmap
获取热力图图层中像素的核密度估计，只能用于 `heatmap-color` 属性。
``` js
['heatmap-density']: number
```
> 更详细的介绍请样式表达式请参考：[expressions](/guide/expression.html)
