From ad168fef47a78b8f2624e475cef6fffb6a0ac190 Mon Sep 17 00:00:00 2001 From: Stream Date: Sun, 3 May 2026 22:40:10 +0300 Subject: [PATCH] auto-sync: 2026-05-03 22:40:01 --- tasks/enduro-trails/osrm/enduro.lua | 135 ++++++++++++++++++++++++++++ 1 file changed, 135 insertions(+) create mode 100644 tasks/enduro-trails/osrm/enduro.lua diff --git a/tasks/enduro-trails/osrm/enduro.lua b/tasks/enduro-trails/osrm/enduro.lua new file mode 100644 index 0000000..b54993a --- /dev/null +++ b/tasks/enduro-trails/osrm/enduro.lua @@ -0,0 +1,135 @@ +-- enduro.lua — OSRM профиль для эндуро-роутинга "Дикий путь" +-- Стратегия: weight = distance_meters * penalty +-- Грунтовки penalty=1, асфальт penalty=10+ +-- OSRM минимизирует суммарный weight → выбирает грунтовки + +api_version = 4 + +-- Штраф за метр пути (меньше = предпочтительнее) +-- Грунтовки ~1, асфальт ~10+ +local highway_penalty = { + track = 1.0, + bridleway = 1.2, + path = 1.3, + cycleway = 1.5, + footway = 2.0, + unclassified = 3.0, + residential = 5.0, + service = 6.0, + tertiary = 12.0, + tertiary_link= 12.0, + secondary = 18.0, + secondary_link = 18.0, + primary = 25.0, + primary_link = 25.0, + trunk = 40.0, + trunk_link = 40.0, + motorway = 999.0, + motorway_link= 999.0, +} + +-- Скорости (км/ч) — только для ETA, не влияют на выбор маршрута +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 = 60, + secondary_link = 60, + primary = 60, + primary_link = 60, + trunk = 60, + trunk_link = 60, + motorway = 90, + motorway_link= 90, +} + +-- Мультипликатор по качеству грунтовки (grade1=лучший, grade5=тяжёлый) +local tracktype_multiplier = { + grade1 = 1.0, + grade2 = 1.1, + grade3 = 1.2, + grade4 = 1.4, + grade5 = 1.6, +} + +function setup() + return { + properties = { + weight_name = 'duration', + 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 + +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 + result.barrier = true + end +end + +function process_way(profile, way, result) + local highway = way:get_value_by_key("highway") + if not highway then return end + + local penalty = highway_penalty[highway] + if not penalty then return end + + local speed = highway_speeds[highway] or 30 + + -- Мультипликатор по tracktype для грунтовок + local tracktype = way:get_value_by_key("tracktype") + if tracktype and tracktype_multiplier[tracktype] then + penalty = penalty * tracktype_multiplier[tracktype] + end + + result.forward_mode = mode.driving + result.backward_mode = mode.driving + result.forward_speed = speed + result.backward_speed = speed + + -- duration = реальное время (секунды) — используется для ETA + -- weight = штраф для роутера — грунтовки дешевле асфальта + -- Задаём rate: weight_per_meter = penalty / speed_mps + -- OSRM считает weight = rate * distance + local speed_mps = speed / 3.6 + result.forward_rate = penalty / speed_mps + result.backward_rate = penalty / speed_mps + + -- Одностороннее движение + 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, +}