Сделать приложение Московского метро мне захотелось сразу же, как только Артемий Лебедев и его студия нарисовали схему метро в нынешнем виде.

1. Исходные данные


Сейчас официальную схему метро можно загрузить в PDF с официального сайта Московского метрополитена. На момент создания приложения (середина 2013 года) схема была доступна в виде .ai файла (Adobe Illustrator) на сайте студии Лебедева. В любом случае, следующий этап — это подготовка данных в Illustrator'e.

2. Подготовка данных


Открываем PDF в Illustrator, включаем режим preview и падаем в обморок.

ужас-ужас

(кликабельно)

После долгой и кропотливой работы (тут мне пригодился многолетний опыт работы в московской рекламной газете, сначала в отделе дизайна и вёрстки, затем в IT-отделе)

получилось следующее

(кликабельно)

Что было сделано:

  • удален многочисленный мусор, надписи и пр.
  • каждая линия метро была разбита на участки между станциями. Линии разбивались под рисунками станций, чтобы при отрисовке построенных маршрутов не было видно стыков и разрывов.

вот так:


— все «кусочки» линий и все станции, относящиеся к каждой линии, сгруппированы по слоям, в порядке их следования.

вот так:


3. Преобразуем графику в XAML


Для перевода графики в XAML используется Microsoft Expression Design. Тут всё просто — открываем ai-файл, экспортируем в XAML.

Microsoft Expression Design:

