---
title: Layer Styles
source: https://vjmap.com/en/guide/layer.html
---

# Layer Styles

## Background

#### Parameters

##### layout parameters
|Name|Type|Description|
|:---|:---|:---|
|visibility|String| visible, whether visible: visible / none|

##### paint parameters
|Name|Type|Description|
|:---|:---|:---|
|background-color|String|Color examples: `#ff0`, `#ffff00`,`rgb(255, 255, 0)`,`rgba(255, 255, 0, 1)`,`hsl(100, 50%, 50%)`,`hsla(100, 50%, 50%, 1)`,`yellow`|
|background-opacity|Number|0～1.0, opacity, lower values are more transparent|
|`background-pattern`|String|picture_name, stretched image type for fill, must match the image name in the corresponding style library exactly|


## symbol

**Symbol style consists of two parts: `icon` and `text`, which are independent of each other**

> Core idea: Use a `GeoJSON layer` to implement specific style configuration, then dynamically add image annotations by `dynamically adding data` to the GeoJSON layer.

``` javascript
map.on('click', function(mapMouseEvent) {
  //Mouse click point coordinates
  var latlon = mapMouseEvent.lngLat;
  //Add a new annotation (vector feature)
  var symbol = { //Must be standard GeoJSON format
    "type": "Feature",
    "geometry": {
      "type": "Point",
      "coordinates": latlon.toArray()
    },
    "properties": {
      "name": "New points",
    }
  };
  GeoPoints.features.push(symbol);
  map.getSource('symbolLayer').setData(GeoPoints);//symbolLayer name must match the source above
});
```

``` javascript
//Add data source, GeoJSON here
map.addSource('symbolLayer', {
  "type": "geojson",
  "data": GeoPoints
});

// Add layer
map.addLayer({
  "id": "zondy",
  "type": "symbol",
  "source": "symbolLayer", //Must match symbolLayer above
  "filter": ["==", "name", "East Gate", "South Gate", "North Gate"], // Key: name is the GeoJSON property field
  "layout": {
    "symbol-placement": "point", //"point" for point-based annotations, "line" for annotations tiled along lines, "line-center" for annotations at line center
    "symbol-spacing": 200, //Pixels, space occupied by each annotation, only effective when symbol-placement=line
    "symbol-avoid-edges": false, //Avoid annotation collision at edges, generally not set

    "icon-allow-overlap": false, //true means when layers overlap, only the current icon stays visible
    "icon-ignore-placement": false, //If true, display even when other features collide
    "icon-optional": true, // true means when conflicting with other annotations, if text is not overlapped, show text and hide icon
    "icon-rotation-alignment": "viewport", //map: rotate with map, viewport: align with current view/data shape (line direction)
    "icon-size": 1.4, //Image scale factor
    "icon-text-fit": "none", //"none", "width", "height", "both" - fit image to text dimensions
    "icon-text-fit-padding": [0, 0, 0, 0], //Add internal padding when fitting to text size
    "icon-image": "college-15", //Like line-pattern, fill-pattern - corresponds to image name in style library
    "icon-rotate": 0, //Image rotation angle
    "icon-padding": 2, //Normal internal padding for image
    "icon-keep-upright": false, //true: keep image upright when map rotation changes, prevents upside-down display
    "icon-offset": [0, 0], //[x,y] image offset from anchor. Positive = right/down, negative = left/up. Each component multiplied by icon-size for final pixel offset. Combined with icon-rotate, offset is as if rotation is upward.
    "icon-anchor": "center", //"center", "left", "right", "top", "bottom", "top-left", "top-right", "bottom-left", "bottom-right" - image alignment
    "icon-pitch-alignment": "auto", //"map", "viewport" - alignment for road annotations, along road direction or rigid placement

    "text-pitch-alignment": "auto", //"map", "viewport" - alignment for road annotations, along road direction or rigid placement
    "text-rotation-alignment": "auto", //map: rotate with map, viewport: align with current view/data shape (line direction)
    "text-field": "{name}", //Fixed syntax, do not forget {} brackets
    "text-font": ["Open Sans Regular", "Arial Unicode MS Regular"], 
    "text-size": 20, //Font size, default 16
    "text-max-width": 10, //Max text width, default 10 ems
    "text-line-height": 1.2, //Line height, default 1.2 ems
    "text-letter-spacing": 0,
    "text-justify": "center", //Text alignment: "left", "center", "right"
    "text-anchor": "center", //Text anchor: "center", "left", "right", "top", "bottom", "top-left", "top-right", "bottom-left", "bottom-right"
    "text-max-angle": 45, //Max angle difference between adjacent characters at corners
    "text-rotate": 0, //Text rotation, degrees
    "text-padding": 0, //Text padding, pixels
    "text-keep-upright": false, //true: keep text upright when map rotation changes, prevents upside-down text
    "text-transform": "none", //"none", "uppercase", "lowercase" - display as all caps, all lowercase, or unchanged
    "text-offset": [4.5,0], //[x,y] text offset
    "text-allow-overlap": false, // true: when overlapping other annotations, keep current text visible
    "text-ignore-placement": false, //If true, display even when other features collide
    "text-optional": true, // true: when conflicting with other annotations, if icon is not overlapped, show icon and hide text
    "visibility": "visible", //visible/none
  },
  "paint": {
    "icon-opacity": 1.0, //Icon opacity
    "icon-color": "#202", //Icon color
    "icon-halo-color": "#888", //Icon halo color
    "icon-halo-width": 2, //Icon halo width
    "icon-halo-blur": 1, //Icon halo blur
    "icon-translate": [0, 0], //Display position offset from original in screen coordinates

    "text-opacity": 1.0, // Text opacity
    "text-color": "#fff", //Text color
    "text-halo-color": "#000", //Text halo color
    "text-halo-width": 2, //Text halo width
    "text-halo-blur": 1, //Text halo blur
    "text-translate": [0, 0] //Display position offset from original in screen coordinates
  }
});
```

