На чем написаны яндекс карты

Как устроены Яндекс.Карты. Лекция Владимира Зайцева в Яндексе

Яндекс.Карты – это высоконагруженный картографический портал, который работает с огромными объемами данных. В своей лекции Владимир Зайцев рассказывает старшеклассникам – студентам Малого ШАДа – о том, как создавать и поддерживать такие ресурсы, и о технологиях, которые для этого используются. А также на примерах объясняет, какие можно разрабатывать инструменты и проводить исследования на базе полученных данных.

Спутниковые снимки и карта

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

Но если применять этот метод для составления более масштабных карт, процесс окажется слишком длительным и трудоемким. Поэтому сегодня для этих целей применяются более технологичные решения. Например спутниковая фотосъемка. Спутники летают над Землей на высоте 200-500 километров и делают фотоснимки при помощи вот таких объективов:

На чем написаны яндекс карты. Смотреть фото На чем написаны яндекс карты. Смотреть картинку На чем написаны яндекс карты. Картинка про На чем написаны яндекс карты. Фото На чем написаны яндекс карты

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

Но есть две проблемы. Во-первых пролеты над какими-то территориями обязательно придутся на ночное время. А ночные спутниковые снимки представляют исключительно эстетическую ценность, для картографии они бессмысленны. Это обязательно нужно учитывать, и снимать только освещенные части, что может потребовать большего количества пролетов. Вторая проблема – это облачность. Если часть города при съемке закрывают облака, то нам потребуется при следующем пролете спутника над ним снимать эту часть заново. Но если в следущий раз спутник полетит над этим городом в другое время, тени будут направлены в совершенно другую сторону. И если мы совместим два снимка, у нас будет ощущение диссонанса. Поэтому такие спутники летают по солнечно-синхронной орбите, рассчитанной таким образом, чтобы каждый пролет спутника над определенной местностью приходился на одно и то же локальное время.

Итак мы произвели фотосъемку, склеили фотографии, получили одно большое полотно в высоком разрешении. Но съемка производилась с какой-то одной точки, так что некоторые углы у нас будут искажаться. Чтобы скомпенсировать искажения нужно всю картинку перепроецировать. Сделать так, будто каждая фотография была сделана именно над этой точкой.

Есть и еще одна проблема спутниковой съемки. Мы ведь хотим получить цветные фотографии, но при проходе через атмосферу световые лучи разного спектра преломляются по-разному. Поэтому цветной снимок высокого разрешения из космоса сделать не получается. Делается по два снимка. Один – черно-белый, высокого разрешения, а второй меньшего разрешения, но цветной. Затем цветной снимок растягивают и накладывают как текстуру на черно-белый. Это становится заметно, когда в кадр попадают быстродвижущиеся объекты, например, самолеты.

На чем написаны яндекс карты. Смотреть фото На чем написаны яндекс карты. Смотреть картинку На чем написаны яндекс карты. Картинка про На чем написаны яндекс карты. Фото На чем написаны яндекс карты

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

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

На чем написаны яндекс карты. Смотреть фото На чем написаны яндекс карты. Смотреть картинку На чем написаны яндекс карты. Картинка про На чем написаны яндекс карты. Фото На чем написаны яндекс карты

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

На чем написаны яндекс карты. Смотреть фото На чем написаны яндекс карты. Смотреть картинку На чем написаны яндекс карты. Картинка про На чем написаны яндекс карты. Фото На чем написаны яндекс карты

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

На чем написаны яндекс карты. Смотреть фото На чем написаны яндекс карты. Смотреть картинку На чем написаны яндекс карты. Картинка про На чем написаны яндекс карты. Фото На чем написаны яндекс карты

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

На чем написаны яндекс карты. Смотреть фото На чем написаны яндекс карты. Смотреть картинку На чем написаны яндекс карты. Картинка про На чем написаны яндекс карты. Фото На чем написаны яндекс карты

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

Еще один момент, который нужно учитывать при выборе цветовой палитры заключается в том, что карты часто печатают на черно-белых принтерах, и монохромная карта тоже должна оставаться читаемой:

На чем написаны яндекс карты. Смотреть фото На чем написаны яндекс карты. Смотреть картинку На чем написаны яндекс карты. Картинка про На чем написаны яндекс карты. Фото На чем написаны яндекс карты

Народная карта

Пробки

Подробно о том, как работают Яндекс.Пробки уже рассказывал в своей лекции Леонид Медников, ну а общее представление можно составить из этой картинки:

На чем написаны яндекс карты. Смотреть фото На чем написаны яндекс карты. Смотреть картинку На чем написаны яндекс карты. Картинка про На чем написаны яндекс карты. Фото На чем написаны яндекс карты

