Styles | MapGL | Urbi Documentation

Map styles

You have the ability to change the design of the map by applying styles to the map. The style is a document that defines the visual appearance of the map: what data to draw, the order to draw it in, and how to style the data when drawing it, what icons to draw and etc.

You can create your own map style by using the map Style Editor.

You can pass any valid style ID via the option style:

const map = new mapgl.Map('container', {
    center: [55.31878, 25.23584],
    styleZoom: 13,
    key: 'Your API access key',
    style: 'Your map style identifier',
});

All instructions for creating your style and getting its identifier you can get on map Style Editor docs.

The example above uses styleZoom option instead of zoom. Use it, if you want to set the same zoom that is used in the style settings. This option will be described later.

Also, there is a convenient option defaultBackgroundColor with which you can set the background color while your style is loading. This can be really helpful when the new style has a different base color theme from the default style. For example, you can set the dark default background color for the dark style:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>2GIS Map API</title>
        <meta name="description" content="Style apply example" />
        <style>
            html,
            body,
            #container {
                margin: 0;
                width: 100%;
                height: 100%;
                overflow: hidden;
            }
        </style>
    </head>
    <body>
        <div id="container"></div>
        <script src="https://mapgl.2gis.com/api/js/v1"></script>
        <script>
            const map = new mapgl.Map('container', {
                center: [55.187609, 25.141736],
                styleZoom: 16,
                pitch: 40,
                rotation: -45,
                key: 'Your API access key',
                style: 'e05ac437-fcc2-4845-ad74-b1de9ce07555',
                defaultBackgroundColor: '#3b3b3b',
            });
        </script>
    </body>
</html>

If you need to change the map style in runtime, you can use setStyleById method:

const map = new mapgl.Map('container', {
    center: [37.616723, 55.751],
    styleZoom: 13,
    key: 'Your API access key',
});

map.setStyleById('Your map style identifier');

This is about changing the map style as a whole, for example when switching between a light and dark theme:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>2GIS Map API</title>
        <meta name="description" content="Style apply in runtime example" />
        <style>
            html,
            body,
            #container {
                margin: 0;
                width: 100%;
                height: 100%;
                overflow: hidden;
                font-family: Helvetica, Arial, sans-serif;
            }

            #dark_theme, #light_theme {
                margin: 0 10px 10px;
                padding: 3px 12px;
                background: #3b3b3b;
                color: #fff;
                border: none;
            }
        </style>
    </head>
    <body>
        <div>
            Click to switch theme:
            <button id="dark_theme">Switch to dark theme 🌙</button>
            <button id="light_theme">Switch to light theme 🌞</button>
        </div>

        <div id="container"></div>
        <script src="https://mapgl.2gis.com/api/js/v1"></script>
        <script>
            const map = new mapgl.Map('container', {
                center: [55.187609, 25.141736],
                styleZoom: 16,
                pitch: 40,
                rotation: -45,
                key: 'Your API access key',
            });

            document.getElementById('dark_theme').addEventListener('click', function() {
                map.setStyleById('e05ac437-fcc2-4845-ad74-b1de9ce07555');
            });
            document.getElementById('light_theme').addEventListener('click', function() {
                map.setStyleById('c080bb6a-8134-4993-93a1-5b4d8c36a59b');
            });
        </script>
    </body>
</html>

In order to modify current style the map instance has two methods: addLayer and removeLayer.

After creating a map, its style will be empty until it is loaded from the server. It is important to add new layers only after style loading because the loaded style will completely overwrite the old one. To do this, the example above uses styleload event, which is emitted every time after a new style is set:

map.on('styleload', () => {
    map.addLayer(layer);
});

If you change a map style with map.setStyleById() method, you can also use Promise that the method returns:

map.setStyleById('e05ac437-fcc2-4845-ad74-b1de9ce07555').then(() => {
    map.addLayer(layer);
});

Layers of a map style are ordered relative to each other. The order of the layers determines the sequence in which they are drawn on the map.

By default, the map.addLayer(layer) method adds a new layer to the end of the layers list, i.e. the new layer will be drawn last. If you need to add the layer not at the end, but before of another layer, you need to specify the ID of another layer in the method as the second argument:

