Как сделать схему метро в metro

Обновлено: 04.07.2024

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

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

С другой стороны, пересадка «Пушкинская» — «Тверская» — «Чеховская» выглядит в пять раз чище, пропал непонятный поворот серой ветки и девяностокилометровый перегон между «Аннино» и «Бульваром Дмитрия Донского». Кстати, другие дизайнеры при создании своих схем часто копируют этот странный фрагмент :-)

Вернемся к старой сорокапятиградусной схеме и попробуем все это так сохранить.

Из-за того, что «Смоленским» и «Арбатским» теперь потребовалось немного больше места (добавилась река, появились строящиеся «Плющиха» и «Волхонка» — вот это всё), переход на «Библиотеке им. Ленина» перестал быть большим красивым кругом и стал больше похож на центральный московский ипподром. В общем, стало окончательно ясно, что визитную карточку предыдущей схемы — пересадку на «Библиотеке» — следует выкинуть в корзину и нарисовать новую визитную карточку.

Ини и яни нравятся способом построения, но не нравятся тем, что нихуя, прямо скажем, не считываются.

Тут внезапно пришел Людвиг и нарисовал на бумажке руль.

Охуенно, оставляем руль.

Заодно решено привести размеры всех кружков-пересадок к одному знаменателю. Раньше размера было три: маленький (когда пересадка из трех станций с разными названиями), средний (две станции с одним названием, а третья — с другим) и большой (все три станции называются «Киевская» и их нужно, блядь, как-то подписать).

Попробуем сделать все кружки большими, как «Киевская»:

О, вроде норм. Ну а «Киевская» пусть так и будет исключением. И «Библиотеку» еще раза в два покрупнее (Тема попросил).

Параллельно придумываем, как показать железнодорожные ветки. Дело в том, что показывать просто пересадку со станции «Кунцевская» на платформу Кунцево-I — это не очень информативно. Гораздо информативнее то, что, пересев на Кунцево-I, пассажир может доехать сначала до «Филей», а потом и вовсе до «Белорусской».


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

В итоге останавливаемся на деликатных розовых полосочках, которые видны, но в глаза не бросаются. И дружат со скоростными автобусами — 901, 902, 903 и 904.

Добавляем сетку, список станций и легенду.

Проверяем расстояние от текста до меток на всех ветках.


Файл отправляется на конкурс Дептранса, Егор отправляется на самолет.


Эволюция схемы в 95 картинках:
































































































Одной из причин создания второй версии схемы было желание вставить в нее строящийся второй пересадочный контур и продолжить желтую ветку на запад. Теперь можно их удалить — получится в два раза чище:


У 903 автобуса конечная — Холмогорская улица, а не Мытищи, а у 902 — Ново-Переделкино, а не Солнцево:


Выравниваем ветки на севере, съехавшие из-за строящихся веток:


А теперь — на юге:


Все, можно готовить анонс и рисовать для него последнюю картинку.


Может, на этой картинке должны стоять маршруты автобусов между периферийными станциями?


Или какая-нибудь контурная фигня на айфоне?


Или там должна стоять схема с кольцевыми дорогами и кросс-платформенными пересадками?


Или нет, не просто кольцевые дороги, а еще и главные шоссе и достопримечательности. И пусть это будет не последняя картинка, а первая.

Выводы

Проблемы с «Mozilla Firefox»

В процессе работы выяснилось, что «Mozilla Firefox» переоптимизированна. В то время как другие ребята исправно отображают всю графику, «Mozilla» допускает пропуск рендера элементов, если элемент не виден пользователю — закрыт div'ом сверху или просто вне области видимости монитора. Как сознательный гражданин я добавил баг, который до сих пор неподтверждён, так как удовлетворить просьбу предоставить the simplest possible testcase у меня не получается, на малом количестве элементов всё работает нормально, а ссылки на проект, видимо, не достаточно.

Если это читает представитель «Mozilla»: Ребят, работает криво независимо от платформы (windows/mac) и версии (наблюдается и в старых версиях), чесслово.