The core of the code above consists of 4 parts:

> + **source** `Data source name` must match the previous map.addSource('sourceName'), `very important`
> + **filter** `Filter condition` Implement data filtering per your business logic, ensure property field matching
> + **layout** `View` Generally controls visibility, annotation collision avoidance, etc. Pay special attention when `type=symbol`
> + **paint** `Paint style` *This is where color, width, opacity and other styles are actually defined* - different types have different properties

---
#### Parameters
##### layout parameters
|Name|Type|Description|
|:---|:---|:---|
|||**Symbol parameters**|
|`symbol-placement`|String| "point" for point-based annotations, "line" for annotations tiled along lines|
|symbol-spacing|Number| 200, pixels, space occupied by each annotation, only effective when symbol-placement=line|
|symbol-avoid-edges|Bool| false, avoid annotation collision at edges, generally not set|
|||**Icon parameters**|
|icon-allow-overlap|Bool| false, true: when layers overlap, only current icon stays visible|
|icon-ignore-placement|Bool| false, if true, display even when other features collide|
|icon-optional|Bool| true, true: when conflicting with other annotations, if text not overlapped, show text and hide icon|
|`icon-rotation-alignment`|String| "viewport", map: rotate with map, viewport: align with current view/data shape (line direction)|
|`icon-size`|Number|1.4, image scale factor|
|icon-text-fit|String| "none", "none", "width", "height", "both" - fit image to text dimensions|
|icon-text-fit-padding|Number array| [0, 0, 0, 0], add internal padding when fitting to text size|
|`icon-image`|String| "college-15", like line-pattern, fill-pattern - corresponds to image name in style library|
|icon-rotate|Number| 0, image rotation angle|
|icon-padding|Number| 2, normal internal padding for image|
|icon-keep-upright|Bool| false, true: keep image upright when map rotation changes, prevents upside-down display|
|`icon-offset` |Number array|[0, 0], [x,y] image offset|
|icon-anchor|String| "center", "center", "left", "right", "top", "bottom", "top-left", "top-right", "bottom-left", "bottom-right" - image alignment|
|icon-pitch-alignment|String| "auto", "map", "viewport" - alignment for road annotations, along road direction or rigid placement|
|||**Text parameters**|
|text-pitch-alignment|String| "auto", "map", "viewport" - alignment for road annotations, along road direction or rigid placement|
|text-rotation-alignment|String| "auto", map: rotate with map, viewport: align with current view/data shape (line direction)|
|`text-field`|String| "{name}",|
|`text-font`|String array| ["Open Sans Regular", "Arial Unicode MS Regular"], 
|`text-size`|Number| 20, font size, default 16|
|text-max-width|Number| 10, max text width, default 10 ems|
|text-line-height|Number| 1.2, line height, default 1.2 ems|
|text-letter-spacing|Number| 0, letter spacing, rarely used|
|text-justify|String| "center", text alignment: "left", "center", "right"|
|text-anchor|String| "center", text anchor: "center", "left", "right", "top", "bottom", "top-left", "top-right", "bottom-left", "bottom-right"|
|text-max-angle|Number|45, max angle difference between adjacent characters at corners|
|text-rotate|Number| 0, text rotation, degrees|
|text-padding|Number| 0, text padding, pixels|
|text-keep-upright|Bool| false, true: keep text upright when map rotation changes, prevents upside-down text|
|text-transform|String| "none", "none", "uppercase", "lowercase" - display as all caps, all lowercase, or unchanged|
|`text-offset`|Number array| [4.5,0], [x,y] text offset|
|text-allow-overlap|Bool|true: when overlapping other annotations, keep current text visible|
|text-ignore-placement|Bool| `false, if true, display even when other features collide`|
|text-optional|Bool| true, true: when conflicting with other annotations, if icon not overlapped, show icon and hide text|
|visibility|String| "visible", visible/none|

