Определение местоположения без GPS: как устроен Яндекс.Локатор. Улучшение точности определения…

Сейчас всё больше мобильных приложений становятся геозависимыми. Одни просто не имеют смысла без знаний о местоположении пользователя, другие становятся с ним удобнее. Это так называемые Location Based Services (LBS): навигаторы, форскверы, инстаграмы с геотегами фотографий и даже приложения-напоминалки, которые срабатывают около конкретного места, например, рядом с офисом или магазином.

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

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

Почему без GPS и как иначе

Спутниковые системы навигации (GNSS), в нашем случае это GPS и ГЛОНАСС, - самый точный на сегодняшний день метод геоопределения. Соответствующие модули есть практически во всех современных смартфонах. Но не всегда и не везде он может решить задачи LBS.

Во-первых, поиск спутников иногда занимает несколько минут, а бывают ситуации, в которых скорость определения важна даже с потерей точности. Например, когда нужно построить предварительный маршрут в навигаторе или зачекиниться . Во-вторых, спутники обычно не «видны» в помещениях или под землёй. В-третьих, GPS-модули есть не в каждом мобильном телефоне или планшете, и их почти нет в ноутбуках. То есть для LBS нужны альтернативы.

И альтернативы, конечно, есть - определять местоположение можно по ближайшим GSM-вышкам, сетям Wi-Fi и даже по IP-адресу. Точность определения у каждого из этих способов гораздо хуже, чем у GPS. Но если их скомбинировать, они вместе дадут приемлемое качество. При этом какие-то недостатки одного нейтрализуются возможностями другого. GSM-вышки есть практически везде, а Wi-Fi сети - нет. При этом по Wi-Fi точность определения лучше. Поэтому комбинированный способ по полноте и точности лучше, чем каждый в отдельности. Менее известен факт, что у двух роутеров в разных частях города может оказаться одинаковый MAC-адрес. Совмещение GSM и Wi-Fi решает такие коллизии. У этих роутеров, скорее всего, рядом будут находиться вышки с разными идентификаторами - ведь вероятность совпадения в пределах квартала гораздо меньше, чем в масштабах всего города.

В мире есть несколько реализаций такого комбинированного способа геоопределения. И кажется, первый вопрос, с которым сталкивались все разработчики, - где же взять информацию о местоположении сетей Wi-Fi и сотовых вышек?

База местоположений сетей

В дилемме «купить или создать» мы в конечном счёте предпочли второе. Основная причина - что с собственными данными и алгоритмами гораздо легче контролировать качество результата. В сборе информации нам помогли пользователи мобильных Яндекс.Карт.

Когда мы начинали разрабатывать Локатор, на улицах городов были уже сотни тысяч людей с включёнными в телефонах Яндекс.Картами. С согласия пользователя приложение постоянно передаёт его GPS-координаты - на основе этой информации строятся Яндекс.Пробки. Мы подумали, что вместе с этим приложение может отмечать, какой базовой станцией обслуживается телефон в этих координатах, какие видны сети Wi-Fi (при этом, конечно, к самим сетям не подключаясь - чтобы не создавать privacy-рисков).

Человеку для участия в таком краудсорсинге ничего специально делать не нужно - просто пользоваться приложением. Как и о координатах, данные об окружающих Wi-Fi сетях и станциях GSM обезличены. Они практически ничего не «весят», и батарейка от их передачи, соответственно, быстрее не садится.

Таким образом, пользователи стали помогать друг другу:


Одни, с GPS-приёмником в телефоне, узнают точное расположение сетей и передают информацию в Яндекс. Другие, у которых GPS-модулей нет, присылают список сетей, которые видят в данный момент, и получают в ответ своё примерное местоположение на карте.

База собрана и регулярно обновляется. И тут мы сталкиваемся со следующей проблемой.

«Переезд» сетей

Опыт показывает, что идентификаторы сотовых вышек постоянно меняются - номер, который вчера был в центре города, завтра может оказаться на окраине. Переезжать могут и Wi-Fi-роутеры - вместе со своими владельцами. И получается, что с каждым переездом нужно инвалидировать заметную часть данных.