В качестве заключения

Несмотря на то, что в html5 осталась некоторая сырость, пришло время его использовать. Не нужно нагружать процессоры пользователей, добавляя на каждый второй сайт «модные» эффекты, которые ещё вчера были в рассылке для frontend-разработчиков.

Но пришло время делать удобные транспортные схемы и интерактивные продукты, доступные с любого устройства.

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

Формируем требования

  1. Показ станций и линий для выбранного диапазона дат
  2. Красота — «Студия Лебедева» разработала замечательную схему; её и возьмём за основу.
  3. Удобство использования.
    • Для ввода значений я решил использовать ползунки (range slider). С ними мы добьёмся интерактивности и изменений «на лету».
    • Я привык к функционалу картографических сервисов, позволяющих менять масштаб и двигать карту, — реализуем его; тем более что наша схема, по факту, и есть карта.
    • Добавим возможность поделиться ссылкой на выборку.

Отображаем схему

Чтобы сделать схему интерактивной нам, для начала, нужна сама схема. Взглянем на то, что мы хотим получить и разберём картинку на простые элементы.

Станции

Самое главное на схеме, — станции, поэтому начнём с них. Всего 3 типа: конечные, пересадочные и обычные. 2 прямоугольника и круг. Что может быть проще? Кропотливо расставим их на полотне, а некоторые ещё и повернём.

Сохраните схему как картинку, задайте невысокую прозрачность и расположите её под нашим svg-холстом, которому задайте такие же размеры. Это упростит расстановку станций.



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

Если вы делаете нечто большее, нежели proof of concept, не пожалейте нескольких часов на написание редактора с возможностью перетаскивания станций и указания их свойств. Обслуживать вашу карту станет на порядок проще. Целесообразность прямо пропорциональна количеству станций и их свойств.
Линии

Что же такое линия? Это набор отрезков между станциями. У нас есть координаты, индексы и линии станций — а значит мы легко нарисуем отрезки. Пройдёмся по станциям и будем руководствоваться следующей логикой для каждой из них: если есть станция той же линии, но с индексом старше на единицу, то рисуем между ними сегмент.

Взгляните на схему и попробуйте ответить, какие 2 сегмента не будут нарисованы?

1. отрезок на кольцевой, соединяющий «младшую» и «старшую» по индексу станции
2. отрезок между «Выставочной» и «Киевской»

Как мы увидим, начало и конец сегмента идут не совсем так, как нам надо. Добавим для каждого из 3 типов станций смещение, высчитанное опытным путём. Так же наши сегменты заданы прямыми, но сами линии много где причудливо изогнуты. Пожалуй, это самая кропотливая часть работы над проектом, для ряда сегментов добавим исключение в поведении. Благо, синтаксис несложный.



Переходы

Svg графика использует модель слоёв, а значит чтобы получить нужный результат, каждый переход сделаем с помощью двух кривых: цветная с толстой обводкой пониже и белая с тонкой повыше. Итогое расположение элементов следующее, от нижних к верхним: линии, отрезки переходов с цветной толстой обводкой, станции, отрезки переходов с тонкой белой обводкой, подложка названия станций, название станций.

Названия станций и подложка

Отобразим названия и выровняем текст с помощью свойства text-anchor. Способа осуществить перенос строки, кроме как созданием дополнительного элемента, к сожалению, нет.

Подложку текста сделаем обычным полупрозрачным прямоугольком. Размеры и координаты текста мы получим с помощью getBBox.

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

Приложение Московское метро для Windows Store


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

Почти всё

Я использовал модульную архитектуру (вышло где-то полтора десятка модулей), в помощь взял Snap.svg. Данные подгружались динамично, просчитывались и, так как часть вещей была сделана с помощью promises (я использовал jquery, так что их взял оттуда же), я даже смог добавить нехитрый прогресс бар пока всё загружается.

