Перейти к основному содержимому

GeoJSON

Для показа GeoJSON данных на карте:

  1. Подключите источник этих данных в карту.
  2. Добавьте слой в стиль карты, который объяснит, как рисовать эти данные.

Подключение источника данных

Возьмем простейший пример данных в формате GeoJSON:

const data = {
type: 'FeatureCollection',
features: [
{
type: 'Feature',
properties: {},
geometry: {
type: 'Polygon',
coordinates: [
[
[55.41, 25.34],
[55.44, 25.34],
[55.43, 25.37],
[55.41, 25.34],
],
],
},
},
],
};

Для их подключения в качестве источника данных карты нужно использовать класс GeoJsonSource:

const source = new mapgl.GeoJsonSource(map, {
data,
});

Так мы добавили полигон только в данные карты. Однако, отрисовать этот полигон не получится, поскольку его нельзя связать с конкретным слоем стиля карты. Полигон добавился в общий массив данных карты, а там его невозможно отличить от других полигонов.

Чтобы полигон отличался от других, можно добавить ему уникальное свойство в properties:

const data = {
type: 'FeatureCollection',
features: [
{
type: 'Feature',
properties: {
foo: 'qwe', // Уникальное свойство
},
geometry: {
type: 'Polygon',
coordinates: [
[
[55.41, 25.34],
[55.44, 25.34],
[55.43, 25.37],
[55.41, 25.34],
],
],
},
},
],
};

Либо добавить уникальное свойство всему источнику данных через поле attributes:

const source = new mapgl.GeoJsonSource(map, {
data,
attributes: {
bar: 'asd', // Уникальное свойство
},
});

Теперь такой полигон можно связать с новым слоем стилем карты, а значит и отрисовать.

Добавление слоя в стиль карты

Стиль карты — это конфиг, который описывает как рисовать данные карты. Стиль состоит из слоев. Каждый слой содержит:

  • в поле filter — логику фильтрации данных карты для определения, какие именно данные будут рисоваться этим слоем;
  • в поле style — описание внешнего вида объектов отрисовки (цвет, ширина, шрифт и пр.).

Подробнее про стиль карты можно узнать в Спецификации стиля.

Добавление через API

Выше мы добавили полигон в качестве источника данных карты, теперь его нужно связать с новым слоем стиля.

Для начала создадим новый слой:

const layer = {
id: 'my-polygons-layer', // ID каждого слоя должен быть уникальным

// Логика фильтрации или выбора данных для этого слоя
filter: [
'match',
['sourceAttr', 'bar'],
['asd'],
true, // Значение при совпадении атрибута bar источника cо значением "asd"
false, // Значение при несовпадении
],

// Тип объекта отрисовки
type: 'polygon',

// Стиль объекта отрисовки
style: {
color: '#0000ff',
},
};

Здесь в filter используются:

  • SourceAttrExpression — для получения значений из свойства bar источника данных;
  • MatchExpression — для сопоставления полученного свойства из атрибута bar со строковым значением "asd".

Если при добавлении данных был выбран вариант не со свойством источника данных, а с добавление свойства только одному объекту GeoJSON в properties, то вместо SourceAttrExpression нужно использовать GetExpression.

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

Добавление после загрузки стиля

Сразу после создания карты её стиль будет пустым, до тех пор пока он не загрузится с сервера. Важно дождаться его загрузки, прежде чем добавлять новый слой, поскольку загруженный стиль полностью затрет старый. Для этого в примере выше используется событие 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, '577315');

Добавление через редактор стилей

Для отображения источника данных необязательно добавлять слой через API, можно также добавить его в Редакторе стилей в свой стиль карты.

Для этого там при создании нового слоя на этапе выбора данных нужно нажать на кнопку JSON — добавить вручную и добавить MatchExpression, который нужно было бы указать в filter при добавлении слоя через API:

GeoJSON styles from editor

События

Чтобы подписаться на клик по объекту GeoJSON или на другие события MapEventTable, надо использовать метод on() у карты. Для объектов GeoJSON в событиях в поле targetData приходит специальный тип GeoJsonEventTargetData, который содержит все исходные данные объекта.

Комплексный пример

Ниже представлен сложный пример использования GeoJSON, в нем одновременно:

  • подключаются разные типы данных GeoJSON (Point, Polygon, LineString);
  • показываются разные объекты отрисовки (line, dashedLine, point, polygon);
  • используются составные выражения в filter;
  • используются выражения внутри стилевых свойств.