Досмотрев лекцию до конца, вы узнаете, как устроены не менее интересные компоненты Яндекс.Карт: маршрутизация, Панорамы и API.

Источник

На каких языках программирования пишут в Яндексе

«Когда-то давно, семь с лишним лет назад, я пришёл на собеседование в Яндекс. Собеседовали по С++, взяли.
Первый день. Самокатная, шумная столовая кислотных расцветок, обед. Суп из пластмассовых прямоугольных параллелепипедов.
— Хочешь писать на С++? — спрашивают меня.
— Нет, — говорю, — не хочу.
— Ну ок, учи Perl.
С тех пор я пишу на Perl и нежно его люблю».

Такую историю рассказал нам разработчик Яндекса, когда мы готовили эту публикацию и проводили опрос. Мы спрашивали у наших разработчиков, на чём они пишут, чтобы выяснить — какие языки программирования в Яндексе самые популярные. В опросе приняли участие больше половины разработчиков компании, расклад получился такой:

Многие разработчики используют в работе несколько языков, поэтому мы просили их выбрать один — тот, на котором они пишут больше всего. В лидерах оказались пять языков: C++, JavaScript, Java, Python и Perl. Все эти языки разные, и каждый лучше решает свою задачу. Поэтому они по-разному используются в Яндексе.

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

На JavaScript в основном пишут интерактивные элементы сайтов, такие как анимация или браузерные игры. Этот язык очень широко используется в браузерах для написания интерфейсов — того, с чем напрямую взаимодействуют пользователи. На JavaScript написаны веб-интерфейсы всех сервисов Яндекса.

Java — это универсальный язык, на котором можно написать любое приложение, будь то игра Flappy Bird или веб-сервер, обрабатывающий миллионы запросов в минуту. Несмотря на название имеет мало общего с JavaScript. Разработка на нём пойдёт быстрее, чем на C++, однако программа может получиться чуть медленнее. Особенности Java позволяют создавать программы, которые работают практически на любом устройстве — от телефона до микроволновки. На Java у нас написаны, например, Маркет и Музыка.

Python — это дружелюбный к программисту язык с простым синтаксисом. С него хорошо начинать изучение программирования. У нас Python широко используется в системном администрировании, но подходит для решения почти любых задач, кроме обработки больших объёмов данных. На Python многое делать проще и быстрее, чем на C++, но программа будет не такой производительной. Это разумный выбор, когда производительность не очень важна или задачу нужно сделать быстро. На Python написана серверная часть Диска, а ещё он используется в Директе, внутренних сервисах и многих других проектах.

Perl был создан для обработки текстов — например, для извлечения фактов из текста. Талисман языка — верблюд, лишённый изящества, но выносливый и эффективный, — точно отражает его особенности. Это лаконичный, но непростой язык, который, однако, хорошо решает свою задачу. В Яндексе его используют, например, для анализа данных в баннерной системе и в разработке серверной части некоторых сервисов — например, Директа.

С точки зрения задачи выбор языка — это поиск равновесия между эффективностью программы, квалификацией программиста и временем, потраченным на работу. Конечно, в реальности всё немного сложнее, поэтому иногда и случаются истории вроде той, с которой мы начали. «Шёл на вакансию C++, взяли на Perl, пишу на Python, а люблю Scala», — такое тоже бывает.

С точки зрения разработчика, выбор языка — это вопрос предпочтений. Кому-то действительно нравится сам язык, кому-то — задачи, которые он решает. Например, одни предпочитают фундаментальные задачи и пишут базу поиска на C++, а другие любят делать то, что видно пользователям, и пишут интерфейсы на JavaScript. Третьи пишут на каком-то языке просто потому, что знают его досконально. А некоторые, наоборот, готовы пробовать новое и участвуют в разных проектах.

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

Источник

На чем написаны яндекс карты

Как быстро отрисовать 10000 меток на карте и не затормозить всё вокруг. Как и зачем мы делали ObjectManager — читайте в новой статье на Хабрахабре. Автор статьи — создатель модуля и руководитель группы разработки визуальных компонент API Карт, Марина Степанова.

Перед разработчикам, которые используют API Яндекс.Карт, довольно часто встаёт задача отобразить много объектов на карте. Действительно много — порядка 10 000. Причем эта задача актуальна и для нас самих — попробуйте поискать аптеки на Яндексе. На первый взгляд кажется: «А в чем собственно проблема? Бери да показывай». Но пока не начнешь этим заниматься, не поймешь, что проблем на самом деле целый вагон.

