Стили | MapGL | 2GIS Documentation
MapGL JS API

Стили карт

Вы можете изменять внешний вид карты с помощью применения к ней стилей. Стиль — это документ, который определяет внешний вид карты: какие данные отрисовывать, в каком порядке, как стилизовать данные при отрисовке, какие иконки использовать и т.д.

Вы можете создать собственный стиль карты с помощью Редактора стилей.

Вы можете передать любой валидный идентификатор стиля с помощью опции style:

const map = new mapgl.Map('container', {
    center: [55.31878, 25.23584],
    styleZoom: 13,
    key: 'Ваш ключ доступа к API',
    style: 'Ваш идентификатор стиля карты',
});

Все инструкции по созданию вашего стиля и получению его идентификатора вы можете получить в документации Редактора стилей карты.

Приведенный выше пример использует опцию styleZoom вместо zoom. Выберите её, если вы хотите установить тот же масштаб, что и в настройках стиля. Эта опция будет описана позже.

Также есть удобная опция defaultBackgroundColor, с помощью которой вы можете установить цвет фона во время загрузки вашего стиля. Это может быть очень полезно, если базовая цветовая тема нового стиля отличается от таковой у стиля по умолчанию. Например, вы можете установить темный цвет фона по умолчанию для тёмного стиля:

<!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>

Если вам нужно изменить стиль карты in runtime, вы можете использовать метод setStyleById:

const map = new mapgl.Map('container', {
    center: [37.616723, 55.751],
    styleZoom: 13,
    key: 'Ваш ключ для доступа к API',
});

map.setStyleById('Идентификатор вашего стиля карты');

Речь идёт об изменении стиля карты в целом, например, как при переключении между светлой и тёмной темой:

<!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>

Чтобы изменить текущий стиль, экземпляр карты имеет два метода: addLayer и removeLayer.

После создания карты ее стиль будет пустым до тех пор, пока он не будет загружен с сервера. Важно добавлять новые слои только после загрузки стиля, поскольку загруженный стиль полностью перезапишет старый. Для этого в приведенном выше примере используется событие styleload, которое генерируется каждый раз после установки нового стиля:

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

Если вы измените стиль карты с помощью метода map.setStyleById(), вы также можете использовать Promise, возвращаемый этим методом:

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

Слои стиля карты упорядочены относительно друг друга. Порядок слоев определяет последовательность их отрисовки на карте.

По умолчанию метод map.addLayer(layer) добавляет новый слой в конец списка, т.е. новый слой будет отрисован последним. Если вам нужно добавить слой не в конец, а перед другим слоем, укажите ID другого слоя в качестве второго аргумента:

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

Вы также можете добавить слой перед слоями, настроенными в Редакторе стилей:

map.addLayer(layer, 'other roads');
<!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');
    });
  </script>
</body>

Рассмотрим небольшой фрагмент объекта стиля:

{
    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%)',
        ],
    },
},

Объект описывает цвет фона для данных с полем "sublayer", равным s_region. Обратите внимание на фрагмент кода ниже:

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

Этот массив описывает, как цвет фона зависит от масштаба. Но это не обычный уровень масштабирования, который можно установить в настройках карты, а styleZoom. Параметры styleZoom и zoom задают один и тот же масштаб карты, но в разных проекциях. А значение styleZoom используется в стилях.

Вы можете задать styleZoom в настройках карты, если хотите установить тот же масштаб, что и в настройках стиля. Если заданы обе опции (zoom и styleZoom), то styleZoom имеет более высокий приоритет, чем zoom. Если вам нужно установить/получить styleZoom in runtime, вы можете использовать setStyleZoom и getStyleZoom.

Пример, где вы можете увидеть разницу между zoom и 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 введён для компенсации искажений проекции Меркатора. Благодаря этому объекты карты отображаются в одном и том же масштабе на разных широтах.

Используйте zoom, если хотите работать с масштабом карты. Он будет одинаковым вблизи полярного круга и на экваторе.

Используйте styleZoom, если вы хотите работать именно с границами масштабирования в стилях. Обычно это тот случай, когда вы разрабатываете стиль карты с помощью Редактора стилей карты и вам необходимо убедиться, что определенные объекты, ограниченные масштабом, будут видны.

По умолчанию используется опция zoom.