Стилизация линейных объектов в OpenLayers опирается на комбинацию
классов Style, Stroke и геометрий типа
LineString и MultiLineString. Векторный слой
(VectorLayer) отображает линии через canvas или WebGL (в
зависимости от конфигурации), применяя стиль к каждой геометрии на этапе
рендеринга.
Ключевой элемент управления внешним видом линии — объект
ol/style/Stroke, который определяет цвет, толщину, тип
штриха и поведение соединений сегментов.
import Style from 'ol/style/Style.js';
import Stroke from 'ol/style/Stroke.js';
const lineStyle = new Style({
stroke: new Stroke({
color: '#2a6fdb',
width: 3
})
});
Такой стиль задаёт базовую визуализацию: сплошную синюю линию фиксированной толщины.
Объект Stroke управляет низкоуровневым поведением
отрисовки.
Цвет задаётся строкой в формате HEX, RGB или RGBA:
new Stroke({
color: 'rgba(255, 0, 0, 0.8)',
width: 2
});
Использование альфа-канала позволяет управлять прозрачностью линий, что особенно важно при наложении множества слоёв.
Параметр width определяет толщину в пикселях:
new Stroke({
color: '#000',
width: 10
});
Толщина влияет не только на визуальное восприятие, но и на интерактивность: hit-detection (попадание курсора) также учитывает ширину.
OpenLayers поддерживает управление геометрией стыков сегментов:
lineCap — оформление концов линииlineJoin — оформление соединений сегментовnew Stroke({
color: '#333',
width: 6,
lineCap: 'round',
lineJoin: 'round'
});
Возможные значения:
butt — обрезанный конецround — скруглениеsquare — квадратное продолжениеДля соединений:
bevel — срезанный уголround — скруглениеmiter — острый уголmiter особенно важен при острых поворотах линии, где
может возникать эффект «шипов», контролируемый параметром
miterLimit.
new Stroke({
color: '#000',
width: 5,
lineJoin: 'miter',
miterLimit: 10
});
miterLimit задаёт максимальную длину выступа при острых
углах. При превышении значения происходит переход к
bevel.
Один из наиболее часто используемых эффектов — пунктирные линии,
реализуемые через lineDash.
new Stroke({
color: '#0066ff',
width: 3,
lineDash: [10, 5]
});
Массив определяет чередование:
Более сложные паттерны:
lineDash: [1, 3, 5, 3]
Это создаёт повторяющийся ритмический рисунок, полезный для отображения границ, маршрутов или вспомогательных слоёв.
Стили в OpenLayers могут задаваться функцией, что позволяет изменять внешний вид в зависимости от масштаба, атрибутов или состояния объекта.
const styleFunction = (feature, resolution) => {
const speed = feature.get('speed');
return new Style({
stroke: new Stroke({
color: speed > 60 ? 'red' : 'green',
width: 2 + speed / 20
})
});
};
Такой подход используется для:
Параметр resolution позволяет менять стиль в зависимости
от масштаба карты.
const styleFunction = (feature, resolution) => {
const width = resolution > 10 ? 1 : 4;
return new Style({
stroke: new Stroke({
color: '#1f78b4',
width: width
})
});
};
При увеличении масштаба линии могут становиться толще или тоньше, а также менять цвет или структуру.
Хотя OpenLayers не предоставляет прямого API для CSS-градиентов в линиях, эффект градиента можно имитировать через canvas-стили или сегментацию линии.
Базовый подход — использование RGBA с изменением прозрачности:
new Stroke({
color: 'rgba(255, 165, 0, 0.4)',
width: 6
});
Более сложные визуальные эффекты достигаются через кастомный
рендеринг renderFeature или WebGL-слой.
Линии обычно представляются через LineString:
import Feature from 'ol/Feature.js';
import LineString from 'ol/geom/LineString.js';
const line = new Feature({
geometry: new LineString([
[0, 0],
[1000000, 1000000]
])
});
Стиль применяется к объекту целиком:
line.setStyle(lineStyle);
Или через слой:
import VectorLayer from 'ol/layer/Vector.js';
const layer = new VectorLayer({
source: vectorSource,
style: lineStyle
});
Для сложных объектов используется MultiLineString,
содержащий несколько независимых линий.
new LineString([...])
new MultiLineString([
[[0, 0], [10, 10]],
[[20, 20], [30, 30]]
]);
Один стиль применяется ко всем подлиниям, но при необходимости можно использовать функцию стиля для дифференциации.
OpenLayers позволяет привязывать визуальные свойства к данным feature.
const styleFunction = (feature) => {
const type = feature.get('type');
const colors = {
highway: '#ff0000',
road: '#000000',
path: '#00aa00'
};
return new Style({
stroke: new Stroke({
color: colors[type] || '#666',
width: 3
})
});
};
Такой подход широко применяется в картографических системах для отображения дорожных сетей.
При работе с множеством слоёв важно учитывать порядок отрисовки и прозрачность:
new Stroke({
color: 'rgba(0, 0, 255, 0.2)',
width: 8
});
Комбинация широкой полупрозрачной линии с узкой непрозрачной создаёт эффект «обводки»:
new Style({
stroke: new Stroke({
color: '#0033cc',
width: 6
})
});
В OpenLayers масштаб выражается через resolution. Чем
выше значение resolution, тем дальше масштаб.
const styleFunction = (feature, resolution) => {
const baseWidth = 2;
const width = baseWidth * Math.max(1, 50 / resolution);
return new Style({
stroke: new Stroke({
color: '#1a1a1a',
width
})
});
};
Такая динамика используется для сохранения визуальной читаемости линий при разных уровнях увеличения.
Часто применяется наложение нескольких стилей через массив:
feature.setStyle([
new Style({
stroke: new Stroke({
color: '#000',
width: 8
})
}),
new Style({
stroke: new Stroke({
color: '#00aaff',
width: 4
})
})
]);
Это создаёт эффект обводки (outline), повышающий читаемость линий на сложных подложках.
При работе с тысячами объектов критично минимизировать пересоздание стилей. Рекомендуется:
Styleconst cache = {};
function getStyle(type) {
if (!cache[type]) {
cache[type] = new Style({
stroke: new Stroke({
color: type === 'main' ? '#ff0000' : '#999',
width: 3
})
});
}
return cache[type];
}
zIndex влияет на порядок отрисовки:
new Style({
stroke: new Stroke({
color: '#000',
width: 4
}),
zIndex: 10
});
Линии с большим zIndex отображаются поверх других, что
важно при визуализации транспортных сетей и маршрутов.
В Canvas-рендерере OpenLayers линии рисуются с учётом антиалиасинга браузера. Это влияет на:
Толщина менее 1 пикселя может интерпретироваться по-разному в зависимости от devicePixelRatio, что важно учитывать при адаптивной стилизации.