LineString геометрия

LineString — один из базовых типов геометрии стандарта GeoJSON, предназначенный для представления линейных объектов. В картографических приложениях такие объекты используются для отображения дорог, маршрутов, железнодорожных путей, рек, трубопроводов, линий электропередачи, границ и любых других объектов, состоящих из последовательности связанных точек.

В Mapbox GL JS геометрия LineString чаще всего отображается при помощи слоя типа line, который визуализирует набор координат в виде непрерывной линии на карте.


Структура LineString в GeoJSON

LineString содержит массив координат, где каждая координата представляет собой пару значений:

[долгота, широта]

Простейший пример:

{
    "type": "LineString",
    "coordinates": [
        [37.6176, 55.7558],
        [37.6500, 55.7600],
        [37.7000, 55.7800]
    ]
}

Каждая следующая точка соединяется с предыдущей прямым сегментом.

Визуально такая геометрия выглядит следующим образом:

Точка A -------- Точка B -------- Точка C

Mapbox GL JS автоматически строит между ними линии.


Создание GeoJSON-источника с LineString

Линейная геометрия обычно передаётся в карту через источник данных (source).

Пример создания маршрута:

map.addSource('route', {
    type: 'geojson',
    data: {
        type: 'Feature',
        geometry: {
            type: 'LineString',
            coordinates: [
                [37.6176, 55.7558],
                [37.6500, 55.7600],
                [37.7000, 55.7800]
            ]
        }
    }
});

Источник содержит:

  • тип источника geojson;
  • объект Feature;
  • геометрию LineString;
  • массив координат.

Отображение LineString на карте

После создания источника необходимо добавить слой.

map.addLayer({
    id: 'route-line',
    type: 'line',
    source: 'route',
    paint: {
        'line-color': '#ff0000',
        'line-width': 4
    }
});

Результат:

  • линия окрашивается в красный цвет;
  • толщина линии составляет 4 пикселя;
  • геометрия отображается поверх базовой карты.

Формат координат

Mapbox GL JS использует стандарт WGS84.

Порядок координат всегда следующий:

[longitude, latitude]

Правильно:

[37.6176, 55.7558]

Неправильно:

[55.7558, 37.6176]

Ошибочный порядок координат приводит к отображению объекта в совершенно другом месте земного шара.


Минимальное количество точек

LineString должен содержать как минимум две точки.

Корректный пример:

{
    type: "LineString",
    coordinates: [
        [37.61, 55.75],
        [37.62, 55.76]
    ]
}

Некорректный пример:

{
    type: "LineString",
    coordinates: [
        [37.61, 55.75]
    ]
}

Одна координата не позволяет построить линию.


FeatureCollection с несколькими линиями

На практике часто требуется отображать множество маршрутов одновременно.

Для этого используется FeatureCollection.

{
    type: "FeatureCollection",
    features: [
        {
            type: "Feature",
            geometry: {
                type: "LineString",
                coordinates: [
                    [37.61, 55.75],
                    [37.62, 55.76]
                ]
            }
        },
        {
            type: "Feature",
            geometry: {
                type: "LineString",
                coordinates: [
                    [37.70, 55.80],
                    [37.75, 55.82]
                ]
            }
        }
    ]
}

Каждая линия представляет отдельный объект Feature.


Свойства объектов

Каждая линия может содержать собственные атрибуты.

{
    type: "Feature",
    properties: {
        name: "Маршрут №1",
        distance: 12.5,
        status: "active"
    },
    geometry: {
        type: "LineString",
        coordinates: [
            [37.61, 55.75],
            [37.62, 55.76]
        ]
    }
}

Свойства могут использоваться:

  • для фильтрации;
  • для отображения всплывающих окон;
  • для стилизации линий.

Изменение цвета через свойства

Mapbox GL JS позволяет динамически оформлять линии на основе данных объекта.

Источник:

{
    type: "Feature",
    properties: {
        color: "#00ff00"
    },
    geometry: {
        type: "LineString",
        coordinates: [
            [37.61, 55.75],
            [37.62, 55.76]
        ]
    }
}

Слой:

map.addLayer({
    id: 'routes',
    type: 'line',
    source: 'routes',
    paint: {
        'line-color': ['get', 'color'],
        'line-width': 4
    }
});

Каждый объект будет использовать собственный цвет.


Настройка толщины линии

Толщина задаётся параметром:

'line-width'

Пример:

paint: {
    'line-width': 8
}

Толстые линии часто используются для:

  • автомобильных маршрутов;
  • магистралей;
  • визуального выделения важных объектов.

Прозрачность линий

Для управления прозрачностью применяется свойство:

'line-opacity'

Пример:

paint: {
    'line-color': '#0066ff',
    'line-width': 5,
    'line-opacity': 0.4
}

Диапазон значений:

0   — полностью прозрачная
1   — полностью непрозрачная

Пунктирные линии

Для отображения пунктирных маршрутов используется свойство:

'line-dasharray'

Пример:

