Хабрахабр

Как я пытался починить поиск по картам для водителей. Часть 3 (финал)

Итак, это третья часть моей попытки переосмыслить привычный поиск по картам. Первая часть тут, а вторая тут — они более технические, но пробежать глазами для лучшего понимания можно. Вкратце это звучит так: мне надоело ковыряться в картах за рулем, пытаясь среди мелких значков и рекламы найти ближайшую заправку. Вместо этого хотелось бы просто ехать, посматривая на экран приложения. Чтобы оно сортировало ближайшие места по времени езды, показывало списком, объясняло, какие из них по пути и какой к ним трафик. Такая вот идея.

0 наконец получилось реализовать все основные функции, которые хотелось. Собственно, к версии приложения 3. Работал над новой версией месяца два интенсивно, все мелкие изменения не перечислить — по сути это на 80% новое приложение. После прошлой статьи из этой серии его скачало некоторое количество людей, и даже написали отзывы — спасибо, ко всем прислушался. Опять же, приглашаю сочувствующих оценить и поругать. С кардинально улучшенным интерфейсом, раза в 2 быстрее и значительно стабильнее. А под катом снова технические моменты.

Вот тут ссылки на айфон и андроид

Пробки

Одной из ключевых претензий к предыдущей версии приложения был неправильный расчет времени — я реализовал его своими силами через Open Source Routing Machine, и он считал чистое время дороги. В периоды минимального трафика (например, ночью) мои цифры совпадали с тем, что выдавали те же гугловские карты, но в большинстве случаев оценка были как минимум крайне оптимистична. Это нивелировало собственно сам смысл приложения, и надо было что-то придумать.

Очень не хотелось от кого-то зависеть, поэтому какое-то время я потратил на поиск второго решения. Пути решения здесь два: обратиться к стороннему апи или пытаться выкачать веса трафика откуда-то и импортировать к себе. Есть какие-то открытые базы по кускам Европы и Америки, которые в теории можно сшить с OSM через прыжки с бубном — но в итоге, поразмыслив, я решил не связываться. Итоги оказались неутешительными: я нигде не нашел базу весов трафика с глобальным покрытием, которая была бы совместима с OpenStreetMap. Короче, опять потратить кучу времени и получить мизер в итоге. Конечно, возможность хостить у себя навигацию с трафиком прельщала, но отпугнули неполное покрытие, сложности с интеграцией, погрешности и сам факт, что трафик кеширован, а не в реальном времени.

Потыкавшись, я остановил свой выбор на сервисах HERE — это бывшие карты нокии, потом их забрал к себе майкрософт, оставив в виде отдельного подразделения. Осознав, что в наше время без апи большого дяди никуда, я принялся искать адекватного и дешевого дядю. А главное, у них есть глобальный реалтаймовый трафик и достаточно щедрые квоты. Как я понял, они сейчас в основном работают с корпоративными клиентами (например по вопросам логистики) и имеют достаточно вменяемое и чистое апи. Неочевидный выбор, но я решил попробовать.

Немалую роль здесь сыграла общая гибкость архитектуры, которую я наваял. Интеграция в итоге оказалась довольно простой. Трафик из HERE я сделал отключаемым с фоллбэком в свою старую навигацию. При желании сейчас в нее несложно встроить хоть гугл, хоть яндекс пробки. Наконец, сравнивая значения без трафика (мои) и с трафиком, можно вывести общую оценку — пустая дорога, легкий трафик, средний и так далее.

Карты — список

Карты были второй главной претензией к приложению. Я угрохал какое-то невероятное количество времени на рисование собственных превьюшек маршрута и общей карты, и оно даже работало — но генерация растровых тайлов с модным дизайном колоссально просаживала сервер. Если в режиме тестирования картинки появлялись в пределах половины секунды, то с реальной аудиторией (даже небольшой), люди могли ждать до пяти или даже десяти (!!!!) секунд. Особенно, если кусок карты был крупный — тогда мой код пережевывал и рендерил кучу векторных данных. К тому же этот процесс особо не распараллелишь: там были узкие места, и все очереди все равно быстро забивались. В общем, печаль.