Вот как нам удалось решить одновременно проблемы с переездом и вышек, и роутеров. От пользователя поступает запрос на определение местоположения вместе с данными о том, какие сети он видит. Если в списке сетей есть та, что была замечена в разных частях города, алгоритм учитывает, сколько сигналов от неё накоплено в каждом районе и возраст последнего. Каждое плотное скопление сигналов от Wi-Fi сети или сотовой вышки мы называем «облаком». Чем больше сигналов в облаке и чем они свежее, тем больше оно заслуживает доверия. Ответом будет, соответственно, самое большое и свежее. А облако, в котором нет сигналов больше месяца, мы считаем устаревшим - даже если для этой сети не появилось более свежего облака в другом районе.

Радиус облака

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

Чтобы ответ был предельно точным, радиус круга должен быть минимальным. Если просто обвести окружность вокруг всех точек сигналов конкретной сети, радиус получится слишком большим. Уменьшить его помогла мат. статистика. Плотность сигналов подвержена нормальному распределению, то есть применимо правило трёх сигм . В окрестность такого радиуса попадает 99,7% точек.

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

Необлачные сигналы

К сожалению, не все GPS-сигналы от пользователей просто скомпоновать в облака. Оказалось, что, если наложить на карту все сигналы отдельно взятой сети, помимо «эллипсов» на ней окажутся точки и линии. Это, соответственно, одиночные сигналы, сильно удалённые от скопления сигналов той же сети, и очень длинные GPS-треки (т.е. цепочки GPS-сигналов).

«Одиночки» появляются, например, когда человек передвигается на метро. Телефон теряет связь с сотой на одной станции, а при выходе на другой всё ещё считает, что обслуживается той сотой. Такие сигналы Локатор отфильтровывает. Кроме того, мы установили минимальный порог для облаков, чтобы не полагаться на слишком малочисленные скопления сигналов.

Длинные GPS-треки появляются, например, когда человек едет на машине через весь город. Телефон «тащит» за собой идентификатор вышки с начала маршрута и передаёт, что якобы видит её на всём пути. Известно, что у базовых станций ограниченный радиус действия, так что такие GPS-треки Локатор тоже отфильтровывает. Треки, длина которых укладывается в радиус действия вышки, остаются. Как правило, они заметны в районах, где мало данных. Там они становятся цепочкой небольших облаков.

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

Когда данных было накоплено мало, была ещё одна трудность с объединением всех сигналов в одно облако. Случалось что сигналы от вышки из одного города приходили также из другого. Помогло нам наличие в идентификаторах GSM-сетей кода зоны местоположения - LAC (Location Area Code). Поскольку вышки с одинаковым кодом должны по стандарту находиться рядом, облакам, которые оказались «не в своём городе» (т.е. среди облаков с другим LAC), Локатор стал придавать заниженный вес.

Улучшение точности определения…

…по GSM-сетям
Когда-то приложениям была доступна информация лишь об одной базовой станции, хоть телефон видит чаще всего несколько. После появления платформы Android приложения смогли научиться видеть их все (кроме подключения в стандарте 3G, который позволяет узнать только одну сотовую вышку). Местоположение стало определяться точнее - уже не по одному облаку, а по совокупности нескольких. Оказалось, что для множества облаков можно использовать тот же подход, что и для одного. Радиус считается по среднеквадратичному отклонению сигналов, входящих в совокупность облаков, а центр вычисляется по среднему их координат.
…по Wi-Fi-сетям
Когда смартфон находится в радиусе действия нескольких Wi-Fi-сетей, он может сообщить не только их список, но и мощность сигнала каждой. Знание об этой мощности мы и использовали для уточнения центра окружности, в которой находится пользователь. К центрам наблюдаемых облаков мы начали подвешивать воображаемые пружинки - тем туже, чем сильнее сигнал. А их свободные концы - соединять. Точка, в которой эти пружинки уравновешиваются, и есть уточнённый центр.

Получившееся качество

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

Используя эту методику, мы получили следующие цифры:

  • для 83% запросов в сутки местоположение определено правильно - GPS-координаты устройства попали в область, названную Локатором
  • 14% сигналов - с ошибкой:
    • 7% - ошибка меньше 100 метров
    • 5,6% - от 100 метров до нескольких километров
    • 1,4% - Локатор ошибается городом
  • оставшиеся 3% запросов получают ответ «Местоположение не найдено»