Вопросы по большому количеству меток с завидной регулярностью поступают в наш клуб и техподдержку. Кто все эти люди? Кому может быть интересно показать на карте больше 10 меток? В этом посте я подробно рассмотрю весь вагон проблем и расскажу, как в API появились инструменты, помогающие разработчикам оптимально показать большое количество объектов на карте.

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

Также от большого количества данных страдают ресурсы, посвященные недвижимости. Яркий пример – Cian.ru.

Мы сами внутри Яндекса до недавнего времени советовали смежным командам различные «хаки» и приемы для показа множества точек через API. Яркие примеры – Яндекс.Недвижимость и Яндекс.Такси.

Пункт 1. В чем собственно проблема?

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

Клиент (например, Safari на iPhone) запрашивает с сервера страницу index.html. Страница представляет собой документ вот с таким кодом:

Теперь усложняем задачу. У нас есть база данных, в которой хранятся адреса болельщиков «Зенита». И мы хотим показать на карте адреса этих болельщиков.

Решение задачи «в лоб»:

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

Мысль получает два направления:

В API Яндекс.Карт сто лет назад был сделан инструмент для решения этих задач – технология активных областей. Кому интересно подробно, почитайте руководство разработчика.

Кратко – вы генерируете на сервере прозрачные картинки с метками плюс текстовое описание меток. Клиент может следить за видимой областью карты и запрашивать данные, которые нужны для текущей видимой области карты.

С помощью хотспотов, например, рисуются пробки на maps.yandex.ru. На этой же технологии сделан сайт bankomator.ru.

У этой технологии есть несколько существенных минусов

1. Очень сложная серверная часть. Попробуйте на досуге написать модуль, который генерирует вот такие картинки и их геометрические описания, и вы все поймете.

2. Абсолютная негибкость. Невозможно «приподнять» метку при наведении на нее курсора. Невозможно быстро поменять на клиенте внешний вид меток. Короче – на любой чих надо просить сервер перегенерировать картинку.

Поэтому пользователи крутились, как могли, без хотспотов – передавали наборы единичных объектов на клиент пачками, через таймаут. При этом на клиенте их снова ждали проблемы. Если вы передали на клиент 1000 точек, как их отрисовать?

Из каждой точки нужно было сгенерировать объект ymaps.Placemark и добавить его на карту. Можно было добавить метки в кластеризатор (ymaps.Clusterer) и добавить откластеризованные метки на карту. Тут надо обратить внимание, что при кластеризации 10 000 точек нужно сначала эти 10 000 точек инстанцировать, а потом передать в кластеризатор. То есть метка может не показаться на карте, так как войдет в кластер, но мы все равно потратим время на ее инициализацию.

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

И мы это сделали. Мы котики.

Пункт 2. Рисуем метки быстро

Чтобы научиться рисовать метки быстро, надо было понять, какие проблемы кроются в текущем, уже существующем решении. Давайте посмотрим, что может делать объект ymaps.Placemark :

Кроме того, метка динамически реагирует на любое изменение внешней среды – изменение опций, данных, проекции карты, смена масштаба карты, смена центра карты и многое, многое другое. Такие вот у нас могучие плейсмарки.

А нужна ли вся эта программная мощь для случая, когда разработчику просто нужно показать много однотипных меток на карте? Правильно, не нужна.

Поэтому первое озарение заключалось в следующем: а давайте вынесем все вспомогательные модули меток в один общий компонент и для каждого отдельного объекта будем создавать только программную сущность, которая непосредственно отвечает за отрисовку.

Второе озарение пришло, когда мы думали над проблемой лишних программных инициализаций. Вспоминаем рассказ выше, где-то в районе вот такой картинки.

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

Мы решили, что будем хранить пользовательские данные об объектах (по факту в JSON), а программные сущности для объектов будут создаваться только тогда, когда какой-либо объект нужно будет отрисовать на карте.

После комбинации этих идей и некоторой разработки родился новый модуль API для отображения большого количества точечных объектов – ymaps.ObjectManager.

На вход этого менеджера скармливается JSON-описание объектов.

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

Для отрисовки меток и кластеров на карте мы взяли только часть объекта ymaps.Placemark (а именно ymaps.overlay.*), которая отвечала только за отображение метки на карте. Всю инфраструктуру типа балунов и хинтов мы вынесли в единый общий компонент.

Эти приемы позволили нам неплохо продвинуться в вопросе отрисовки большого числа меток на клиенте. Вот какие мы получили приросты по скорости:

График 1. Скорость создания и добавления объектов на карту с последующей асинхронной отрисовкой их видимой части

График 2. Скорость создания и добавления объектов на карту с последующей синхронной отрисовкой их видимой части

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