Я долго боролся с собой (весь я же так долго их делал), однако в итоге принял волевое решение и, в общем, правильно сделал. Что делать, было очевидно — выкинуть превьюшки карт к чертовой матери. Даже заполнив его новыми данными и увеличив надписи, я смог втиснуть в экран в два раза больше результатов, чем ранее. Когда огромные и зачастую не грузившиеся картинки ушли, стало спокойнее и освободилась куча места на экране.

Карты — новый режим

А вот с общей картой я поступил иначе. Никто (включая меня самого) не мог понять, зачем, собственно, она нужна. Она была самопальной, корявой, грузилась вечность и вообще изначально создавалась для дебага. Однако визуальное изображение изохроны почему-то продолжало мне греть душу и в итоге осталось занимать место в интерфейсе. Тогда я решил: а давай попробуем сделать из этой бессмысленной картинки полноценный альтернативный режим просмотра. Если кому-то не нравится список и он легче читает карту — почему бы и нет? Тем более у меня оставалась парочка идей, которым больше нигде не нашлось места.

Вместо нее я встроил полноценную карту через плагин flutter_map — фоновые тайлы взял у Mapbox — и стал показывать на ней свой положение и точки результатов вокруг. Скрепя сердце, я выкинул свою картинку (стонущий от нагрузки сервак был благодарен за это). Он довольно примитивный, но 90% случаев покрывает. Почти сразу всплыла необходимость эти точки кластеризовать, и я быстро набросал основанный на расстоянии код кластеризации. Наконец, легенда карты тоже стала интерактивной: тап по количеству результатов фокусирует карту на точках, а тап по времени — на изохроне. Под все это я опять подложил свою любимую зеленую кляксу изохроны. Довольно удобно.

Я пытался влепить это в карточки маршрутов разными способами, но нигде оно не выглядело органично и на своем месте. Одной из идей, в которой я чувствовал ценность, но никак не мог ее сформулировать, было отображение текущего маршрута и вектора движения автомобиля. Потому что в режиме списка я пишу напрямую текстом, по пути какое-то место или нет — а вот на карте это всегда непонятно. И вот наконец, почти отчаявшись, я понял: новый режим карты идеален для этой фишки. Даже у гугла или эппла ты наблюдаешь постоянно вертящийся сектор компаса и долгое время не понимаешь, в каком направлении ты едешь.

Пришлось попутно отрефакторить кучу кода, но спустя пару дней логика была готова. Воодушевленный, я сел работать. Каждое обновление я пересчитываю вектор движения, и так он получается очень точным, поскольку зависит не от акселерометра, а от предыдущей позиции. Я решил обновлять позицию не каждый 200 метров, как результаты, а гораздо чаще — через метров 10. Все это обновляется почти в реальном времени, и вы даже не представляете, насколько карта преобразилась и стала удобней. Маршрут (то есть массив истории наших координат) я рисую на карте линией, а направление движение — стрелочкой.

Замечали, как точка ползает по карте какое-то время вначале? Отдельным нюансом стал факт, что в первые секунды получения локации gps еще калибруется. А с учетом того, что ближайшее обновление результатов аж через 200 метров, это бы здорово дезинформировало водителя. С моей логикой эти фантомные перемещения сразу давали бы ложные выводы о направлении движения. То есть не показывать на карте ни стрелочку (хотя точка все равно ползает), ни маршрут. Решил я эту проблему очень просто: до первого обновления делать вид, что мы стоим. А разблокировать эти данные уже после, когда мы переместились на какое-то существенное расстояние, прошло секунд 5 и шансы получить ложную информацию практически нулевые.

По сути это те же данные, что и в списке, но к ним добавлена превьюшка маршрута (да-да, она все-таки вернулась) и кнопка, запускающая навигацию. Еще я добавил карточку, которая вылетает при выборе результата на карте.

Интерфейс

В целом интерфейс был основательно перекроен. Я не буду описывать, как переписал менюшки, заново отстроил цветовую палитру и все в таком духе. Сфокусируюсь на самых интересных моментах. Все надписи были пропорционально увеличены (мое падающее зрение тут пригодилось — увеличивал, пока сам с водительского кресла не увидел). Поменял шрифт на SF Pro Rounded — это закругленная вариация эппловского San Francisco. Качать тут, толковый шрифт. Настоятельно рекомендую в случаях, где у вас не сплошной текст, а крупные плашки, которые должны быть читаемы издалека.