(кликабельно)

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)


  1. linux_id
    05.03.2019 17:40

    Так винду мобильную прекращают же поддерживать?


    1. infund Автор
      05.03.2019 17:41
      +1

      Это приложение для «большой винды»


      1. Anton23
        05.03.2019 18:37

        Не хотите сделать так же только для СПб?


        1. infund Автор
          05.03.2019 18:43

          Почему нет, если ткнете меня в ссылку на официальную схему СПб. Есть еще один момент — всегда есть нюансы, и поэтому хорошо быть «местным» и быть в курсе деталей проезда, переходов и пр. Для Москвы я — «местный».


          1. staticlab
            05.03.2019 19:21

            http://www.metro.spb.ru/uploads/img/map/metro_map2018_1700x2431.jpg


            Из нюансов метро СПб разве что кроссплатформенная пересадка на Технологическом институте (как в Москве на Китай-Городе).


            1. infund Автор
              06.03.2019 09:37

              Да, по сравнению с московским метро… Не разгуляешься, скудноватая схема )) Но можно, почему бы нет…


              1. mtop
                06.03.2019 12:32
                +1

                Вы еще Омское метро не видели, а также Красноярское метро. В Новокузнецке его вообще поверх города построить хотят.


                1. c13
                  06.03.2019 13:50

                  Наземное метро (скоростной трамвай) — это единственная возможность построить наземный транспорт с большим покрытием в этих городах. За рубежом подобное называется LRT, например: Прага, Будапешт или Кельн.


                  1. tnsaturday
                    06.03.2019 13:52

                    Трамвай — это не метро. Трамвай — это когда все деньги украли, а построить что-то надо.


                    1. c13
                      06.03.2019 16:51

                      Современный трамвай раз в 10 дешевле метро. LRT удобнее, потому что не нужно пускаться под землю, можно чаще чем раз в километр делать остановки. Получается, что LRT намного выгоднее для городов-миллионников, чем метро.
                      https://gre4ark.livejournal.com/576213.html


                      1. tnsaturday
                        06.03.2019 17:39

                        Современная маршрутка раз в 10 дешевле трамвая. Не нужно портить асфальт, не нужно вешать провода, можно остановки делать на каждом перекрестке. Получается, что маршрутки намного выгоднее для городов-миллионников, чем трамвай.


                  1. mtop
                    06.03.2019 13:54
                    +1

                    в выше перечисленных городах, из моего коммента, с метром все плохо, скажем так ооочень плохо, нет скажу еще больше: ваще плохо, но зато на бумаге оно есть, а так с ним все плохо, даже очень

                    p.s. я со словом плохо не переборщил?


                1. codemafia
                  06.03.2019 13:59
                  +1

                  Вы забыли упомянуть про Барнаульский метрополитен.


      1. domix32
        05.03.2019 19:01

        А зачем, если можно открыть какой-нибудь metro.ya.ru? Как будут обновляться открытые/закрытые станции?


        1. infund Автор
          05.03.2019 20:56

          Приложение полностью «оффлайновое», таким образом, при изменении схемы метро я вношу изменения в приложение и отправляю апдейт. Что касается metro.yandex.ru, по мне — там именно ужас-ужас. Понятно, что функционально и утилитарно, но мне понравилась официальная схема метро и захотелось ее реализовать. Я уж не касаюсь того, что в iOS у яндекса своя третья (!) схема.


      1. unclegluk
        06.03.2019 14:38

        Кто-то пользуется в дороге «большой виндой»? Под Андроид или Айос было бы понятно. Но в таком виде — что делать людям с системами, отличными от виндов? Да и 2013 год как-то давненько по современным цифровым меркам был, лет, эдак, «50» назад.


        1. infund Автор
          06.03.2019 14:48
          +1

          Ну, во-первых, маршрут можно прикинуть «до» выхода. А обсудить его (маршрут), скажем, вдвоём — удобнее на большом экране. Во-вторых, вполне себе есть планшеты с «большой» виндой. Ещё раз — я прекрасно понимаю, что все уткнулись в смартфоны. Но это вовсе не основание не отметиться лично мне в магазине Microsoft с симпатичным приложением. Насчёт 2013 года — не вполне уловил мысль в контексте разработки под винду. Все применённые методы и технологии с минимальными изменениями актуальны и сейчас.


          1. unclegluk
            06.03.2019 15:08

            Большая винда на планшетах, как и мобильная версия — уже статистически незначимая величина.
            Насчёт 2013 года — если вы взяли схему 2013 года, то она давно протухла. Винды здесь ни причем.


            1. infund Автор
              06.03.2019 15:14

              Ну не знаю, у меня аж два планшета на винде )). Что касается схемы метро, то по скриншотам видно,



              что она находится в актуальном, нынешнем состоянии. Скажем, издалека видно Московское центральное кольцо, а оно открылось в 2016. Разумеется, приложение аккуратно обновляется.


              1. unclegluk
                06.03.2019 15:28
                -2

                у меня аж два планшета на винде — у меня не то что на планшетах, но вообще нет винды как класса.


        1. zagayevskiy
          06.03.2019 18:29

          что делать людям с системами, отличными от виндов?

          Использовать приложение от Яндекса.


    1. LoadRunner
      06.03.2019 09:25

      Пока Майкрософт не отбирает смартфоны у пользователей, они ими пользуются, даже если нет поддержки.


      1. infund Автор
        06.03.2019 12:28
        +1

        Пока Майкрософт не отбирает смартфоны у пользователей...

        И на том спасибо…


  1. vis_inet
    05.03.2019 18:30

    пришлось «выпилить» информацию о выходах в город

    А почему эта информация исчезла?


    1. infund Автор
      05.03.2019 18:39

      Дело в том, что в последней версии я слегка изменил формат описания станции в XML (пример которого приведён в публикации для «Китай-города»). А информация о выходах в город хранилась там же. Честно говоря, хотелось побыстрее выкатить обновление с кучей более важных изменений, поэтому это было закомментированно и отложено.


  1. Exchan-ge
    05.03.2019 18:42
    +1

    Хорошо у вас получилось.
    Продолжайте )


    1. infund Автор
      05.03.2019 18:45

      Спасибо ))


  1. Shersh
    05.03.2019 18:53

    Ощущение, будто вернулся на 5 лет назад… когда сам разрабатывал под Win, WP, UWP…


    1. prostofilya
      05.03.2019 19:02

      UWP выкатили с win 10, а релиз десятки был 3.5 года назад. Как так?


      1. Shersh
        05.03.2019 19:09

        ну начинал то я с WP 7 =)


  1. Blaine_Mono
    05.03.2019 20:18

    Странный маршрут между Боровицкой и Александровским садом возникает из-за того что между ними нет прямого перехода. На Боровицкой, насколько я помню, даже не объявляют переход на Александровский сад.
    Для маршрута между Площадью Революции и Охотным рядом это тоже справедливо.


    1. infund Автор
      05.03.2019 20:51

      Да, всё так, между этими станциями нет прямых переходов. Но есть переход «транзитом» через «Арбатскую» или «Библиотеку имени Ленина» в первом случае и через «Театральную» — во втором. Эти варианты тоже предложены, просто на скриншотах подробно изображены такие «вырожденные» варианты. «Нормальные» варианты в момент снятия скриншота были неактивны, но все равно видны.


  1. Karpion
    05.03.2019 20:23

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

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

    Не понравилось:
    Привязка в одной платформе. Я считаю, что разрабатывать надо максимально кроссплатформенно — например, на JS.

    Дальнейшее развитие (мои хотелки):
    Рекомендую довести систему до такого состояния, чтобы она могла заменить «Яндекс/Гугл-карты». Т.е. ввести в базу данных все объекты: улицы, дома, наземный транспорт. Желательно — хранить всё в максимально компактном виде, чтобы работало быстро.
    И желательно — чтобы работало автономно, без доступа к сети.
    Но чтобы при наличии сети — можно было иметь информацию о движении транспорта в реальном времени, дабы карта могла сказать человеку «поторопись — автобус, на который ты должен сесть, будет через две минуты».


    1. HaJIuBauKa
      05.03.2019 20:54

      вы предлагаете написать свой яндекс карты, метро, транспорт? :)


    1. infund Автор
      06.03.2019 14:03

      То есть как — «откуда маршруты с большим количеством переходов»? Кто-то захочет проехать большее количество станций, но с одним переходом, а кто-то быстроногий, молодой и политически грамотный — покороче, но с «лишними» переходами.
      От «Улицы 1905 года» до «Динамо» можно доехать так:

      А можно так:


      1. Ametrin
        06.03.2019 14:21

        но на втором маршруте и время меньше, и количество пересадок… т.е. лучше сразу по обоим параметрам


        1. infund Автор
          06.03.2019 14:27

          Я о чём: приложение предлагает возможные варианты. А вот так — от «Улицы 1905 года» до «Марьиной рощи»?

          или


  1. nerudo
    05.03.2019 20:42

    pMetro смотрели? Если хочется «свое» — можно взять их формат файлов — там планы постоянно актуализируются.


    1. infund Автор
      05.03.2019 20:58

      Спасибо, когда-то помнил про них, потом забыл


  1. HaJIuBauKa
    05.03.2019 21:00

    Круто. Но в чем главный посыл статьи? Только в качестве спортивного интереса. Приложение для десктопа уже практически не актуально. Нужно кроссплатформенной решение. Ну и с 2013 года прошло уже не мало времени. Яндекс уже все сделал.


    1. infund Автор
      05.03.2019 22:05

      В целом да, так и есть — спортивный интерес. На тот момент — новая область для меня, сейчас — просто не хочется бросать красивое приложение. Что касается того, что сделал яндекс… Ну не знаю, не эстетично это как-то… И не совсем понял, что именно сделал яндекс с 2013 года? metro.yandex.ru с тех пор не изменился


  1. Denai
    05.03.2019 21:49

    А у «большой винды» есть вообще легальные способы считать NFC? Я приложение метро всегда только для этой цели ставил, карта была скорее приятным бонусом


    1. infund Автор
      05.03.2019 22:01

      Да, какой-то SDK есть, но я никогда его не изучал. Планшеты на винде мало распространены, если мы говорим о возможности оплаты путем прикладывания устройства к турникету.


      1. Denai
        05.03.2019 22:13

        Не скажу про оплату ничего ибо не пользовался. Фишечка в том чтоб приложить тройку и понять надо ли что-то докинуть чтоб уехать:

        Пример
        image


        1. infund Автор
          05.03.2019 22:20

          А, я понял. Повторю, я не изучал этот вопрос, у меня была цель именно реализовать официальную «лебедевскую» схему метро.


    1. IL_Agent
      06.03.2019 11:35
      +1

      Так у кассиров терминалы на винде. Подключаем ридер, ставим дрова и вперёд. Ну и формат данных надо знать, конечно, чтобы тройку прочитать.


      1. infund Автор
        06.03.2019 11:49

        Можно даже и без отдельного ридера обходиться — есть планшеты на винде с NFC. Формат данных — это да…


  1. makarychev13
    05.03.2019 23:34

    Так и не понял. А приложение-то можно скачать где-то?


    1. infund Автор
      05.03.2019 23:36

      Windows 10? Запускаете Windows Store, в поиске вколачиваете «Московское метро», устанавливаете приложение. Прямые ссылки тут не приветствуются, как я понимаю.


      1. makarychev13
        05.03.2019 23:52

        Спасибо, заценю


  1. Pilat
    06.03.2019 09:14

    Всё это здорово, но пользоваться я буду только Яндексом. Успеете или нет внести исправления — не уверен, это изменения раз в сутки минимум, вручную Вы должны внести, я должен скачать… нереально.

    Яндекс конечно сам не без греха. Вчера он (Я.Карта) так и не смог проложить правильный маршрут до Щукинского учебного театра. Арбатские наверно его совсем запутали. При открытии Я.Метро надо постоянно ждать пока он сбегает в Интернет — неудобно, если Интернет нестабилен. Но он хотя бы вешает предупреждения о закрытии станций.


    1. infund Автор
      06.03.2019 09:22

      Чем пользоваться, безусловно, вопрос вкуса, тем более, что речь идёт о «немобильном» приложении. Мне не нравятся карты яндекса ни на yandex.metro.ru, ни в приложении для айфона. Что касается исправлений, тем более «раз в сутки» — ну не знаю, ничего критичного не происходит, поезда ходят, свет светит, до места доберёшься в любом случае. Какие там изменения, которые нужно вносить ежедневно? Эскалатор у выхода 3 станции Шипиловская не работает? Ну и чёрт с ним. А картинка официальной схемы метро мне нравится.


      1. Pilat
        06.03.2019 10:48

        Например, на Смоленской висит изменение времени работы — только на вход утром. На Рязанском — аналогично. Голубая ветка давно в ремонтах и где там поезда не останавливаются, когда это началось и когда закончилось — как узнать? Если маршрутизация правильно не работает, то от схемы вне зависимости от её красоты толку немного.


  1. infund Автор
    06.03.2019 09:36

    del


    1. bopoh13
      06.03.2019 18:16

      Было бы здорово увидеть эту красоту в мобильном приложении pMetro.


  1. IL_Agent
    06.03.2019 11:44
    +2

    В целом хорошая работа! Только почему-то winrt, а не uwp. Настройки и путь к ним — не по современным гайдам.
    Ну и да, практическая ценность приложения в таком виде, увы, не велика. Много покупают, если не секрет? :)


    1. infund Автор
      06.03.2019 11:54

      Ну про настройки я упомянул в публикации. И почему «не-UWP» — тоже. Не вижу особого смысла кардинально переделывать то, что было сделано 6 лет назад. По инфе от Microsoft, апдейты к приложениям на W8.1 они будут принимать всегда. А настройки можно реализовать в виде отдельной страницы. Ну и совершенно дикое время билда проекта в VS 2017 обескураживает… По поводу приобретений — сумма положительная, но унитазы в доме ещё не золотые (


      1. IL_Agent
        06.03.2019 12:01
        +1

        Прошу прощения, не дочитал до конца — бросился устанавливать ))). К причинам перехода на uwp можно отнести возможность перехода на новую студию и использования новых фич.


        1. infund Автор
          06.03.2019 12:05

          Это да, всякие красивости и пр. Ну посмотрим.


  1. roboter
    06.03.2019 11:46
    +1

    Вроде как Xamarin это тотже XAML так что портировать под iOS, Android не сильно сложно.


    1. infund Автор
      06.03.2019 11:57

      Нет, лично меня с Xamarin'а воротит… А вот Swift — очень приятен.


    1. mrxten
      06.03.2019 14:51

      не, стандартный набор контролов из коробки в Xamarin.Forms очень уж куцый. в любом случае в натив опускаться, а там считай все заново делать. либо отрисовывать через какую нибудь SkiaSharp. что было бы проще, мне кажется