У нас получилось ускорить непосредственно создание и отрисовку объектов, вдобавок к этому мы максимально оптимизировали инициализацию программных сущностей. Теперь вы можете, например, откластеризовать на клиенте 50 000 точек, и работать с картой будет комфортно.

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

Итак, мы научились быстро-быстро рисовать и кластеризовать точки на клиенте. Что дальше?

Пункт 3. Оптимально подгружаем данные

Помните пример про болельщиков «Зенита»? Мы решили проблему отрисовки данных на клиенте, но никак не решили проблему, связанную с оптимальной подгрузкой этих данных. Мы начали собирать типовые задачи пользователей API. По итогам исследований мы получили два типовых кейса:

Для решения этих кейсов были написаны модули LoadingObjectManager и RemoteObjectManager соответственно.Оба модуля основаны по сути на реализации ObjectManager, но имеют ряд различий в алгоритме загрузки и кеширования загруженных данных.

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

Данные хранятся на клиенте в pr-дереве, поэтому выборки даже для большого количества данных делаются довольно шустро.

Теперь обсудим вариант номер два – отображение на клиенте результатов серверной кластеризации. Допустим, вы написали серверную кластеризацию меток. Также вы написали скрипт, который по запросу от клиента умеет отдавать кластеры и единичные метки, не вошедшие в состав кластера.

Вам остается только создать инстанцию RemoteObjectManager и прописать в нем путь до этого чудо-скрипта. RemoteObjectManager будет работать почти так же, как и LoadingObjectManager. Разница будет только в том, что мы будем перезапрашивать данные с сервера при каждой смене зума.

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

Если с сервера передается описание метки-кластера, то на клиенте эти метки подцепят всю инфраструктуру из API – для кластеров нарисуются специальные значки, для них будут работать все стандартные поведения и так далее и тому подобное.

Пункт 4. Размышления на тему серверной реализации

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

1. Хранение информации об объектах на сервере в статических файлах

Клиентский код оперирует данными исключительно потайлово. Тайл – это некоторая нумерованная область на карте. Подробнее про нумерацию тайлов можно прочитать в нашей документации.

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

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

zoom=0, tile=[0, 0]
zoom=1, tile=[0, 0]
zoom=1, tile=[0, 1]
zoom=1, tile=[1, 0]
zoom=1, tile=[1, 1]
zoom=2, tile=[0, 0]

Поскольку запросы известны заранее, ответы на запросы тоже можно сгенерировать заранее. Организуем на сервере какую-то такую файловую структуру.

В файлах будет храниться примерно такой код:

При загрузке такого файла на клиенте будет вызван JSONP-callback, прописанный в файле. Данные попадут в недры LoadingObjectManager, закешируются и отрисуются в нужном виде.

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

2. Динамическое формирование ответа из статических файлов

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

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

3. Динамическое формирование ответа с использованием базы данных

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

Вообще хранение геопривязанных данных на сервере и их кластеризация – тема отдельной беседы. Так что обсудим в другой раз.

В этом репозитории живет пример реализации серверной части с серверной grid-кластеризацией, написанный на node.js + mongo.db. может кому-то пригодится (Демо).

Заключение

Сравнительная таблица новых модулей.

МодульПреимуществаНедостатки
ObjectManagerПозволяет кластеризовать объекты на клиенте.

Отрисовка производится только тех объектов, которые попадают в видимую область карты.

Позволяет фильтровать объекты при их отображении.

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

Поддерживает работу только с метками.

Данные загружаются для всех объектов сразу (даже для тех, которые не попадают в видимую область карты).

Кластеризация объектов производится на стороне клиента.

LoadingObjectManagerПозволяет кластеризовать объекты на клиенте.
Загружает данные только для видимой области карты.

Сохраняет загруженные данные. Для каждого объекта данные загружаются только один раз.

Позволяет фильтровать объекты при их отображении.

Поддерживает работу только с метками.

Кластеризация объектов производится на стороне клиента.

Необходимо реализовать серверную часть.

RemoteObjectManagerИспользует серверную кластеризацию данных.

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

Поддерживает работу только с метками.

При изменении коэффициента масштабирования данные загружаются заново (даже для тех объектов, для которых данные уже были загружены).

Необходимо реализовывать собственную кластеризацию.

Необходимо реализовать серверную часть.

На данный момент мы поддерживаем работу только с точечными объектами. Поддержка полигонов, полилиний и прочих прекрасных фигур стоит у нас в планах и появится в будущих релизах.

Когда стоит задуматься об использовании этих модулей? Почти в любой ситуации, когда вам надо отрисовать на карте много точечных объектов.

Источник

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

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