Как и фильтр по времени, поначалу он казался чуть ли не основной функцией аппа. После некоторых раздумий принял неочевидное для себя решение убрать фильтр “По пути”. В режиме списка и так прекрасно видно, какие места по пути, а в режиме карты он и вовсе сбивает с толку. Однако в какой-то момент я понял, что им не пользуюсь. Плюс чисто технически он плодил нюансы, которые было муторно и совершенно необязательно решать. Я какое-то время бессмысленно таскал этот переключатель по интерфейсам, после чего просто скрыл его и ничего не потерял.

Данные

Собственно, главная на данный момент проблема приложения — данные. Я по-прежнему беру их из OSM со всеми сопутствующими проблемами: неравномерное покрытие, куча устаревших данных, отсутствие часов работы, телефонов и так далее. Мой бекенд построен так, что интегрировать в него любое стороннее апи мест очень просто — только вот где его взять? Первый (и самый лучший) кандидат это Google Places, но после недавнего удорожания на 1400% (господи) я пока их не могу себе позволить. Все остальные — TripAdvisor, Foursquare и им подобные — тоже или дорогие, или с корявым апи. Некоторые сервисы (тот же Mapbox или HERE) под видом своих данных предоставляют пережеванные места из OSM, которые у меня самого есть.

Я понимал, что это американский портал, соответственно, данных по другим частям света будет минимум, но это хотя бы какой-то прогресс. Из всей этой братии я решил попробовать прикрутить Yelp — он вроде недорогой и апи выглядело прилично. Однако не успел я обрадоваться, как начался какой-то цирк. И выглядело все поначалу неплохо: я за пару часов все интегрировал, и даже почитал, что они заявляют покрытие чуть ли не половины мира. Очевидно, они вводили места не через точки, а через адреса — и их геокодер расставлял координаты произвольно. Огромное количество мест в их данных имело неправильные координаты. Единственные свойства, по которым наши данные можно свести, это имя и адрес. В результате у меня какая-нибудь заправка находится в правильном месте, но кроме адреса почти не имеет данных; а у них есть и отзывы, и рейтинг, и часы работы — только вот координаты вообще какие-то левые. Я попробовал сличать их через свой геокодер + fuzzy matching, и, в принципе, это сработало — хотя какой-то процент мест мы таким образом все же теряем. Причем зачастую и то, и то написано произвольно, с ошибками, неправильно форматировано и тд.

Дальше посыпались остальные: у них очень нестабильный поиск по радиусу, куча багов (если почитать коменты людей в их гите, то там вообще ничего не работает) и так далее. Но это оказалось лишь первой проблемой. Посмотрев, как это выглядит в моем интерфейсе, я плюнул и весь этот балаган отключил. В конце концов я проверил требования по брендингу — оказывается, ты обязан использовать их красные (!!!) звезды для рейтинга мест.

Собственно, единственное, что можно (и очень легко) сделать — это прикрутить Google Places. В итоге, с данными прогресса особо нет. Только вот это стоит теперь очень больших денег. Там все отлично и с покрытием, и с координатами. В бесплатной версии было бы как сейчас, а за какую-то символическую сумму в месяц были бы доступны данные гугла или например яндекса (надо почитать, сколько у них стоит). Поэтому прошу вашего мнения: как бы вы отнеслись к платной подписке? Так я, наверное, не разорюсь.

Итог

В общем, я недавно прикинул: почти полтора года у меня заняло это приложение. Конечно, не все мое свободное время я на него тратил, но большую часть точно. Пару раз бросал на месяц, иногда казалось, что никогда не доделаю — но вот все-таки доделал. И, в принципе, сейчас оно выглядит именно так, как я хотел с самого начала. По пути освоил не одну новую технологию и получил очень много опыта. В общем, было интересно. Теперь я был бы рад, если бы результат кому-то пригодился.

P.S.

На правах саморекламы: в промежутке сделал для себя другое приложение, совсем маленькое — помощник при парковке. Я не перевел его на русский, но там однокнопочный интерфейс. Может, будет кому-то интересно.

Теги
Показать больше

Похожие статьи

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»
Закрыть