-- enduro.lua — OSRM профиль для эндуро-роутинга "Дикий путь" -- -- Ключевая логика: -- weight = distance / forward_rate -- Высокий rate → маленький weight → предпочтительный маршрут -- -- Чтобы duration НЕ влиял на выбор маршрута: -- forward_speed одинаковый для всех типов дорог (30 км/ч) -- Тогда OSRM выбирает только по rate (грунтовки vs асфальт) -- ETA будет неточным, но маршрут пойдёт по грунтовкам -- -- rate: track=100 (предпочтительно) ... motorway=0.1 (избегаем) api_version = 4 -- forward_rate: чем ВЫШЕ — тем ПРЕДПОЧТИТЕЛЬНЕЕ -- weight = distance / rate → высокий rate = низкий weight = предпочтительный путь local highway_rate = { track = 100.0, bridleway = 90.0, path = 85.0, cycleway = 70.0, footway = 60.0, unclassified = 20.0, residential = 15.0, service = 12.0, tertiary = 4.0, tertiary_link= 4.0, secondary = 2.0, secondary_link = 2.0, primary = 1.0, primary_link = 1.0, trunk = 0.3, trunk_link = 0.3, motorway = 0.1, motorway_link= 0.1, } -- Мультипликатор по качеству грунтовки local tracktype_multiplier = { grade1 = 1.3, grade2 = 1.2, 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 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 rate = highway_rate[highway] if not rate then return end -- Мультипликатор по 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 не влияет на выбор маршрута -- Выбор идёт ТОЛЬКО по rate (грунтовки vs асфальт) result.forward_speed = 30 result.backward_speed = 30 -- weight = distance / rate 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, }