Можно ли добиться лучшего качества? Да. Преимущество метода в том, что при определённой зрелости алгоритмов достаточно лишь собирать больше данных, чтобы определять местоположение точнее. А это достаточно легко, потому что растёт и количество Wi-Fi сетей, и количество пользователей наших приложений.

Но есть технологические пределы:

  • если телефон сообщает только об одной GSM-вышке - минимальный радиус составит несколько сотен метров в городе, и несколько километров за городом
  • если телефон видит несколько вышек - центр можно определить точнее, но радиус уменьшить вряд ли получится
  • если видна Wi-Fi сеть - минимальный радиус будет 10 метров

Объёмы вычислений

Чтобы быстро отвечать пользователю, нужно заранее подготовить весь ответ или, хотя бы, существенную часть. Каждую ночь кластер на базе нашей системы распределённых вычислений YAMR агрегирует сигналы, полученные вплоть до вчерашнего дня, получая готовые для ответа «облака». В момент запроса Локатору остаётся только правильным образом их скомбинировать. Так терабайты «сырых сигналов» сжались до 1.5-2 ГБ готовых ответов, которые запросто помещаются в память. И подготовка ответа почти всегда укладывается в 1 мс, а каждый сервер в кластере выдерживает 10 тыс. RPS.

А чтобы продолжительность ежесуточного расчёта не росла линейно с ростом истории GPS-сигналов, мы добились «аддитивности» облаков. Теперь достаточно хранить лишь несколько показателей на каждое облако, и не нужно каждые сутки заново обрабатывать всю старую историю.

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

Аналоги

Сервисы определения местоположения без GPS, как мы уже говорили, есть не только у Яндекса. Разработчики могут обратиться к коммерческому поставщику (как, например, Altergeo в России и Skyhook Wireless в мире), либо использовать API мобильной платформы или браузера.

Вообще собрать такую базу можно тремя способами:

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

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

WARNING

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

INTRO

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

Юзкейс 1. «Я тебя вычислю по IP»

Допустим, в твоем блоге завелся тролль, который регулярно оставляет грубые комменты. Если ты собираешь инфу о посетителях Яндекс.Локатором, то без труда выяснишь, что этот кто-то находится на восточном конце улицы Ленина, в котором как раз живет один неприятный тип из твоего универа. И если повезет, то, сделав запрос к Vkontakte API, ты найдешь его последнюю фотку.

Юзкейс 2. Геомаркетинг

Яндекс.Директ уже давно применяет прицельный геотаргетинг для своих объявлений. Объявление «Сеть пиццерий в Москве» сознание игнорирует. А мимо ссылки «Пицца Рочдельская улица дом 14» (через дорогу от тебя) пройти практически невозможно.
Ты можешь использовать геоданные для продвижения товаров и услуг. Если человек в данный момент ощущает на себе действие пониженного атмосферного давления, то есть вероятность, что ему захочется купить таблетки для поднятия жизненного тонуса.

Юзкейс 3. Веселый функционал

Здесь огромный простор для творчества. Ставим на сайт «ночную» тему оформления после того, как у юзера заходит солнце. Показываем ему последние селфи девушек, сделанные в 10 км от него. По климату и глубине водоемов определяем, какая рыба водится в округе. Вариантов масса.

Юзкейс 4. «Научные» исследования аудитории

Результаты анонимного онлайн-опроса могут оказаться существенно полезнее, если в дополнение к ответам отмечать географическое положение респондентов.

Интересно? Тогда вперед.

Получение координат

GPS-данные можно получить с помощью JavaScript и HTML5 Geolocation API. Но учти: узнать точное местоположение пользователя можно только с его согласия. Он должен выразить его, ответив утвердительно на вопрос всплывающего окна, разрешить ли текущему сайту узнать его местоположение.

Пример кода на нативном JS:

// Кладем в переменную адрес

