- ADR-001: блокировка шлагбаумов через mode.inaccessible (обоснование выбора vs penalty vs учёт access) - 07-infra-requirements: пересборка графа ~45 мин, downtime /api/route ~10 сек, RAM peak 4.5 GB, threads=1, rollback - infra/osrm/enduro.lua — as-is копия профиля с mva154 (до изменений ET-001) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
158 lines
5.4 KiB
Lua
158 lines
5.4 KiB
Lua
-- enduro.lua — OSRM профиль для эндуро-роутинга "Дикий путь"
|
||
-- Логика: weight = distance / forward_rate
|
||
-- Чтобы грунтовки были ДЕШЕВЛЕ асфальта → у грунтовок forward_rate БОЛЬШЕ
|
||
-- (высокий rate → маленький weight на тот же distance)
|
||
-- У асфальта forward_rate МЕНЬШЕ → большой weight → OSRM избегает
|
||
-- Обновлён: 2026-05-06 (F-07, F-08, новые rate для асфальта)
|
||
|
||
api_version = 4
|
||
|
||
-- forward_rate: чем ВЫШЕ — тем ПРЕДПОЧТИТЕЛЬНЕЕ маршрут
|
||
-- грунтовки = высокий rate (предпочтительны)
|
||
-- асфальт = низкий rate (избегаем, но штраф 3-5x вместо 17-200x)
|
||
local highway_rate = {
|
||
track = 100.0, -- самый предпочтительный
|
||
bridleway = 90.0,
|
||
path = 85.0,
|
||
cycleway = 70.0,
|
||
footway = 55.0, -- за городом полезны
|
||
unclassified = 45.0,
|
||
residential = 35.0,
|
||
service = 28.0,
|
||
tertiary = 28.0, -- было 6.0 → теперь ~3.5x хуже track
|
||
tertiary_link= 28.0,
|
||
secondary = 22.0, -- было 3.0 → теперь ~4.5x хуже track
|
||
secondary_link = 22.0,
|
||
primary = 18.0, -- было 1.5 → теперь ~5.5x хуже track
|
||
primary_link = 18.0,
|
||
trunk = 12.0, -- было 0.5
|
||
trunk_link = 12.0,
|
||
motorway = 5.0, -- было 0.1
|
||
motorway_link= 5.0,
|
||
}
|
||
|
||
-- Скорости (км/ч) — только для ETA (duration), не влияют на выбор маршрута
|
||
local highway_speeds = {
|
||
track = 30,
|
||
bridleway = 20,
|
||
path = 20,
|
||
cycleway = 25,
|
||
footway = 15,
|
||
unclassified = 40,
|
||
residential = 40,
|
||
service = 30,
|
||
tertiary = 60,
|
||
tertiary_link= 60,
|
||
secondary = 70,
|
||
secondary_link = 70,
|
||
primary = 80,
|
||
primary_link = 80,
|
||
trunk = 90,
|
||
trunk_link = 90,
|
||
motorway = 110,
|
||
motorway_link= 90,
|
||
}
|
||
|
||
-- Мультипликатор по качеству грунтовки (grade1 лучше grade5)
|
||
local tracktype_multiplier = {
|
||
grade1 = 1.2,
|
||
grade2 = 1.1,
|
||
grade3 = 1.0,
|
||
grade4 = 0.9,
|
||
grade5 = 0.8,
|
||
}
|
||
|
||
function setup()
|
||
return {
|
||
properties = {
|
||
weight_name = 'routability',
|
||
max_speed_for_map_matching = 30/3.6,
|
||
call_tagless_node_function = false,
|
||
traffic_light_penalty = 2,
|
||
u_turn_penalty = 20,
|
||
continue_straight_at_waypoint = false,
|
||
use_turn_restrictions = false,
|
||
}
|
||
}
|
||
end
|
||
|
||
-- F-07: шлагбаумы блокируем только если явно закрыты для публики
|
||
function process_node(profile, node, result)
|
||
local barrier = node:get_value_by_key("barrier")
|
||
if barrier == "gate" or barrier == "bollard" or barrier == "lift_gate" then
|
||
local access = node:get_value_by_key("access")
|
||
-- Блокировать только явно закрытые для публики
|
||
if access == "private" or access == "no" or access == "customers" or access == "permissive" then
|
||
result.barrier = true
|
||
end
|
||
-- Без тега access или access=yes — пропускаем (публичный)
|
||
end
|
||
end
|
||
|
||
function process_way(profile, way, result)
|
||
local highway = way:get_value_by_key("highway")
|
||
if not highway then return end
|
||
|
||
local rate = highway_rate[highway]
|
||
if not rate then return end
|
||
|
||
-- steps — всегда исключить
|
||
if highway == "steps" then return end
|
||
|
||
-- F-08: пешеходные/велодорожки в городской застройке — исключить
|
||
if highway == "footway" or highway == "path" or highway == "cycleway" then
|
||
local landuse = way:get_value_by_key("landuse")
|
||
local place = way:get_value_by_key("place")
|
||
-- Признаки городской застройки
|
||
if landuse == "residential" or landuse == "commercial" or landuse == "industrial" or
|
||
place == "city" or place == "town" or place == "village" then
|
||
return -- исключить из графа
|
||
end
|
||
end
|
||
|
||
local speed = highway_speeds[highway] or 30
|
||
|
||
-- Мультипликатор по tracktype для грунтовок
|
||
local tracktype = way:get_value_by_key("tracktype")
|
||
if tracktype and tracktype_multiplier[tracktype] then
|
||
rate = rate * tracktype_multiplier[tracktype]
|
||
end
|
||
|
||
result.forward_mode = mode.driving
|
||
result.backward_mode = mode.driving
|
||
|
||
-- duration = реальное время (скорость в км/ч)
|
||
result.forward_speed = speed
|
||
result.backward_speed = speed
|
||
|
||
-- weight = distance / rate
|
||
-- высокий rate → маленький weight → предпочтительный маршрут
|
||
result.forward_rate = rate
|
||
result.backward_rate = rate
|
||
|
||
-- Одностороннее движение
|
||
local oneway = way:get_value_by_key("oneway")
|
||
if oneway == "yes" or oneway == "1" or oneway == "true" then
|
||
result.backward_mode = mode.inaccessible
|
||
elseif oneway == "-1" then
|
||
result.forward_mode = mode.inaccessible
|
||
end
|
||
end
|
||
|
||
function process_turn(profile, turn)
|
||
turn.duration = 0
|
||
turn.weight = 0
|
||
|
||
if turn.is_u_turn then
|
||
turn.duration = profile.properties.u_turn_penalty
|
||
turn.weight = profile.properties.u_turn_penalty
|
||
end
|
||
end
|
||
|
||
return {
|
||
setup = setup,
|
||
process_way = process_way,
|
||
process_node = process_node,
|
||
process_turn = process_turn,
|
||
}
|