##### paint parameters
|Name|Type|Description|
|:---|:---|:---|
|||**Icon parameters**|
|`icon-opacity`|Number| 1.0, icon opacity|
|`icon-color`|String|Icon color. Examples: `#ff0`, `#ffff00`,`rgb(255, 255, 0)`,`rgba(255, 255, 0, 1)`,`hsl(100, 50%, 50%)`,`hsla(100, 50%, 50%, 1)`,`yellow`|
|`icon-halo-color`|String|Icon halo color. Examples: `#ff0`, `#ffff00`,`rgb(255, 255, 0)`,`rgba(255, 255, 0, 1)`,`hsl(100, 50%, 50%)`,`hsla(100, 50%, 50%, 1)`,`yellow`|
|`icon-halo-width`|Number| 2, icon halo width|
|`icon-halo-blur`|Number| 1, icon halo blur|
|icon-translate|Number array|[x,y] display position offset from original in screen coordinates, rarely needed|
|||**Text parameters**|
|`text-opacity`|Number| 1.0, text opacity|
|`text-color`|String|Text color. Examples: `#ff0`, `#ffff00`,`rgb(255, 255, 0)`,`rgba(255, 255, 0, 1)`,`hsl(100, 50%, 50%)`,`hsla(100, 50%, 50%, 1)`,`yellow`|
|`text-halo-color`|String|Text halo color. Examples: `#ff0`, `#ffff00`,`rgb(255, 255, 0)`,`rgba(255, 255, 0, 1)`,`hsl(100, 50%, 50%)`,`hsla(100, 50%, 50%, 1)`,`yellow`|
|`text-halo-width`|Number| 2, text halo width|
|`text-halo-blur`|Number| 1, text halo blur, value should be `less than` `text-halo-width` above|
|text-translate|Number array|[x,y] display position offset from original in screen coordinates, rarely needed|


## Line

``` json
//Add data source, GeoJSON here
map.addSource('lineLayer', {
  "type": "geojson",
  "data": geojsonData
});
//Set layer style for data source
map.addLayer({
  "id": "roadid", //id must be unique, otherwise only drawn once
  "type": "line",
  "source": "lineLayer", //Must match lineLayer above
  "filter": ["==", "name", "Guanggu Ave"], // Key: name is the GeoJSON property field
  "layout": {
    "line-cap": "square", //butt pointed, round rounded, square flat
    "line-join": "miter", //bevel flat corner, round rounded corner, miter sharp corner
    "line-miter-limit": 2, //Miter limit, rarely used
    "line-round-limit": 1.05, //Round corner limit, rarely used
    "visibility": "visible", //Visibility: visible / none
  },
  "paint": {
    "line-width": 10, //Width
    "line-color": "#9c27b0", //Color
    "line-opacity": 0.8, //Opacity `0 ~ 1.0`
    "line-gap-width": 0, //Line gap width, turns one line into two with a gap in between
    "line-offset": 0, //Use sparingly - large values can cause distortion at corners
    "line-dasharray": [1,1],//Solid/dashed combination, e.g. for railway lines
    "line-blur": 2, //Blur, use with width - width 20 + blur 10 gives blurred edge effect, value should be less than line width
    "line-pattern": "picture_name", //Stretched image for line, must match image name in style library exactly
    "line-translate": [0,0] //Display position offset from original in screen coordinates, rarely needed
  }
});
```

The core of the code above consists of 4 parts:

> + **source** `Data source name` must match the previous map.addSource('sourceName'), `very important`
> + **filter** `Filter condition` Implement data filtering per your business logic, ensure property field matching
> + **layout** `View` Generally controls visibility, annotation collision avoidance, etc. Pay special attention when `type=symbol`
> + **paint** `Paint style` *This is where color, width, opacity and other styles are actually defined* - different types have different properties

---
#### Parameters

##### layout parameters

