Сделать приложение Московского метро мне захотелось сразу же, как только Артемий Лебедев и его студия нарисовали схему метро в нынешнем виде.
1. Исходные данные
Сейчас официальную схему метро можно загрузить в PDF с официального сайта Московского метрополитена. На момент создания приложения (середина 2013 года) схема была доступна в виде .ai файла (Adobe Illustrator) на сайте студии Лебедева. В любом случае, следующий этап — это подготовка данных в Illustrator'e.
2. Подготовка данных
Открываем PDF в Illustrator, включаем режим preview и
После долгой и кропотливой работы (тут мне пригодился многолетний опыт работы в московской рекламной газете, сначала в отделе дизайна и вёрстки, затем в IT-отделе)
Что было сделано:
- удален многочисленный мусор, надписи и пр.
- каждая линия метро была разбита на участки между станциями. Линии разбивались под рисунками станций, чтобы при отрисовке построенных маршрутов не было видно стыков и разрывов.
— все «кусочки» линий и все станции, относящиеся к каждой линии, сгруппированы по слоям, в порядке их следования.
3. Преобразуем графику в XAML
Для перевода графики в XAML используется Microsoft Expression Design. Тут всё просто — открываем ai-файл, экспортируем в XAML.
4. Начинаем программирование (наконец-то)
В настоящий момент времени для разработки используется Visual Studio 2015 и MVVM-фреймворк MVVM-light. К сожалению, XAML-файл, полученный на предыдущем этапе, напрямую в приложении использовать не получится, кроме статичного слоя с реками и маршрутами «аэроэкспрессов».
Поэтому еще немного работы вручную — и в ресурсах приложения формируем окончательный XML-файл, используемый для рендеринга схемы метро. При его загрузке формируются объекты линий метро, станций метро, формируются связи между станциями в пределах одной линии, переходы между линиями, «замыкаются» кольцевые линии. К слову, переходы между линиями формируются программно. Между двумя станциями — проводятся линии с градиентом заливки, между тремя станциями — строятся дуги окружности, построенной по трём точкам — центрам станций, из которых состоит переход.
Пример View-слоя, отвечающего за отрисовку дуг переходов между тремя станциями (для краткости удалены ресурсы, отвечающие за анимацию и пр.):
<ItemsControl x:Name="ArcCrossings" ItemsSource="{Binding CrossingArcTypeList}" Visibility="Visible" Height="1760" Width="1765">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid x:Name="grid" Opacity="{Binding Dimmed, Converter={StaticResource BooleanToOpacityConverter}}">
<Path StrokeThickness="7.7" Stroke="{Binding CrossBrush}">
<Path.Data>
<PathGeometry>
<PathGeometry.Figures>
<PathFigureCollection>
<PathFigure StartPoint="{Binding GradientLineStartPoint}">
<PathFigure.Segments>
<PathSegmentCollection>
<ArcSegment Point="{Binding GradientLineEndPoint}" Size="{Binding ArcSize}" SweepDirection="Clockwise"/>
</PathSegmentCollection>
</PathFigure.Segments>
</PathFigure>
</PathFigureCollection>
</PathGeometry.Figures>
</PathGeometry>
</Path.Data>
</Path>
<Path StrokeThickness="2.4" Stroke="{Binding SettingsVM.BackMainBrush, Source={StaticResource Locator}}">
<Path.Data>
<PathGeometry>
<PathGeometry.Figures>
<PathFigureCollection>
<PathFigure StartPoint="{Binding BlackLineStartPoint}">
<PathFigure.Segments>
<PathSegmentCollection>
<ArcSegment Point="{Binding BlackLineEndPoint}" Size="{Binding ArcSize}" SweepDirection="Clockwise"/>
</PathSegmentCollection>
</PathFigure.Segments>
</PathFigure>
</PathFigureCollection>
</PathGeometry.Figures>
</PathGeometry>
</Path.Data>
</Path>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
Для поиска маршрутов используется волновой алгоритм с небольшими вариациями. Например, в случае, если находится оптимальный маршрут, содержащий два и более переходов, строятся дополнительные маршруты, в которых запрещено использовать «промежуточные» линии метро. В результате иногда получаются крайне парадоксальные и неожиданные варианты проезда (смотрите скриншоты ниже).
Для поиска необходимого вагона для удобного перехода на другую линию метро использовался следующий подход: у каждой линии установлено направление «вперед» и «назад». Соответственно, нам важно, с какой стороны мы подъехали к станции перехода, и иногда нам еще важно, в каком направлении мы поедем по той линии, на которую переходим.
Фрагмент XML-файла, описывающий станцию «Китай-город» Таганско-Краснопресненской линии и ее характерный переход на Калужско-Рижскую линию:
<Station name="Китай-город" lat="55.755361" lon="37.632361" Width="16.8277" Height="16.8282" Canvas.Left="1011.71" Canvas.Top="741.034" Data="F1 M 1017.45,746.771C 1015.97,748.25 1015.97,750.646 1017.45,752.125C 1018.93,753.604 1021.33,753.603 1022.8,752.125C 1024.29,750.646 1024.28,748.25 1022.81,746.77C 1021.33,745.292 1018.93,745.292 1017.45,746.771 Z M 1014.2,755.425C 1010.91,752.15 1010.88,746.824 1014.15,743.524C 1017.43,740.225 1022.75,740.2 1026.05,743.473C 1029.35,746.744 1029.38,752.071 1026.1,755.371C 1022.83,758.672 1017.51,758.695 1014.2,755.425 Z " TextLabel.Left="2" TextLabel.Top="-15" ShowPad="1" IsCrossPlatform="true" CrossPlatformColor="FFF37025">
<transfers>
<forward>
<transfer LineID="400" station="Китай-город">
<forward vagons="11111"/>
<backward vagons="00100"/>
</transfer>
</forward>
<backward>
<transfer LineID="400" station="Китай-город">
<forward vagons="00100"/>
<backward vagons="11111"/>
</transfer>
</backward>
</transfers>
</Station>
5. Несколько скриншотов построенных маршрутов (кликабельно)
6. Планы
На момент начала разработки приложения (напомню — это начало-середина 2013 года) речь шла об Windows 8 — 8.1. Собственно, приложение до сих пор «не-UWP». Соответственно, у приложения до сих пор есть «родимые пятна» Windows 8.1, в частности, неоднозначное расположение настроек приложения. Чего уж говорить, в Windows 10 «шарм» настроек «а-ля Windows 8.1» смотрится слегка чужеродно. Со временем, вероятно, это будет изменено.
В последнее обновление пришлось «выпилить» информацию о выходах в город (т.е., сейчас нет подсказки, в какой вагон садиться, чтобы было удобно выйти в город). Это в ближайших планах.
Комментарии (62)
vis_inet
05.03.2019 18:30пришлось «выпилить» информацию о выходах в город
А почему эта информация исчезла?infund Автор
05.03.2019 18:39Дело в том, что в последней версии я слегка изменил формат описания станции в XML (пример которого приведён в публикации для «Китай-города»). А информация о выходах в город хранилась там же. Честно говоря, хотелось побыстрее выкатить обновление с кучей более важных изменений, поэтому это было закомментированно и отложено.
Shersh
05.03.2019 18:53Ощущение, будто вернулся на 5 лет назад… когда сам разрабатывал под Win, WP, UWP…
Blaine_Mono
05.03.2019 20:18Странный маршрут между Боровицкой и Александровским садом возникает из-за того что между ними нет прямого перехода. На Боровицкой, насколько я помню, даже не объявляют переход на Александровский сад.
Для маршрута между Площадью Революции и Охотным рядом это тоже справедливо.infund Автор
05.03.2019 20:51Да, всё так, между этими станциями нет прямых переходов. Но есть переход «транзитом» через «Арбатскую» или «Библиотеку имени Ленина» в первом случае и через «Театральную» — во втором. Эти варианты тоже предложены, просто на скриншотах подробно изображены такие «вырожденные» варианты. «Нормальные» варианты в момент снятия скриншота были неактивны, но все равно видны.
Karpion
05.03.2019 20:23Понравилось:
Наличие указаний, в каком месте станции находится нужный переход. Вроде, в других приложениях, с которыми я встречался, такого не было (впрочем, я редко пользуюсь приложениями — нормально ориентируюсь и в реале, езжу в основном одними и теми же маршрутами).
Не понял:
Откуда берутся маршруты с большим количеством переходов?
По идее, пользователь должен указать, насколько тяжело ему ходить — в зависимости от возраста и поклажи. Если он ходит легко — то оптимизация чисто по времени. Если ходить ему тяжело — то оптимизация по расстоянию, которое надо пройти пешком, лестницы учитываются особо, с повышающим коэффициентом.
Не понравилось:
Привязка в одной платформе. Я считаю, что разрабатывать надо максимально кроссплатформенно — например, на JS.
Дальнейшее развитие (мои хотелки):
Рекомендую довести систему до такого состояния, чтобы она могла заменить «Яндекс/Гугл-карты». Т.е. ввести в базу данных все объекты: улицы, дома, наземный транспорт. Желательно — хранить всё в максимально компактном виде, чтобы работало быстро.
И желательно — чтобы работало автономно, без доступа к сети.
Но чтобы при наличии сети — можно было иметь информацию о движении транспорта в реальном времени, дабы карта могла сказать человеку «поторопись — автобус, на который ты должен сесть, будет через две минуты».infund Автор
06.03.2019 14:03То есть как — «откуда маршруты с большим количеством переходов»? Кто-то захочет проехать большее количество станций, но с одним переходом, а кто-то быстроногий, молодой и политически грамотный — покороче, но с «лишними» переходами.
От «Улицы 1905 года» до «Динамо» можно доехать так:
А можно так:
HaJIuBauKa
05.03.2019 21:00Круто. Но в чем главный посыл статьи? Только в качестве спортивного интереса. Приложение для десктопа уже практически не актуально. Нужно кроссплатформенной решение. Ну и с 2013 года прошло уже не мало времени. Яндекс уже все сделал.
infund Автор
05.03.2019 22:05В целом да, так и есть — спортивный интерес. На тот момент — новая область для меня, сейчас — просто не хочется бросать красивое приложение. Что касается того, что сделал яндекс… Ну не знаю, не эстетично это как-то… И не совсем понял, что именно сделал яндекс с 2013 года? metro.yandex.ru с тех пор не изменился
Denai
05.03.2019 21:49А у «большой винды» есть вообще легальные способы считать NFC? Я приложение метро всегда только для этой цели ставил, карта была скорее приятным бонусом
infund Автор
05.03.2019 22:01Да, какой-то SDK есть, но я никогда его не изучал. Планшеты на винде мало распространены, если мы говорим о возможности оплаты путем прикладывания устройства к турникету.
Denai
05.03.2019 22:13Не скажу про оплату ничего ибо не пользовался. Фишечка в том чтоб приложить тройку и понять надо ли что-то докинуть чтоб уехать:
Примерinfund Автор
05.03.2019 22:20А, я понял. Повторю, я не изучал этот вопрос, у меня была цель именно реализовать официальную «лебедевскую» схему метро.
makarychev13
05.03.2019 23:34Так и не понял. А приложение-то можно скачать где-то?
infund Автор
05.03.2019 23:36Windows 10? Запускаете Windows Store, в поиске вколачиваете «Московское метро», устанавливаете приложение. Прямые ссылки тут не приветствуются, как я понимаю.
Pilat
06.03.2019 09:14Всё это здорово, но пользоваться я буду только Яндексом. Успеете или нет внести исправления — не уверен, это изменения раз в сутки минимум, вручную Вы должны внести, я должен скачать… нереально.
Яндекс конечно сам не без греха. Вчера он (Я.Карта) так и не смог проложить правильный маршрут до Щукинского учебного театра. Арбатские наверно его совсем запутали. При открытии Я.Метро надо постоянно ждать пока он сбегает в Интернет — неудобно, если Интернет нестабилен. Но он хотя бы вешает предупреждения о закрытии станций.infund Автор
06.03.2019 09:22Чем пользоваться, безусловно, вопрос вкуса, тем более, что речь идёт о «немобильном» приложении. Мне не нравятся карты яндекса ни на yandex.metro.ru, ни в приложении для айфона. Что касается исправлений, тем более «раз в сутки» — ну не знаю, ничего критичного не происходит, поезда ходят, свет светит, до места доберёшься в любом случае. Какие там изменения, которые нужно вносить ежедневно? Эскалатор у выхода 3 станции Шипиловская не работает? Ну и чёрт с ним. А картинка официальной схемы метро мне нравится.
Pilat
06.03.2019 10:48Например, на Смоленской висит изменение времени работы — только на вход утром. На Рязанском — аналогично. Голубая ветка давно в ремонтах и где там поезда не останавливаются, когда это началось и когда закончилось — как узнать? Если маршрутизация правильно не работает, то от схемы вне зависимости от её красоты толку немного.
IL_Agent
06.03.2019 11:44+2В целом хорошая работа! Только почему-то winrt, а не uwp. Настройки и путь к ним — не по современным гайдам.
Ну и да, практическая ценность приложения в таком виде, увы, не велика. Много покупают, если не секрет? :)infund Автор
06.03.2019 11:54Ну про настройки я упомянул в публикации. И почему «не-UWP» — тоже. Не вижу особого смысла кардинально переделывать то, что было сделано 6 лет назад. По инфе от Microsoft, апдейты к приложениям на W8.1 они будут принимать всегда. А настройки можно реализовать в виде отдельной страницы. Ну и совершенно дикое время билда проекта в VS 2017 обескураживает… По поводу приобретений — сумма положительная, но унитазы в доме ещё не золотые (
roboter
06.03.2019 11:46+1Вроде как Xamarin это тотже XAML так что портировать под iOS, Android не сильно сложно.
mrxten
06.03.2019 14:51не, стандартный набор контролов из коробки в Xamarin.Forms очень уж куцый. в любом случае в натив опускаться, а там считай все заново делать. либо отрисовывать через какую нибудь SkiaSharp. что было бы проще, мне кажется
linux_id
Так винду мобильную прекращают же поддерживать?
infund Автор
Это приложение для «большой винды»
Anton23
Не хотите сделать так же только для СПб?
infund Автор
Почему нет, если ткнете меня в ссылку на официальную схему СПб. Есть еще один момент — всегда есть нюансы, и поэтому хорошо быть «местным» и быть в курсе деталей проезда, переходов и пр. Для Москвы я — «местный».
staticlab
http://www.metro.spb.ru/uploads/img/map/metro_map2018_1700x2431.jpg
Из нюансов метро СПб разве что кроссплатформенная пересадка на Технологическом институте (как в Москве на Китай-Городе).
infund Автор
Да, по сравнению с московским метро… Не разгуляешься, скудноватая схема )) Но можно, почему бы нет…
mtop
Вы еще Омское метро не видели, а также Красноярское метро. В Новокузнецке его вообще поверх города построить хотят.
c13
Наземное метро (скоростной трамвай) — это единственная возможность построить наземный транспорт с большим покрытием в этих городах. За рубежом подобное называется LRT, например: Прага, Будапешт или Кельн.
tnsaturday
Трамвай — это не метро. Трамвай — это когда все деньги украли, а построить что-то надо.
c13
Современный трамвай раз в 10 дешевле метро. LRT удобнее, потому что не нужно пускаться под землю, можно чаще чем раз в километр делать остановки. Получается, что LRT намного выгоднее для городов-миллионников, чем метро.
https://gre4ark.livejournal.com/576213.html
tnsaturday
Современная маршрутка раз в 10 дешевле трамвая. Не нужно портить асфальт, не нужно вешать провода, можно остановки делать на каждом перекрестке. Получается, что маршрутки намного выгоднее для городов-миллионников, чем трамвай.
mtop
в выше перечисленных городах, из моего коммента, с метром все плохо, скажем так ооочень плохо, нет скажу еще больше: ваще плохо, но зато на бумаге оно есть, а так с ним все плохо, даже очень
p.s. я со словом плохо не переборщил?
codemafia
Вы забыли упомянуть про Барнаульский метрополитен.
domix32
А зачем, если можно открыть какой-нибудь metro.ya.ru? Как будут обновляться открытые/закрытые станции?
infund Автор
Приложение полностью «оффлайновое», таким образом, при изменении схемы метро я вношу изменения в приложение и отправляю апдейт. Что касается metro.yandex.ru, по мне — там именно ужас-ужас. Понятно, что функционально и утилитарно, но мне понравилась официальная схема метро и захотелось ее реализовать. Я уж не касаюсь того, что в iOS у яндекса своя третья (!) схема.
unclegluk
Кто-то пользуется в дороге «большой виндой»? Под Андроид или Айос было бы понятно. Но в таком виде — что делать людям с системами, отличными от виндов? Да и 2013 год как-то давненько по современным цифровым меркам был, лет, эдак, «50» назад.
infund Автор
Ну, во-первых, маршрут можно прикинуть «до» выхода. А обсудить его (маршрут), скажем, вдвоём — удобнее на большом экране. Во-вторых, вполне себе есть планшеты с «большой» виндой. Ещё раз — я прекрасно понимаю, что все уткнулись в смартфоны. Но это вовсе не основание не отметиться лично мне в магазине Microsoft с симпатичным приложением. Насчёт 2013 года — не вполне уловил мысль в контексте разработки под винду. Все применённые методы и технологии с минимальными изменениями актуальны и сейчас.
unclegluk
Большая винда на планшетах, как и мобильная версия — уже статистически незначимая величина.
Насчёт 2013 года — если вы взяли схему 2013 года, то она давно протухла. Винды здесь ни причем.
infund Автор
Ну не знаю, у меня аж два планшета на винде )). Что касается схемы метро, то по скриншотам видно,
что она находится в актуальном, нынешнем состоянии. Скажем, издалека видно Московское центральное кольцо, а оно открылось в 2016. Разумеется, приложение аккуратно обновляется.
unclegluk
у меня аж два планшета на винде — у меня не то что на планшетах, но вообще нет винды как класса.
zagayevskiy
Использовать приложение от Яндекса.
LoadRunner
Пока Майкрософт не отбирает смартфоны у пользователей, они ими пользуются, даже если нет поддержки.
infund Автор
И на том спасибо…