LineString — один из базовых типов геометрии стандарта GeoJSON, предназначенный для представления линейных объектов. В картографических приложениях такие объекты используются для отображения дорог, маршрутов, железнодорожных путей, рек, трубопроводов, линий электропередачи, границ и любых других объектов, состоящих из последовательности связанных точек.
В Mapbox GL JS геометрия LineString чаще всего отображается при
помощи слоя типа line, который визуализирует набор
координат в виде непрерывной линии на карте.
LineString содержит массив координат, где каждая координата представляет собой пару значений:
[долгота, широта]
Простейший пример:
{
"type": "LineString",
"coordinates": [
[37.6176, 55.7558],
[37.6500, 55.7600],
[37.7000, 55.7800]
]
}
Каждая следующая точка соединяется с предыдущей прямым сегментом.
Визуально такая геометрия выглядит следующим образом:
Точка A -------- Точка B -------- Точка C
Mapbox GL JS автоматически строит между ними линии.
Линейная геометрия обычно передаётся в карту через источник данных
(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;После создания источника необходимо добавить слой.
map.addLayer({
id: 'route-line',
type: 'line',
source: 'route',
paint: {
'line-color': '#ff0000',
'line-width': 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.
{
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;Специальное выражение:
['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
}
});
Так реализуется отображение трека транспорта или перемещения пользователя.
Для автоматического масштабирования карты часто требуется определить область, занимаемую маршрутом.
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"
}
Стиль линии может изменяться при масштабировании карты.
paint: {
'line-width': [
'interpolate',
['linear'],
['zoom'],
5, 2,
10, 6,
15, 12
]
}
Поведение:
| Масштаб | Толщина |
|---|---|
| 5 | 2 px |
| 10 | 6 px |
| 15 | 12 px |
Это улучшает читаемость карты на разных уровнях приближения.
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:
line;