|Name|Type|Description|
|:---|:---|:---|
|line-cap|String|Default square, `butt` pointed, `round` rounded, `square` flat|
|line-join|String| Default miter, `bevel` flat corner, `round` rounded corner, `miter` sharp corner|
|line-miter-limit|Number| 2, miter limit, rarely used|
|line-round-limit|Number| 1.05, round corner limit, rarely used|
|visibility|String| visible, visibility: visible / none|

##### paint parameters
|Name|Type|Description|
|:---|:---|:---|
|line-width|Number| 10, width|
|line-color|String| Color examples: `#ff0`, `#ffff00`,`rgb(255, 255, 0)`,`rgba(255, 255, 0, 1)`,`hsl(100, 50%, 50%)`,`hsla(100, 50%, 50%, 1)`,`yellow`|
|line-opacity|Number| 0.8, opacity `0 ~ 1.0`|
|line-gap-width|Number| 0, line gap width, turns one line into two with a gap in between|
|line-offset|Number| 0, `use sparingly` - large values can cause distortion at corners|
|line-dasharray|Number array| [1,1], solid/dashed combination, e.g. for railway lines|
|line-blur|Number| 2, blur, use with width - width 20 + blur 10 gives blurred edge effect, value should be less than line width|
|`line-pattern`|String| picture_name, stretched image for line, `must` match image name in `style library Sprite` exactly|
|line-translate|Number array| [0,0] `[x,y]` display position offset from original in screen coordinates, rarely needed|

## Circle

``` json
//Add data source, GeoJSON here
map.addSource('circleLayer', {
  "type": "geojson",
  "data": geojsonData
});
//Set layer style for data source
map.addLayer({
  "id": "circle_cug", //id must be unique, otherwise only drawn once
  "type": "circle",// Fixed syntax circle/line/fill/fill-extrusion/symbol/background
  "source": "circleLayer", //Must match circleLayer in map.addSource('circleLayer') above
  "filter": ["==", "name", "CUG Wuhan"], // Filter by property; name is the GeoJSON property field
  "layout": {
    "visibility": "visible",//visible/none - whether visible
  },
  "paint": {
    "circle-radius": 15, //Radius
    "circle-color": "#202", //Color
    "circle-opacity": 0.8, //Opacity
    "circle-stroke-width": 5, //Stroke width
    "circle-stroke-color": "#0000FF", //Stroke color
    "circle-stroke-opacity": 0.7, //Stroke opacity
    "circle-translate": [0,0] //Display position offset from original in screen coordinates, rarely needed
  }
});
```

The core of the code above consists of 4 parts:

> + **source** `Data source name` must match the previous map.addSource('sourceName'), `very important`
> + **filter** `Filter condition` Implement data filtering per your business logic, ensure property field matching
> + **layout** `View` Generally controls visibility, annotation collision avoidance, etc. Pay special attention when `type=symbol`
> + **paint** `Paint style` *This is where color, width, opacity and other styles are actually defined* - different types have different properties

---
#### Parameters

##### layout parameters
|Name|Type|Description|
|:---|:---|:---|
|visibility|String| visible, visibility: visible / none|

##### paint parameters
|Name|Type|Description|
|:---|:---|:---|
|circle-radius|Number|15, radius|
|circle-color|String|Color examples: `#ff0`, `#ffff00`,`rgb(255, 255, 0)`,`rgba(255, 255, 0, 1)`,`hsl(100, 50%, 50%)`,`hsla(100, 50%, 50%, 1)`,`yellow`|
|circle-opacity|Number|0～1.0, opacity, lower values are more transparent|
|circle-stroke-width|Number|5, stroke width|
|circle-stroke-color|String|: #0000FF, stroke color. Examples: `#ff0`, `#ffff00`,`rgb(255, 255, 0)`,`rgba(255, 255, 0, 1)`,`hsl(100, 50%, 50%)`,`hsla(100, 50%, 50%, 1)`,`yellow`|
|circle-stroke-opacity|Number|0.7, stroke opacity|
|circle-translate|Number array|[0,0] display position offset from original in screen coordinates, rarely needed|

