Разработать навигатор для игры? Смотрите! (часть 3.1)
Точка на карте - это еще не навигатор. Нужны дороги
Когда телефон научился показывать живую позицию машины, очень хотелось объявить победу. Но точка на карте - это еще не навигатор. Это режим “я знаю, где именно заблудился”.
Навигатор начинается там, где ты выбираешь цель, а программа строит дорогу. Не прямую линию через горы, реки и чувство собственного достоинства, а именно маршрут по дорогам.
Самый быстрый способ сделать фейковый маршрут - взять координаты машины, координаты цели и провести между ними линию. Для демо на 10 секунд красиво. Для реальной езды - стыд.
Машина не летает по любому пикселю карты. Значит, карту надо превратить в дорожный граф: узлы, ребра, длины, веса, классы дорог.
В проекте карта живет как большой мир: ```python MAP_ID = 481 DEFAULT_LAYER_ID = 760 MIN_ZOOM, MAX_ZOOM = 12, 18 TILE_SIZE = 256 MAP_WIDTH, MAP_HEIGHT = 20000, 20000 ``` POI тоже лежат отдельно. Если уже есть координаты машины, точки можно сортировать по расстоянию: ```python def search_markers(query: str, limit: int = 25): terms = [t for t in query.strip().lower().split() if t] snap = STATE.get_snapshot() px, py = snap.get("map_x"), snap.get("map_y") results = [] for marker in load_markers_data(): hay = " ".join(str(marker.get(k, "")) for k in ( "title", "category", "parent_category", "description" )).lower() if not all(term in hay for term in terms): continue item = dict(marker) if px is not None and py is not None: item["distance_px"] = round(math.hypot( float(marker.get("map_x", 0)) - float(px), float(marker.get("map_y", 0)) - float(py), ), 2) results.append(item) return results[:limit] ``` Это уже похоже на навигацию: я знаю, где машина, знаю, где цель, умею искать объекты. Но между ними все еще нужна дорога. И вот тут начался самый странный этап: дороги пришлось буквально добывать из картинки.
Если вам интересно посмотреть проект целиком - ссылка на мой GitHub в описании профиля.