Информация о дорожных инцидентах является одним из важнейших компонентов современных геоинформационных систем. Пробки, аварии, дорожные работы, перекрытия улиц, погодные ограничения и другие события оказывают непосредственное влияние на маршрутизацию и анализ транспортной обстановки.
В экосистеме HERE данные о дорожных событиях предоставляются через специализированные сервисы Traffic API, которые позволяют получать актуальную информацию о дорожной ситуации, отображать инциденты на карте и учитывать их при построении маршрутов.
Система дорожных событий решает несколько задач одновременно:
Типичный сценарий работы выглядит следующим образом:
HERE классифицирует дорожные события по нескольким категориям.
Наиболее распространённый тип инцидентов.
Примеры:
Подобные события обычно содержат:
События данной категории описывают:
В ответе сервиса могут присутствовать данные:
Временное или постоянное ограничение движения.
Причинами могут быть:
Часто такие события оказывают максимальное влияние на маршрутизацию.
Информация формируется на основе:
Система позволяет определить:
Некоторые регионы поддерживают отображение погодных ограничений.
Примеры:
Отдельную группу составляют:
Подобные события могут приводить к временному изменению схем движения.
Для доступа к дорожным инцидентам используется REST API HERE.
Пример запроса:
const bbox = "52.4,13.2,52.6,13.5";
const url =
`https://data.traffic.hereapi.com/v7/incidents?` +
`in=bbox:${bbox}&apiKey=${apiKey}`;
fetch(url)
.then(response => response.json())
.then(data => {
console.log(data);
});
В параметре bbox указывается прямоугольная область
поиска.
Формат:
south,west,north,east
Например:
52.4,13.2,52.6,13.5
Типичный ответ содержит массив инцидентов.
Упрощённый пример:
{
"results": [
{
"id": "12345",
"type": "ACCIDENT",
"criticality": "major",
"description": {
"value": "Accident on highway"
}
}
]
}
Ключевые поля:
| Поле | Описание |
|---|---|
| id | идентификатор события |
| type | тип события |
| criticality | уровень серьёзности |
| description | текстовое описание |
| location | географические координаты |
| startTime | время начала |
| endTime | предполагаемое завершение |
Часто требуется получать данные только для видимой части карты.
Получение границ:
const bounds = map.getViewModel()
.getLookAtData()
.bounds;
Формирование запроса:
const bbox =
`${bounds.getBottom()},` +
`${bounds.getLeft()},` +
`${bounds.getTop()},` +
`${bounds.getRight()}`;
Запрос:
async function loadIncidents() {
const response = await fetch(
`https://data.traffic.hereapi.com/v7/incidents` +
`?in=bbox:${bbox}` +
`&apiKey=${apiKey}`
);
return await response.json();
}
Такой подход существенно уменьшает объём передаваемых данных.
После получения данных события можно преобразовать в маркеры.
function createIncidentMarker(lat, lng) {
return new H.map.Marker({
lat,
lng
});
}
Добавление объектов:
incidents.results.forEach(item => {
const position = item.location.shape.links[0].points[0];
const marker = createIncidentMarker(
position.lat,
position.lng
);
map.addObject(marker);
});
Стандартные маркеры редко подходят для транспортных приложений.
Создание собственной иконки:
const icon = new H.map.Icon(`
<svg width="32" height="32">
<circle
cx="16"
cy="16"
r="12"
fill="red"
/>
</svg>
`);
Использование:
const marker = new H.map.Marker(
position,
{ icon }
);
Часто каждому типу назначается собственная визуализация.
function getIcon(type) {
switch(type) {
case "ACCIDENT":
return accidentIcon;
case "ROAD_CLOSED":
return closedRoadIcon;
case "CONSTRUCTION":
return constructionIcon;
default:
return defaultIcon;
}
}
Создание маркера:
const marker = new H.map.Marker(
coords,
{
icon: getIcon(item.type)
}
);
При выборе события полезно отображать дополнительные сведения.
Создание окна:
const bubble = new H.ui.InfoBubble(
marker.getGeometry(),
{
content: description
}
);
ui.addBubble(bubble);
Назначение обработчика:
marker.addEventListener("tap", () => {
const bubble =
new H.ui.InfoBubble(
marker.getGeometry(),
{
content: item.description.value
}
);
ui.addBubble(bubble);
});
В крупных городах количество инцидентов может исчисляться сотнями.
Фильтрация по типу:
const accidents =
incidents.results.filter(
item => item.type === "ACCIDENT"
);
Фильтрация по серьёзности:
const majorEvents =
incidents.results.filter(
item => item.criticality === "major"
);
Практический подход:
const visibleIncidents =
incidents.results.filter(item => {
return (
item.criticality === "major" ||
item.criticality === "critical"
);
});
Это уменьшает визуальный шум на карте.
При большом количестве маркеров рекомендуется использовать кластеризацию.
Подготовка данных:
const dataPoints =
incidents.results.map(item =>
new H.clustering.DataPoint(
item.lat,
item.lng
)
);
Создание провайдера:
const provider =
new H.clustering.Provider(
dataPoints
);
Слой:
const layer =
new H.map.layer.ObjectLayer(
provider
);
map.addLayer(layer);
Кластеризация улучшает производительность и повышает читаемость карты.
Дорожная ситуация постоянно изменяется.
Обновление каждые 60 секунд:
setInterval(async () => {
const incidents =
await loadIncidents();
updateMap(incidents);
}, 60000);
Перед повторной отрисовкой старые объекты обычно удаляются.
group.removeAll();
После этого добавляются новые маркеры.
Удобно хранить инциденты внутри одной коллекции.
Создание группы:
const incidentGroup =
new H.map.Group();
map.addObject(
incidentGroup
);
Добавление маркеров:
incidentGroup.addObject(
marker
);
Очистка:
incidentGroup.removeAll();
Информация об инцидентах тесно связана с сервисом маршрутизации.
При расчёте маршрута HERE может учитывать:
Пример параметра:
router.calculateRoute({
transportMode: "car",
origin: start,
destination: finish,
return: "summary,polyline",
routingMode: "fast"
});
Если дорога перекрыта, алгоритм автоматически подберёт объездной путь.
Маршрутизатор может возвращать данные о времени движения.
Пример:
route.sections[0].summary.duration
Дополнительно может присутствовать:
route.sections[0].summary.baseDuration
Разница между ними показывает влияние текущей дорожной ситуации.
const delay =
duration - baseDuration;
Многие события содержат геометрию.
Например:
item.location.shape
Из неё формируется линия:
const lineString =
new H.geo.LineString();
Добавление точек:
points.forEach(point => {
lineString.pushPoint({
lat: point.lat,
lng: point.lng
});
});
Создание полилинии:
const polyline =
new H.map.Polyline(
lineString
);
Добавление на карту:
map.addObject(polyline);
Такой подход позволяет показывать не только место происшествия, но и весь проблемный участок дороги.
Распространённая схема визуализации:
| Уровень | Цвет |
|---|---|
| minor | зелёный |
| low | жёлтый |
| major | оранжевый |
| critical | красный |
Функция выбора цвета:
function getSeverityColor(level) {
const colors = {
minor: "#00aa00",
low: "#f7d000",
major: "#ff7b00",
critical: "#ff0000"
};
return colors[level];
}
Использование цветовой кодировки позволяет быстро оценивать ситуацию на карте.
Каждый инцидент проходит несколько стадий:
При периодическом обновлении необходимо:
Для этого обычно создаётся словарь:
const incidentsMap =
new Map();
Ключом выступает идентификатор события:
incidentsMap.set(
incident.id,
marker
);
Подобный механизм обеспечивает эффективную синхронизацию карты с актуальными данными Traffic API и позволяет создавать масштабируемые транспортные приложения, системы мониторинга дорожной обстановки, логистические платформы и навигационные решения реального времени на базе HERE Maps JavaScript API.