для вывода текста var posText = document.getElementById("positionText"); function getLocation() { if (navigator.geolocation) { // Если пользователь разрешил, определяем его местоположение и обрабатываем полученное значение с помощью функции ShowPosition navigator.geolocation.getCurrentPosition(showPosition); } else { // Если нет, выводим сообщение об ошибке posText.innerHTML = "Этот браузер не может определять местоположение"; } } function showPosition(position) { // Выводим широту и долготу на страницу posText.innerHTML = "Широта: " + position.coords.latitude + "
Долгота: " + position.coords.longitude; }

Яндекс.Локатор

Если пользователь не хочет добровольно делиться GPS-инфой, то еще не все потеряно. Есть крутой инструмент Яндекс.Локатор. Средняя точность определения составляет 300 м. Он вычисляет, где находится человек, по следующей информации:

  • сигналам сети мобильной связи;
  • сигналам сетей доступа Wi-Fi;
  • IP-адресу мобильного устройства.

Внедряется в проект в разы сложнее, чем HTML5 Geolocation API. Перед отправкой запроса к Яндекс.Локатор API сайт или мобильное приложение должно получить access key и выяснить много подробностей о пользователе. Если посетитель сидит в инете через мобильную связь, то надо знать ID сотовой ячейки и силу сигнала, если через Wi-Fi - силу сигнала и MAC-адрес точки доступа.

За точными инструкциями отсылаем тебя к руководству разработчика .

Exif-данные фотографий

Найти GPS-координаты можно и в метаданных снимков, сделанных цифровой камерой. Информацию о фотках можно читать без согласия пользователя. Надо только заставить его их загрузить. Дальше на помощь приходит библиотека exif-js или серверные инструменты для чтения exif-data:

  • в PHP есть встроенная функция read_exif_data();
  • для Ruby есть библиотека exifr ;
  • у Python есть Package ExifRead 2.0 ;
  • для С++ - easyexif .

База GeoIP

Можно попробовать найти IP-адрес пользователя в базе GeoIP, но это чистой воды хиромантия. Дорогая и устаревшая. По моему опыту, эта база полна неточностей и доверять ей нельзя. Да и процент использующих VPN довольно значителен.

Составляем досье

Получив в руки географические координаты, приступим к сбору информации. Для каждого пункта будем делать запрос с параметрами к одному из API и парсить возвращаемый XML/JSON-ответ.

Для начала узнаем адрес пользователя с точностью до улицы.

Узнаем адрес пользователя

Это можно сделать Яндекс.Геокодером (с ним можно работать без предварительной OAuth-авторизации).

Синтаксис запроса:

Http://geocode-maps.yandex.ru/1.x/?geocode=36.3630,56.0000

Все просто. Запросу передается два параметра: широта (56.0000) и долгота (36.3630).

Сервер выдаст ответ в формате XML (см. скрин). Нас интересуют следующие поля:

  • AdressDetails->Country->AdressLine - текстовая строка с полным адресом пользователя;
  • AdressDetails->Country->СountryName - страна;
  • AdressDetails->AdministrativeArea->AdministrativeAreaName - регион;
  • AdressDetails->SubAdministrativeArea->SubAdministrativeAreaName - район;
  • AdressDetails->Locality->LocalityName - населенный пункт;
  • AdressDetails->ThoroughFare->ThoroughFareName - улица.

Адрес с номером дома Яндекс.Геокодер не раскрывает. Но если немного напрячь мозги и вспомнить школьную программу, то можно вычислить его. В одном градусе широты 111 км 111 м. С долготой все чуть-чуть сложнее. Ведь диаметр Земли варьируется в зависимости от широты. Поэтому долгота рассчитывается по следующей формуле (6371 - это радиус Земли):

6371 * (Math::PI/180) * cos(широта * Math::PI/180)

Как эти знания помогут вычислить точный адрес пользователя? А вот как:

  1. Узнаем улицу с помощью Яндекс.Геокодера.
  2. Отправляем запрос на получение точных географических координат какого-нибудь дома на этой улице:
    http://geocode-maps.yandex.ru/1.x/?geocode=пермь, улица Яблочкова,2
  3. Считываем значение из ответа сервера.
  4. Зная длину градуса широты и долготы, рассчитываем расстояние от искомой точки до этого дома.
  5. Открываем Яндекс.Карты и линейкой прикидываем, какой дом имеет географические координаты пользователя.

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

Google Street View

Координаты можно найти на Google Maps и включить режим просмотра улиц. Забавно посмотреть на дом или офис человека, который нагло критикует в твоем блоге фотки свежего ремонта дачи.

Фотографии вокруг

Теперь поищем фотографии, сделанные рядом с местом Х. Как это делается, разберем на примере ВКонтакте API:

Https://api.vk.com/method/photos.search.xml?lat=38.600000&long=35&count=100&radius=500

  • lat - широта;
  • long - долгота;
  • count - количество возвращаемых запросом фотографий;
  • radius - радиус окружности вокруг заданной точки, в которой должны быть сделаны фотографии.

Вот какие поля ответа нас интересуют:

  • src, src_big - ссылки на фотографии;
  • created - дата создания фотографии в unixtimestamp;
  • owner_id - ID владельца фотографии.

Зная ID владельца, можно зайти на его страницу или собрать инфу с помощью того же VK API:

Https://api.vk.com/method/getProfiles.xml?uids=111111&fields=last_name,first_name,sex,age

  • uids - ID владельцев через запятую;
  • fields - поля, которые мы хотим получить в ответе.

Полный список полей

«Яндекс» объявил об открытии программного интерфейса (API) своего сервиса геопозиционирования «Яндекс.Локатор». API стал доступен сторонним разработчикам в режиме тестирования 25 февраля 2011 г. Из тестовой стадии проект может выйти «через несколько месяцев».

Согласно сообщению «Яндекса», API позволяет определять местоположение мобильных телефонов или ноутбуков, не имеющих собственного приемника GPS, что открывает разработчикам возможности создания сервисов и приложений, основанных на идее геопозиционирования. В качестве примеров таких программ в «Яндексе» приводят добавление геотега к фотографиям или сообщениям, публикуемым в соцсетях или в Twitter.

Работа географического API «Яндекса», подобно аналогичным решениям, основана на использовании данных о положении близлежащих базовых станций сотовой связи и точек доступа Wi-Fi.

Инструмент, по словам руководителя отдела разработки мобильных сервисов «Яндекса» Олега Герасимова, сейчас используется в нескольких собственных продуктах поисковика (в мобильных «Яндекс.Картах», мобильном «Яндексе» и в «Яндекс.Баре» для Firefox и Internet Explorer). Сторонних проектов, основанных на географическом API «Яндекса», пока не существует, однако, когда они появятся, «Яндекс» сможет добавить к своим знаниям о местоположении пользователей «Яндекс.Карт» аудиторию пользователей сторонних приложений.

В пользовательском соглашении «Яндекс» предупреждает пользователей API — разработчиков приложений, что «условием использования сервиса в мобильных приложениях является передача GPS-треков (данных о передвижениях пользователя)» «Яндексу». Если приложение делает более 1 тыс. запросов в сутки, это условие становится обязанностью его разработчика.

В «Руководстве разработчика» для «Локатора» «Яндекс» называет самой точной методикой позиционирование по сигналам точек доступа Wi-Fi. В этом случае положение мобильного устройства может быть определено с точностью до 150 метров.

В том же документе отмечено, что позиционирование с помощью базовых станций сотовой связи зависит от их плотности: в центре городов, где они расположены с максимальной плотностью, она может составлять 200-500 метров, на окраинах — 1,5-2 тыс. метров.

Интересно, что в 2010 г. конкурент «Яндекса» Google был замечен в чрезмерно вольном отношении к чужим Wi-Fi сетям, когда в нескольких странах Азии, Америки и Европы автомобили Google Street View были пойманы за сбором трафика открытых беспроводных сетей.

Олег Герасимов пояснил CNews, что, в отличие от «Яндекса», который в своем геоинструментарии использует только идентификатор точки доступа, Google сканировал всю информацию, передаваемую по открытым сетям, чего «Яндекс» делать не собирается. Хотя большинство частных сетей используют протоколы шифрования, тем не менее, их идентификаторы передаются в открытом режиме, чего вполне достаточно для целей позиционирования, говорят в «Яндексе».

Средства позиционирования, аналогичные яндексовскому, имеют его прямые конкуренты Google и Mail.ru. Сервис Google Latitude (локализованный в России как «Google Локатор») имеет открытый API и широко применяется в различных веб-сервисах и приложениях.