Стилизация определяет внешний вид пространственных объектов на карте. От правильно настроенных стилей зависит читаемость данных, визуальная иерархия, удобство анализа информации и производительность отображения.
В OpenLayers стили применяются к объектам векторных слоёв и позволяют управлять:
Основные классы стилизации располагаются в модуле
ol/style.
Система оформления OpenLayers построена вокруг объекта
Style.
Типичная структура выглядит следующим образом:
import Style from 'ol/style/Style.js';
import Fill from 'ol/style/Fill.js';
import Stroke from 'ol/style/Stroke.js';
const style = new Style({
fill: new Fill({
color: 'rgba(0, 0, 255, 0.3)'
}),
stroke: new Stroke({
color: '#0000ff',
width: 2
})
});
Стиль объединяет несколько компонентов:
| Компонент | Назначение |
|---|---|
| Fill | Заливка полигонов |
| Stroke | Контур линий и полигонов |
| Circle | Отображение точек окружностями |
| Icon | Использование изображений |
| Text | Подписи объектов |
| RegularShape | Геометрические фигуры |
| Style | Контейнер всех элементов оформления |
Наиболее распространённый способ оформления — назначение одного стиля всему векторному слою.
import VectorLayer from 'ol/layer/Vector.js';
const vectorLayer = new VectorLayer({
source: vectorSource,
style: style
});
Все объекты слоя будут отображаться одинаково.
Такой подход подходит для:
Для отображения площадных объектов используется класс
Fill.
import Fill from 'ol/style/Fill.js';
const fill = new Fill({
color: 'rgba(255, 0, 0, 0.4)'
});
Пример полигона:
const polygonStyle = new Style({
fill: new Fill({
color: 'rgba(255, 100, 100, 0.5)'
})
});
Поддерживаются различные форматы цветов:
color: '#ff0000'
color: 'rgb(255,0,0)'
color: 'rgba(255,0,0,0.5)'
color: 'red'
На практике чаще используются RGBA-значения, поскольку они позволяют задавать прозрачность.
Контур объекта создаётся классом Stroke.
import Stroke from 'ol/style/Stroke.js';
const stroke = new Stroke({
color: '#000000',
width: 3
});
Пример:
const style = new Style({
stroke: new Stroke({
color: '#2c3e50',
width: 4
})
});
Для создания пунктирных линий применяется свойство
lineDash.
const style = new Style({
stroke: new Stroke({
color: '#e74c3c',
width: 3,
lineDash: [10, 5]
})
});
Параметры массива:
lineDash: [длина_штриха, длина_пробела]
Примеры:
lineDash: [5, 5]
lineDash: [15, 10]
lineDash: [20, 5, 5, 5]
Подобное оформление часто используется для:
Для точечных объектов обычно используется класс
Circle.
import CircleStyle from 'ol/style/Circle.js';
Пример:
const pointStyle = new Style({
image: new CircleStyle({
radius: 8,
fill: new Fill({
color: '#3498db'
}),
stroke: new Stroke({
color: '#ffffff',
width: 2
})
})
});
Результат:
Размер определяется параметром radius.
radius: 4
radius: 10
radius: 20
Увеличение радиуса повышает заметность объекта, однако чрезмерно крупные символы могут перекрывать соседние элементы карты.
Вместо окружностей можно применять изображения.
import Icon from 'ol/style/Icon.js';
Пример:
const style = new Style({
image: new Icon({
src: 'images/marker.png'
})
});
Размер изображения можно изменять независимо от исходного файла.
image: new Icon({
src: 'images/marker.png',
scale: 0.5
})
Увеличение:
scale: 2
Уменьшение:
scale: 0.3
Это особенно удобно при использовании одного набора иконок для различных уровней масштабирования.
Положение значка относительно координаты объекта настраивается через параметры привязки.
image: new Icon({
src: 'images/marker.png',
anchor: [0.5, 1]
})
Значение:
[0.5, 1]
означает:
Такой вариант часто используется для маркеров местоположения.
Иконки могут вращаться.
image: new Icon({
src: 'images/arrow.png',
rotation: Math.PI / 4
})
Угол задаётся в радианах.
Примеры:
Math.PI / 2
90°
Math.PI
180°
Math.PI * 2
360°
Поворот активно используется при визуализации:
Текст отображается через класс Text.
import Text from 'ol/style/Text.js';
Пример:
const style = new Style({
text: new Text({
text: 'Город'
})
});
Размер и параметры текста определяются свойством
font.
text: new Text({
text: 'Алматы',
font: '14px Arial'
})
Более сложный вариант:
font: 'bold 16px Verdana'
Возможности:
text: new Text({
text: 'Объект',
fill: new Fill({
color: '#000000'
})
})
Белая подпись:
fill: new Fill({
color: '#ffffff'
})
Для повышения читаемости часто добавляют обводку.
text: new Text({
text: 'Река',
fill: new Fill({
color: '#ffffff'
}),
stroke: new Stroke({
color: '#000000',
width: 3
})
})
Такой приём широко применяется в веб-картографии.
Текст можно перемещать относительно объекта.
text: new Text({
text: 'Город',
offsetY: -20
})
Подпись будет расположена над маркером.
Горизонтальное смещение:
offsetX: 15
Вертикальное:
offsetY: 10
Наиболее распространённый вариант — отображение значений полей объекта.
const styleFunction = function(feature) {
return new Style({
text: new Text({
text: feature.get('name')
})
});
};
Если объект содержит поле:
{
name: 'Караганда'
}
то на карте появится соответствующая подпись.
OpenLayers позволяет динамически формировать стиль для каждого объекта.
layer.setStyle(function(feature) {
return style;
});
Функция вызывается для каждого отображаемого объекта.
Это один из важнейших механизмов оформления.
Предположим, объекты содержат поле населения:
{
population: 500000
}
Можно изменять цвет в зависимости от значения.
const styleFunction = function(feature) {
const population = feature.get('population');
let color;
if (population > 1000000) {
color = 'red';
} else {
color = 'orange';
}
return new Style({
fill: new Fill({
color: color
})
});
};
Такой подход лежит в основе тематических карт.
Часто используется классификация по типам объектов.
const type = feature.get('type');
Далее:
switch(type) {
case 'city':
color = 'red';
break;
case 'village':
color = 'green';
break;
case 'capital':
color = 'blue';
break;
}
Каждая категория получает собственное оформление.
Функция стиля получает текущее разрешение карты.
function(feature, resolution) {
}
Можно скрывать подписи при сильном уменьшении масштаба.
function(feature, resolution) {
if (resolution > 100) {
return simpleStyle;
}
return detailedStyle;
}
Подобный механизм предотвращает перегрузку карты.
Создание новых стилей для каждого объекта может отрицательно влиять на производительность.
Неэффективный вариант:
function(feature) {
return new Style({
...
});
}
Более эффективный подход:
const cityStyle = new Style({
...
});
function(feature) {
return cityStyle;
}
Стиль создаётся один раз и используется многократно.
При большом количестве объектов полезно хранить стили в кэше.
const styleCache = {};
Пример:
function(feature) {
const category = feature.get('category');
if (!styleCache[category]) {
styleCache[category] = new Style({
image: new CircleStyle({
radius: 6
})
});
}
return styleCache[category];
}
Подход существенно снижает нагрузку на браузер.
OpenLayers позволяет возвращать массив стилей.
return [
style1,
style2
];
Пример:
return [
polygonStyle,
labelStyle
];
Или:
return [
shadowStyle,
markerStyle
];
Стили будут отрисованы последовательно.
Часто используется двойная линия.
const outerStyle = new Style({
stroke: new Stroke({
color: 'white',
width: 8
})
});
const innerStyle = new Style({
stroke: new Stroke({
color: 'blue',
width: 4
})
});
Возврат:
return [
outerStyle,
innerStyle
];
В результате получается контур с эффектом свечения или выделения.
Для создания геометрических символов применяется
RegularShape.
import RegularShape from 'ol/style/RegularShape.js';
Треугольник:
image: new RegularShape({
points: 3,
radius: 10,
fill: new Fill({
color: 'red'
})
})
Квадрат:
points: 4
Пятиугольник:
points: 5
Регулярные фигуры позволяют создавать звёзды.
image: new RegularShape({
points: 5,
radius: 12,
radius2: 5,
fill: new Fill({
color: 'gold'
})
})
Такое оформление часто используется для специальных объектов или тематических обозначений.
Практически любой элемент поддерживает альфа-канал.
Пример полигона:
fill: new Fill({
color: 'rgba(52,152,219,0.25)'
})
Пример линии:
stroke: new Stroke({
color: 'rgba(231,76,60,0.6)'
})
Прозрачность позволяет отображать несколько перекрывающихся слоёв без потери информации.
Для разных типов объектов обычно создаются отдельные наборы стилей.
CircleStyle
Stroke
Fill + Stroke
Универсальная функция:
function(feature) {
const type = feature.getGeometry().getType();
switch(type) {
case 'Point':
return pointStyle;
case 'LineString':
return lineStyle;
case 'Polygon':
return polygonStyle;
}
}
Подобный подход особенно полезен при работе со смешанными наборами геометрий.
Использование кэширования стилей
Ограничение количества подписей
Применение прозрачности
Единая визуальная система
Использование масштабно-зависимого оформления
Разделение логики и оформления
Система стилизации OpenLayers предоставляет полный набор инструментов для построения профессионального картографического интерфейса: от простого изменения цвета объектов до сложной динамической символизации, основанной на атрибутах, масштабе отображения и пользовательской логике визуализации данных.