From 149c2fb68dcf99f7eb8b984653f2292b6a652aec Mon Sep 17 00:00:00 2001 From: Stream Date: Wed, 6 May 2026 20:40:01 +0300 Subject: [PATCH] auto-sync: 2026-05-06 20:40:01 --- tasks/enduro-trails/prototype/app.py | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/tasks/enduro-trails/prototype/app.py b/tasks/enduro-trails/prototype/app.py index 234bf1b..41432c3 100644 --- a/tasks/enduro-trails/prototype/app.py +++ b/tasks/enduro-trails/prototype/app.py @@ -954,8 +954,8 @@ async def _build_segmented_route(req: RouteRequest) -> dict: segment_alternatives.append(data["routes"]) - # Для каждого сегмента берём до 3 вариантов чтобы не взорвать комбинаторику - max_per_segment = 3 + # Для каждого сегмента берём до 5 вариантов чтобы не взорвать комбинаторику + max_per_segment = 5 trimmed = [alts[:max_per_segment] for alts in segment_alternatives] all_combos = list(itertools.product(*trimmed)) @@ -981,15 +981,24 @@ async def _build_segmented_route(req: RouteRequest) -> dict: "legs": [leg for r in combo for leg in r.get("legs", [])], }) - # Дедупликация: если дистанции отличаются менее чем на 2% — считать дублем + # Дедупликация по геометрии (не по дистанции) + def _route_signature(coords: list) -> tuple: + """Сигнатура маршрута: несколько контрольных точек по геометрии.""" + n = len(coords) + if n == 0: + return () + indices = [0, n//4, n//2, 3*n//4, n-1] + return tuple( + (round(coords[i][0], 3), round(coords[i][1], 3)) + for i in indices if i < n + ) + + seen_sigs = set() deduped: list = [] for route in combined_routes: - is_dup = False - for existing in deduped: - if abs(route["distance"] - existing["distance"]) / max(existing["distance"], 1) < 0.02: - is_dup = True - break - if not is_dup: + sig = _route_signature(route["geometry"]["coordinates"]) + if sig not in seen_sigs: + seen_sigs.add(sig) deduped.append(route) # Топ-5