## Fill
``` json
//Add data source, GeoJSON here
map.addSource('fillLayer', {
  "type": "geojson",
  "data": geojsonData
});
//Set layer style for data source
map.addLayer({
  "id": "huiyishi", //id must be unique, otherwise only drawn once
  "type": "fill",
  "source": "fillLayer", //Must match geojsonPolygon above
  "filter": ["==", "name", "Meeting room"], // Key: name is the GeoJSON property field
  "layout": {
    "visibility": "visible",//visible/none - whether visible
  },
  "paint": {
    "fill-antialias": true, //Antialiasing, true fills boundary gaps
    "fill-color": "#00695c", //Color
    "fill-opacity": 0.9, //Opacity `0 ~ 1.0`
    "fill-outline-color": "#FFFF00", //Outline color - note, there is no outline width option
    "fill-pattern":"picture_name", //Stretched image for fill, must match image name in style library exactly
    "fill-translate": [0,0] //Display position offset from original in screen coordinates, rarely needed
  }
});
map.addLayer({
  "id": "bounding",
  "type": "line",  //Believe your eyes - this is indeed line, polygon can reuse line style
  "source": "fillLayer", //Must match geojsonPolygon above
  "filter": ["==", "name", "Boundary"], // Key: name is the GeoJSON property field
  "paint": {
    "line-width": 4, //Width
    "line-color": "#e51c23", //Color
    "line-opacity": 1.0, //Opacity
    "line-gap-width": 2, //Line gap width, turns one line into two with a gap in between
  }
});
```

The core of the code above consists of 4 parts:

> + **source** `Data source name` must match the previous map.addSource('sourceName'), `very important`
> + **filter** `Filter condition` Implement data filtering per your business logic, ensure property field matching
> + **layout** `View` Generally controls visibility, annotation collision avoidance, etc. Pay special attention when `type=symbol`
> + **paint** `Paint style` *This is where color, width, opacity and other styles are actually defined* - different types have different properties

---
#### Parameters

##### layout parameters

|Name|Type|Description|
|:---|:---|:---|
|visibility|String| visible, visibility: visible / none|

##### paint parameters
|Name|Type|Description|
|:---|:---|:---|
|fill-antialias|Bool| true, antialiasing, true fills boundary gaps|
|fill-color|String|Color examples: `#ff0`, `#ffff00`,`rgb(255, 255, 0)`,`rgba(255, 255, 0, 1)`,`hsl(100, 50%, 50%)`,`hsla(100, 50%, 50%, 1)`,`yellow`|
|fill-opacity|Number| 0.9, opacity|
|fill-outline-color|String| #FFFF00, outline color - note, there is `no outline width` option|
|`fill-pattern`|String|picture_name, stretched image for fill, must match image name in style library exactly|
|fill-translate|Number array| [0,0] `[x,y]` display position offset from original in screen coordinates, rarely needed|


## fillextrusion


``` json
//Add data source, GeoJSON here
map.addSource('fillExtrusionLayer', {
  "type": "geojson",
  "data": geojsonData
});
//Set layer style for data source
map.addLayer({
  "id": "main", //id must be unique, otherwise only drawn once
  "type": "fill-extrusion",
  "source": "fillExtrusionLayer", //Must match fillExtrusionLayer above
  "filter": ["==", "name", "Main building"], // Key: name is the GeoJSON property field
  "paint": {
    "fill-extrusion-height": ['get', 'height'], //Fixed syntax, get numeric value of height property
    "fill-extrusion-base": 10,//Base height, height relative to horizontal plane
    "fill-extrusion-color": "#00695c", //Color
    "fill-extrusion-opacity": 0.9, //Opacity `0 ~ 1.0`
    "fill-extrusion-pattern":"si-main-3", //Stretched image for fill, must match image name in style library exactly
    "fill-extrusion-translate": [0,0] //Display position offset from original in screen coordinates, rarely needed
  }
});
```

The core of the code above consists of 4 parts:

> + **source** `Data source name` must match the previous map.addSource('sourceName'), `very important`
> + **filter** `Filter condition` Implement data filtering per your business logic, ensure property field matching
> + **layout** `View` Generally controls visibility, annotation collision avoidance, etc. Pay special attention when `type=symbol`
> + **paint** `Paint style` *This is where color, width, opacity and other styles are actually defined* - different types have different properties

---
#### Parameters

##### layout parameters

|Name|Type|Description|
|:---|:---|:---|
|visibility|String| visible, visibility: visible / none|

##### paint parameters
|Name|Type|Description|
|:---|:---|:---|
|`fill-extrusion-height`|Number| `['get', 'height']`, fixed syntax to get height property value, or pass a `fixed number` directly|
|fill-extrusion-base|Number| 10, base height, height `relative to horizontal plane`|
|fill-extrusion-color|String|#00695c. Color examples: `#ff0`, `#ffff00`,`rgb(255, 255, 0)`,`rgba(255, 255, 0, 1)`,`hsl(100, 50%, 50%)`,`hsla(100, 50%, 50%, 1)`,`yellow`|
|fill-extrusion-opacity|Number| 0.9, opacity|
|`fill-extrusion-pattern`|String|`si-main-3`, stretched image for fill surface, must match image name in style library exactly|
|fill-extrusion-translate|Number array| [0,0] `[x,y]` display position offset from original in screen coordinates, rarely needed|