paint: {
    'line-color': '#000000',
    'line-width': 3,
    'line-dasharray': [2, 2]
}

Значения означают:

2 пикселя линия
2 пикселя пробел

Скругление углов

При соединении сегментов линии могут образовываться острые углы.

Параметр:

line-join

Позволяет управлять соединением.

layout: {
    'line-join': 'round'
}

Варианты:

round
bevel
miter

Наиболее распространён вариант round.


Оформление концов линии

Концы линии настраиваются свойством:

line-cap

Пример:

layout: {
    'line-cap': 'round'
}

Возможные значения:

butt
round
square

Скруглённые окончания обычно выглядят более естественно.


Линии с градиентом

Mapbox GL JS поддерживает плавное изменение цвета вдоль маршрута.

paint: {
    'line-width': 6,
    'line-gradient': [
        'interpolate',
        ['linear'],
        ['line-progress'],
        0, '#0000ff',
        1, '#ff0000'
    ]
}

Особенности:

  • цвет изменяется от синего к красному;
  • используется значение line-progress;
  • работает только с GeoJSON-источниками.

Использование line-progress

Специальное выражение:

['line-progress']

Возвращает положение точки вдоль линии.

Диапазон:

0.0 → начало линии
1.0 → конец линии

Применяется для:

  • градиентов;
  • анимации движения;
  • выделения пройденного участка маршрута.

Динамическое обновление маршрута

Координаты можно изменять после создания источника.

const source = map.getSource('route');

source.setData({
    type: 'Feature',
    geometry: {
        type: 'LineString',
        coordinates: [
            [37.61, 55.75],
            [37.65, 55.78],
            [37.70, 55.80]
        ]
    }
});

После вызова setData() линия автоматически перерисовывается.


Анимация движения маршрута

Один из популярных сценариев — постепенное построение линии.

const coordinates = [];

По мере движения объекта новые точки добавляются:

coordinates.push([lng, lat]);

Затем источник обновляется:

source.setData({
    type: 'Feature',
    geometry: {
        type: 'LineString',
        coordinates: coordinates
    }
});

Так реализуется отображение трека транспорта или перемещения пользователя.


Получение границ LineString

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

const bounds = new mapboxgl.LngLatBounds();

coordinates.forEach(coord => {
    bounds.extend(coord);
});

map.fitBounds(bounds, {
    padding: 40
});

Результат:

  • карта центрируется;
  • выбирается оптимальный масштаб;
  • вся линия становится видимой.

Обработка событий на линиях

Слой линии поддерживает обработчики событий.

Щелчок по маршруту:

map.on('click', 'route-line', (e) => {
    console.log('Маршрут выбран');
});

Наведение курсора:

map.on('mouseenter', 'route-line', () => {
    map.getCanvas().style.cursor = 'pointer';
});

Уход курсора:

map.on('mouseleave', 'route-line', () => {
    map.getCanvas().style.cursor = '';
});

Фильтрация линий

Если источник содержит множество маршрутов, можно отображать только нужные объекты.

Пример:

map.setFilter('routes-layer', [
    '==',
    ['get', 'status'],
    'active'
]);

Будут показаны только линии со свойством:

{
    status: "active"
}

Использование zoom-зависимого оформления

Стиль линии может изменяться при масштабировании карты.

paint: {
    'line-width': [
        'interpolate',
        ['linear'],
        ['zoom'],
        5, 2,
        10, 6,
        15, 12
    ]
}

Поведение:

Масштаб Толщина
5 2 px
10 6 px
15 12 px

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


LineString и MultiLineString

LineString представляет одну непрерывную линию.

{
    type: "LineString",
    coordinates: [...]
}

MultiLineString представляет набор независимых линий.

{
    type: "MultiLineString",
    coordinates: [
        [
            [37.61, 55.75],
            [37.62, 55.76]
        ],
        [
            [37.70, 55.80],
            [37.75, 55.82]
        ]
    ]
}

Основное различие заключается в структуре массива координат.


Практический пример маршрута

map.addSource('route', {
    type: 'geojson',
    data: {
        type: 'Feature',
        properties: {
            name: 'Основной маршрут'
        },
        geometry: {
            type: 'LineString',
            coordinates: [
                [37.6176, 55.7558],
                [37.6300, 55.7600],
                [37.6500, 55.7700],
                [37.6800, 55.7800]
            ]
        }
    }
});

map.addLayer({
    id: 'route-layer',
    type: 'line',
    source: 'route',
    layout: {
        'line-cap': 'round',
        'line-join': 'round'
    },
    paint: {
        'line-color': '#0066ff',
        'line-width': 6,
        'line-opacity': 0.8
    }
});

В данном примере реализованы основные возможности работы с геометрией LineString:

  • создание GeoJSON-объекта;
  • передача данных в источник;
  • отображение маршрута через слой line;
  • настройка цвета;
  • управление толщиной;
  • скругление углов;
  • настройка прозрачности;
  • подготовка объекта к дальнейшей интерактивной обработке и динамическому обновлению.