map.addLayer(anotherLayer, 'my-polygons-layer');

You can also add the layer before the layers that are configured in the Style Editor:

map.addLayer(layer, 'other roads tunnel');
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>2GIS Map API</title>
  <meta name="description" content="map.addLayer under roads example" />
  <style>
    html,
    body,
    #container {
      margin: 0;
      width: 100%;
      height: 100%;
      overflow: hidden;
    }
  </style>
</head>

<body>
  <div id="container"></div>
  <script src="https://mapgl.2gis.com/api/js/v1"></script>
  <script>
    const map = new mapgl.Map('container', {
      center: [55.425, 25.355],
      zoom: 13,
      key: 'Your API access key',
    });
    const layer = {
      "id": "newLayer",
      "name": "Country, 2GIS",
      "type": "polygon",
      "style": {
        "color": "#949494ee",
        "visibility": "visible"
      },
      "filter": [
        "match",
        [
          "get",
          "sublayer"
        ],
        [
          "Country_2gis_area"
        ],
        true,
        false
      ]
    }
    map.on('styleload', () => {
      map.addLayer(layer, 'other roads tunnel');
    });
  </script>
</body>

Consider one little piece from a style object:

{
    type: 'polygon',
    id: 'background',
    filter: ['match', ['get', 'sublayer'], ['s_region'], true, false],
    style: {
        color: [
            'interpolate', ['linear'], ['zoom'],
            9, 'hsl(50, 61%, 90%)',
            12, 'hsl(51, 37%, 90%)',
            14, 'hsl(49, 48%, 91%)',
            16, 'hsl(51, 51%, 92%)',
        ],
    },
},

This object describes the background color for data with the "sublayer" field equal to s_region. Please note the code snippet below:

color: [
    'interpolate', ['linear'], ['zoom'],
    9, 'hsl(50, 61%, 90%)',
    12, 'hsl(51, 37%, 90%)',
    14, 'hsl(49, 48%, 91%)',
    16, 'hsl(51, 51%, 92%)',
],

This array describes how the background color depends on zoom. But it is not an ordinary zoom level, which you can set in map options, it is styleZoom. The styleZoom and zoom options set the same map scale but in different projections. And styleZoom value is used in styles.

You can set styleZoom in map options if you want to set the same zoom that is used in the style settings. If both options are set (zoom and styleZoom), the styleZoom has a higher priority than the zoom option. If you need to set/get styleZoom in runtime, you can use setStyleZoom and getStyleZoom methods.

There is an example, where you can see the difference between zoom and styleZoom:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>2GIS Map API</title>
        <meta name="description" content="Style zoom example" />
        <style>
            html,
            body {
                margin: 0;
                width: 100%;
                height: 100%;
                overflow: hidden;
                font-family: Helvetica, Arial, sans-serif;
            }
            #container_1, #container_2 {
                height: 250px;
                width: 100%;
                overflow: hidden;
            }
        </style>
    </head>
    <body>
        <h2>Map with zoom option equal to 16</h2>
        <div id="container_1"></div>
        <h2>Map with styleZoom option equal to 16</h2>
        <div id="container_2"></div>
        <script src="https://mapgl.2gis.com/api/js/v1"></script>
        <script>
            let key = 'Your API access key';
            const map_1 = new mapgl.Map('container_1', {
                center: [55.190803, 25.141451],
                zoom: 16,
                pitch: 40,
                rotation: -90,
                key,
            });
            const map_2 = new mapgl.Map('container_2', {
                center: [55.190803, 25.141451],
                styleZoom: 16,
                pitch: 40,
                rotation: -90,
                key,
            });
        </script>
    </body>
</html>

styleZoom introduced to compensate Mercator projection distortions. It makes map objects appear with the same scale on different latitudes.

Use zoom if you want to work with map scale. Map scale will be the same near the Arctic circle and on the equator.

Use styleZoom if you want to work precisely with zoom boundaries in styles. Usually, this is the case when you develop map style with map Style Editor and need to ensure that certain zoom-bounded objects will be visible.

By default, the zoom option is used.