Радость длилась, пока я не решил зайти с телефона… На весьма неглупой lumia 1020 сервис грузился дольше, чем пол минуты. Я же абсолютно забыли о цене манипуляций с dom. У нас, на секунду, больше тысячи элементов! Да и манипуляции с viewBox на мобильном устройстве не работали нормально.

Масштабируем и двигаем

Ответственность за это возьмёт на себя свойство viewBox. Ребята из «Микрософт» написали отличную статью с примерами. Для перехвата скрола я использовал jQuery Mousewheel. Признаться, не самая тривиальная задача, так как при изменении масштаба нужно учитывать сдвиг относительно изначального положения с соответсвующим зуму коэффициентом.

Исправляем недочёты

С клиента на сервер

Волевым решением переносим логику на сервер и кешируем выдачу, чтобы не считать каждый раз. Теперь можно отказаться от Snap.svg на клиенте!

Самописный генератор градиентов для svg весил всего ничего и был изящен, но иногда не срабатывал: к некоторым элементам не применялся ни один из градиентов, только цвет. В то же время с другими элементами градиенты работали абсолютно нормально. Устав от «чёрной магии» я вернул библиотеку в строй. Всё же я пишу доказательство работоспособности, а не «продукт».

Нужно закрыть вопрос с масштабированием и возможностью двигать на мобильных. Подумайте, как бы вы справились с этим.

Начал с поиска библиотек (остановился на hammer.js) и даже ознакомится с документацией, но вспомнил про ТРИЗ. Генрих Альтшуллер определяет идеальный объект, как объект, которого нет, а его функция выполняется.

У нас на носимых устройствах уже есть замечательная поддержка масштабирования и сдвига. А значит… Да, я просто вырубил для телефонов и планшетов манипуляцию с viewBox-свойством.

Что принёс перенос в цифрах?





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

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

Создаём интерактивную векторную схему московского метро

Московское метро меняется. Желающий представить себе схему, скажем, 1945 года без проблем соберёт данные из открытых источников; остаётся вопрос с представлением результата, — не на круговой диаграмме же его показывать. В статье я расскажу об основных шагах в создании proof-of-concept сервиса, позволяющего показать схему метро, например, на 1 мая 74 года (слева) или станции с глубиной заложения больше 30 метров (справа).




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

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

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

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

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



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



Фильтруем

Здесь тоже нестрашно. Проверим, находится ли значение станции в выбранном диапозоне и спрячем станцию, если нет. Когда разберёмся со станциями, поймём, что делать с остальными элементами: если станция спрятана, ни название, ни переход к ней, ни отрезок ветки не должны быть отображены.

Используйте свойство visibility, так как opacity хоть и спрячет элементы, но оставит их выделяемыми и кликабельными.

Так же мы видим, что некоторые станции имеют одно название. Соответственно, прятать название нужно только когда спрятана последняя из станций, связанных с этим названием.

Остаётся настроить понравившийся вам range slider. По определенным причинам я написал свой. Ленивым адекватным людям посоветую, например, этот.

Создание схемы линий Московского метро

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

Ищем основу для равномерности.

Играем в некруглое кольцо. В истории дизайна схем Московского метро такие варианты встречались.





Неплохой, но слишком нестандартный вариант. У нас задача — оставаться знакомой схемой, к которой привыкли москвичи.



Может, такие переходы?



Поиск вдохновения в расположении станций с привязкой к топографии.



Главный плюс этой схемы в том, что центр города тут находится ровно в центре изображения. Добавляем Садовое кольцо, добавляем третье. Больше плюсов нет.



Зато идея с привязкой наталкивает на мысль сохранить топографию в схеме в виде мнемонических подсказок. Дадим слово дизайнеру:

«Грубо говоря, схема привязана к расположению выходов (особенно важно это на подробной схеме, где Садовое кольцо проходит между „Парками Культуры“, „Октябрьскими“, „Павелецкими“ и т. д.). Где-то факт географически точного расположения выходов означает заодно и точное расположение станций („Марксистская“ и „Таганские“, например), где-то — нет („Чкаловская“ и „Курские“).

