---
title: Map Layers
source: https://vjmap.com/en/guide/mapLayers.html
---

# Map Layers

## Overview

---

Layers define how data from data sources is displayed on the map. Each layer must have a unique ID and cannot be duplicated.

Each layer must specify a data source type. The available layer types are:

```js
Background type: 'background'
Polygon geometry types: 'fill', 'extrusion'
Raster image type: 'raster'
Line geometry type: 'line'
Point geometry types: 'symbol', 'circle', 'heatmap'
```

## Layer Specification

---

The layer style structure is JSON. The root structure is:

```js
{
    "id": "road-layer-1",
    "type": "line",
    "source": "RoadSource",
    "source-layer": "Road",
    "layout": {...},
    "paint": {...},
    "minzoom": 6,
    "maxzoom": 17.5,
    "filter": [...]
}
```


Field definitions:

**id**: Layer ID, required; (must be unique, cannot be duplicated)

**type**: Layer render type, required; (value range, see "Overview" above)

**source**: Data source ID to use; (required when layer type is not background)

**source-layer**: Layer identifier in the vector data source; (required when data source type is vector; omit for other source types)

**layout**: Layout properties

**paint**: Paint properties

**minzoom**: Minimum zoom level at which the layer is visible, optional; (value can be decimal or integer, range [0,24]; if not set, layer is visible at map's minimum zoom)

**maxzoom**: Maximum zoom level at which the layer is visible, optional; (value can be decimal or integer, range [0,24]; if not set, layer is visible at map's maximum zoom)

**filter**: Filter condition for features in the data source, optional; (layer displays only when data source feature data matches the filter condition)

### filter Specification

---

Filter selects features from all layers. Filter forms include:

**1. Existence filter:**

Expression form: [way, key]

```js
Existence filters mainly use "has" and "!has"

["has", "count"], filters features that have property "count"
["!has","count"], filters features that do not have property "count"
```


**2. Comparison filter:**

Expression form: [way, key, value]

```js
Comparison filters include equals "==", greater ">", less "<", not equals "!=", greater or equal ">=", less or equal "<="

["==", "count", "1000"], filters features where property "count" equals 1000
//  Note: if data source stores "1000" as string, filter uses strict type matching
```


**3. Membership filter:**

Form: [way, key, v0,v1,…,vn]

```js
Membership filters mainly use "in" and "!in"

["in", "name", "point", "fill", "line"],
//  filters features where property "name" is "point", "fill", or "line"
```


**4. Match filter:**

Selects output when label value matches input. If no match is found, uses fallback value. Input can be any expression (e.g. ["get", "building_type"]). Each label must be:

A single literal value; or
An array of literal values, which must be all strings or all numbers (e.g. [100, 101] or ["c", "b"]). If any value in the array matches, the input matches, similar to the deprecated "in" operator.
Each label must be unique. If input type does not match label type, the result is the fallback value.

```js
"circle-color": [
    'match', ['get', 'name'],
    'Point1', 'red',
    'Point2', 'yellow',
    ['Point3','Point4'], 'blue',
    '#fff'
],

// Get name value from feature's properties, match corresponding color by name; default (no match) is #fff. ['Point3','Point4'] means label can be array type.

```



**5. Combination filter:**

Form: [way, f0,f1,…,fn]

```js
Combination filters mainly use "all", "any", "none"
"all" means data satisfying all filter conditions, "any" means satisfying any one condition, "none" means filtering data not satisfying all conditions
["all", ["<=", "count", 34], ["like", "code", "101"]]
//  filters features where "count" >= 34 and "code" contains 101
```


For more expression syntax, see [Style Expressions](/en/guide/expression.html)


### Layer Style Operations

---

Common layer style methods:

**Get a specific layout style value for a layer:**

```js
Parameters: layer id, layout parameter name, example:
map.getLayoutProperty('my-layer-id', 'visibility')
```


**Set a specific layout style value for a layer:**

```js
Parameters: layer id, layout parameter name, layout parameter value, example:
map.setLayoutProperty('my-layer-id', 'visibility', 'none')
```


**Get a specific paint style value for a layer:**

```js
Parameters: layer id, paint parameter name, example:
map.getPaintProperty('my-layer-id', 'fill-color')
```


**Set a specific paint style value for a layer:**

```js
Parameters: layer id, paint parameter name, paint parameter value, example:
map.setPaintProperty('my-layer-id', 'fill-color', '#faafee')
```


**Set layer zoom range:**

```js
Parameters: layer id, minimum zoom level, maximum zoom level, example:
map.setLayerZoomRange('my-layer-id', 6, 12)
```


**Get layer filter:**

```js
Parameters: layer id, example:
map.getFilter('my-layer-id')
```


**Set layer filter:**

```js
Parameters: layer id, filter content. If filter content is null or undefined, clears all existing filters on the layer, example:
map.setFilter('my-layer-id', ['==', 'name', 'myname'])
```

## Three Ways to Add Layers

::: tip Tip
The following three approaches produce the same result; they differ only in level of encapsulation
:::
**Example: adding a line layer**

Sample line data:

```js
var geoLines = {
  "type": "LineString",
  "properties":{
      "prop0": "value0"
  },
  "coordinates": [
      [
          10,
          30
      ],
      [
          50,
          30
      ],
      [
          110,
          40
      ]
  ]
};
```
### Approach 1
::: tip Tip
Use `kebab-case` for property names
:::

```js
map.addSource("lines", {
    type: "geojson",
    data: geoLines
});
map.addLayer({
    id: 'route',
    source: 'lines',
    type: 'line',
    "layout": {
        "line-cap": "square", //butt pointed, round rounded, square flat
        "line-join": "round" //bevel flat corner, round rounded corner, miter sharp corner
    },
    "paint": {
        "line-width": 20, //width
        "line-color": "#FF0000", //color
        "line-opacity": 0.8 //opacity
}})
```

### Approach 2
::: tip Tip
Use camelCase for properties; no need to distinguish `layout` vs `paint`. For more details see [Data Sources and Layers](/en/guide/sourcelayer.html)
:::

```js

map.addGeoJSONSource("lines", geoLines);
map.addLineLayer("route", "lines", {
    lineCap: "square", //butt pointed, round rounded, square flat
    lineJoin: "round", //bevel flat corner, round rounded corner, miter sharp corner
    lineWidth: 20, //width
    lineColor: "#FF0000", //color
    lineOpacity: 0.8 //opacity
})
```
### Approach 3
::: tip Tip
Further simplified; encapsulation avoids passing sourceID and layerID
:::

```js
let polylines = new vjmap.Polyline({
    data: geoLines,
    lineCap: "square", //butt pointed, round rounded, square flat
    lineJoin: "round", //bevel flat corner, round rounded corner, miter sharp corner
    lineWidth: 20, //width
    lineColor: "#FF0000", //color
    lineOpacity: 0.8 //opacity
});
polylines.addTo(map);
```