Еще есть развязки типа „Пушкинской“ — „Тверской“ — „Чеховской“. Выхода там два: общий между „Пушкинской“ и „Тверской“ и общий между „Пушкинской“ и „Чеховской“. В нашей вселенной, где все кратно 45 градусам, они расположены на одной горизонтали. Саму развязку относительно горизонтальной оси мы флипанули (станция „Пушкинская“, на самом деле, севернее двух других), но на расположение выходов это не повлияло».



Хромосома в центре слишком бросается в глаза. Зато появились схемы переходов. Они нам нравятся как идея, но не нравятся на вид.



Все равно не то.



Рождается идея с пересадочными узлами в виде колец. Этот момент напоминает момент в «Докторе Хаусе», когда его вдруг осеняет и зрители понимают, что дело раскрыто. «Вот оно» — главный момент в каждом дизайнерском проекте.



Гармонизируем расположение станций и пересадок.



Включаем все дорожные кольца, расставляем высотки, играем.





Варианты с указанием расположения выходов в город.



Дружит ли Лондон с Москвой? Приживется ли британская штриховка в московском климате?





Лучше просто квадраты. У нас не такая сложная схема, как в Нью-Йорке. И зон, от которых зависит цена проезда, пока что нет.



Посмотрим в сборе. Плохо, слишком много блох. Черные такие, всю схему засидели.



Поиск варианта с указанием цвета линии и координатами квадрата.



Поиски варианта самого удачного расположения пересадочного узла «Третьяковские» — «Новокузнецкая». Причина — не нравится, как желтая линия приходит в узел.



Выдержит ли схема нагрузку будущего строительства — нужно заранее все продумать.





Поиск эффекта для пересечения линий. Просто белым, просто пересекать, просто тень.

4. Начинаем программирование (наконец-то)

В настоящий момент времени для разработки используется Visual Studio 2015 и MVVM-фреймворк MVVM-light. К сожалению, XAML-файл, полученный на предыдущем этапе, напрямую в приложении использовать не получится, кроме статичного слоя с реками и маршрутами «аэроэкспрессов».

Поэтому еще немного работы вручную — и в ресурсах приложения формируем окончательный XML-файл, используемый для рендеринга схемы метро. При его загрузке формируются объекты линий метро, станций метро, формируются связи между станциями в пределах одной линии, переходы между линиями, «замыкаются» кольцевые линии. К слову, переходы между линиями формируются программно. Между двумя станциями — проводятся линии с градиентом заливки, между тремя станциями — строятся дуги окружности, построенной по трём точкам — центрам станций, из которых состоит переход.

Пример View-слоя, отвечающего за отрисовку дуг переходов между тремя станциями (для краткости удалены ресурсы, отвечающие за анимацию и пр.):


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

Для поиска необходимого вагона для удобного перехода на другую линию метро использовался следующий подход: у каждой линии установлено направление «вперед» и «назад». Соответственно, нам важно, с какой стороны мы подъехали к станции перехода, и иногда нам еще важно, в каком направлении мы поедем по той линии, на которую переходим.

Фрагмент XML-файла, описывающий станцию «Китай-город» Таганско-Краснопресненской линии и ее характерный переход на Калужско-Рижскую линию:

Перекрашиваем

Я выбрал цвета по умолчанию для станций как цвета их линий. Но что, если мы хотим перекрасить всё по произвольному градиенту? Это не так сложно как может показаться.

Мы имеем произвольный градиент от одного цвета к другому, который для удобства берём в каналах, значение станции (например, глубину заложения 23 метра) и максимальное и минимальное возможые значения (0 для наземных станций и 80 для самой глубокой «Парк Победы»). Посчитаем процентное соотношение значения станции к разности крайних значений и полученное отношение применим к разности значений по кажому каналу. Вот он наш цвет.

Остальные элементы на странице покрасим градиентом, у нас есть координаты и цвета станций — а это всё что нужно.

Читайте также: