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

Спору нет, GPS — классная штука, но что делать, если приемника под рукой нет?
Далеко не у каждого есть встроенный чип в мобиле. Да и владелец автомобиля
совсем не обязательно успел обзавестись устройством навигации. Так как же быть?
Если не брать в расчет редкие и экзотические варианты, то основных способа три:

  1. Определить IP и с помощью специальной базы данных определить город, в
    котором находишься, и нередко — долготу и широту.
  2. Определить расположение по находящимся рядом базовым станциям GSM/UMTS.
    Это возможно при наличии базы данных с идентификаторами вышек и их
    координатами.
  3. Использовать для вычисления широты и долготы информацию о находящихся
    рядом точках доступа Wi-Fi, передав запрос с их характеристиками на
    специальный сервер.

Итак, начнем с самого простого.

 

IP нам в помощь

Когда мне нужно проверить свой внешний IP, чтобы убедиться, например, что я
включил VPN или прокси, я всегда использую сервис
ip2location.com.
Приятно, что помимо самого IP-адреса выводится информация о провайдере, его
месторасположении (город, страна, штат), а зачастую… еще и координаты. Само
собой, в базе не будут указаны широта и долгота для самого обычного клиента
интернет-услуг. Как правило, данные указываются для провайдера, реже — для
крупных компаний, имеющих большие диапазоны статических IP. Получается, что,
подключившись к сети (например, через любой открытый hotspot или просто
воспользовавшись компьютером), можно с большой долей вероятности определить
примерное место, где ты находишься. Конечно, способ примитивный — и более того,
самый неточный из всех представленных в этой статье. С другой стороны, это
реальный шанс определить месторасположение, всего лишь открыв страничку в
интернете. А если сварганить специальный трекер, установить его на КПК и
отслеживать IP-шники, которые он получает при коннекте к открытым WiFi-сетям, то
реально вычислить передвижения девайса.

Использовать сервис в чистом виде, а именно – переходя браузером по ссылке
ip2location.com, скучно
и беспонтово. Месторасположение на карте не увидеть, лог не сохранить, а сама
страница слишком тяжелая для мобильного инета — короче, это не наш путь. От
сервиса нам нужно только одно — база соответствий разных IP-адресов их
расположению, которую ip2location предлагает приобрести за довольно разумные
деньги. Само собой, подобные базы быстро расплываются по варезным порталам и
торрентам, причем в двух вариантах: .cvs (текстовом) и .bin (бинарном). С такой
базой несложно заточить любое приложение под себя. Правда, IP-адрес в базе
хранится в специальном цифровом виде без точек и разделения на октеты, но
следующая PHP-функция поможет привести обычный IP-шник к нужному виду:

function Dot2LongIP ($IPaddr)
{
if ($IPaddr == "") {
return 0;
} else {
$ips = split ("\.", "$IPaddr");
return ($ips[3] + $ips[2] * 256 + $ips[1] * 256 * 256 + $ips[0] * 256 * 256 *
256);
}
}

Имея такой ключ для адреса, ничего не стоит найти соответствующие ему
координаты в текстовой базе. Если же в распоряжении будет база в BIN-формате, то
задача еще проще. Для Perl, C, Python, PHP, Ruby, C#, VB.NET, Java, Visual Basic
сервисом подготовлены готовые модули (http://www.ip2location.com/developers.aspx),
которые легко использовать в своем проекте. В случае с PHP достаточно закинуть
на сайт модуль IP2Location.inc.php и создать несложный скриптик:

<?php
include("IP2Location.inc.php");
$ip = IP2Location_open("samples/IP-COUNTRY-SAMPLE.BIN", IP2LOCATION_STANDARD);
$record = IP2Location_get_all($ip, "_IP-АДРЕС_");
echo "$record->country_long : " . $record->country_long;
echo "$record->city : " . $record->city;
echo "$record->isp : " . $record->isp;
echo "$record->latitude : " . $record->latitude;
echo "$record->longitude : " . $record->longitude;
IP2Location_close($ip);
?>

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


http://maps.google.com/maps?f=l&hl=en&q=’+query+’&near=’+str(lat)+’,’+str(lng)+’&ie=UTF8&z=12&om=1

 

Используем мобильные вышки!

Старая байка о том, что спецслужбы могут найти человека по сигналу от его
мобильника — один из тех случаях, когда на самом деле все так и есть. Да чего
там спецслужбы, если на это способна даже совершенно бесплатная программа Google
Maps (www.google.com/gmm).

По сути, это удобная оболочка для доступа к одноименному веб-сервису,
позволяющему смотреть фотографии местности со спутника, рельеф и – во многих
случаях – карты с возможностью проложить маршруты. Думаю, рассмотреть крышу
своего дома через maps.google.com пробовали все. Работать с таким сайтом через
браузер на мобильном телефоне (даже если это сверхскоростная Opera Mini) крайне
сложно, поэтому в Google, подсуетившись, сделали удобную оболочку для просмотра
карт. Оформили ее в виде приложения для самых разных платформ – от обычных
мобильных, поддерживающих Java, до смартфонов и коммуникаторов на Windows Mobile
и Symbian S60 3rd Edition, престижных BlackBerry, а теперь еще и Android, к
которой мы пока не привыкли, но очень скоро будем воспринимать как одну из
основных платформ для телефона. В том же iPhone Google Maps встроена по
умолчанию. Так вот, помимо удобного просмотра этих самых карт и спутниковых
снимков, у утилиты есть одна замечательная кнопка «Мое месторасположение». Один
клик — и на карте отмечается нахождение телефона. Да, для владельцев трубок с
GPS это сущая ерунда: нашли чем удивить! Но надо видеть лица тех пользователей,
которые видят на экране свое месторасположение, хотя никаких навигационных
приблуд у них не было и в помине! Впрочем, это только так кажется.

Телефонная трубка всегда находится в зоне действия, по меньшей мере, одной
базовой станции сотовой сети. Ну, или не находится — но в этом случае от нее
толку не более чем от кирпичика. Любая из базовых станций имеет некоторый набор
параметров, которые получает телефон — благодаря этому каждую БС можно
распознать. Один из таких параметров – CellID (сокращенно CID) — уникальный
номер для каждой соты, выданный оператором. Зная его, ты можешь распознать
базовую станцию, а зная расположение базовой станции, можешь, понять где
находишься. Точность варьируется от нескольких сотен метров и до нескольких
километров, но это неплохая отправная точка, чтобы разобраться с координатами.

Получается, имея в наличии табличку, где в соответствии с каждой базовой
станцией будет сопоставлены ее координаты, можно примерно вычислить положение
абонента. А раз Google Maps может так лихо определять месторасположение
человека, то у него такая база данных есть. Но откуда? Расположение базовых
станцией различных операторов – пускай и не секретная, но вряд ли открытая
информация. Даже учитывая масштабность проектов Гугла, с трудом можно поверить,
что тот договорился со всеми операторами сотовой связи — определение
местоположения работает в любом месте (забегая вперед, скажу, что правильнее
говорить «может работать в любом месте»). Ответ скрывается в лицензионном
соглашении во время установки программы, на который мы, конечно же, забили и
сразу нажали «Я согласен» :). А ведь там черным по белому написано, что,
принимая соглашение, мы разрешаем программе анонимно передавать на сервер
информацию о текущем расположении и информации о сотовых вышках поблизости. Да!
Базу данных с примерными координатами базовых станций составляют для Google сами
пользователи Google Maps, имеющие на борту своих телефонов и коммуникаторов
встроенный приемник GPS. И что самое классное: даже при полном отказе от
использования как официальных, так и неофициальных (собранных энтузиастами с
помощью специальных сканнеров — подробнее читай во врезке) баз с расположением
станций, функция для определения месторасположения работает на «ура». Проверь
сам.

 

GSM-навигация своими руками

Возможность посмотреть в программе свое расположение — само по себе здорово,
но разве ж можно отказаться от соблазна использовать базы Google’а в корыстных
целях? Как тебе, например, идея создать собственный трекер, который определял бы
текущее расположение БС и передавал его на наш сервер? Эдакий жучок средствами
самого телефона, который работает везде и всегда!

Компания не разглашает протокол взаимодействия Google Maps, не публикуя API,
однако его легко вскрыли, просто проснифав трафик и реверснув часть кода. Помимо
http-запросов на загрузку карт, отчетливо видно, что программа отправляет
запросы по адресу
http://www.google.com/glm/mmap
, причем именно тогда, когда пользователь
желает получить текущее месторасположение. Вот и попался наш скриптик – в
качестве параметров ему передаются технические значения базовой станции: MCC,
MNC, LAC и CellID.

MCC — код страны (для России — 250)
MNC — код сети (МТС — 01, Мегафон — 02, Билайн — 99 и т.п.)
LAC — код локальной зоны (другими словами, совокупности базовых станций,
обслуживаемых одним контроллером)
CellID (CID) — идентификатор, состоит из номеров базовой станции и сектора

Зная, куда посылать данные, осталось эти значения получить! Наиболее простой
способ — прямо в программе Google Maps перейти в «Справку», там щелкнуть «Общие
сведения», и в самом конце этой странички будет строка с параметрами в формате
myl:MCC:MNC:LAC:CellID. Куда больший простор для деятельности предоставляют
специальные программы netmonitor’ы: с их помощью можно логировать параметры при
переключении от одной станции к другой, извлекать параметры «соседей»
(находящихся в поле зрения других БС), да и просто получать куда более подробную
информацию. Для каждой платформы есть свои реализации нетмониторов с различными
возможностями — ты можешь выбрать программу под себя.

Теперь, когда все необходимые параметры получены, можно обратиться на сервер
и попробовать получить ответ. Приведу для этого несложный скрипт на Python’е,
который написал наш соотечественник Skvo и опубликовал на форуме
forum.netmonitor.ru:

net, cid, lac = 25002, 9164, 4000
import urllib
a = '000E00000000000000000000000000001B0000000000000000000000030000'
b = hex(cid)[2:].zfill(8) + hex(lac)[2:].zfill(8)
c = hex(divmod(net,100)[1])[2:].zfill(8) + hex(divmod(net,100)[0])[2:].zfill(8)
string = (a + b + c + 'FFFFFFFF00000000').decode('hex')
try:
data = urllib.urlopen('http://www.google.com/glm/mmap',string)
r = data.read().encode('hex')
if len(r) > 14:
print float(int(r[14:22],16))/1000000, float(int(r[22:30],16))/1000000
else:
print 'no data in google'
except:
print 'connect error'

Для запуска, естественно, потребуется интерпретатор Python’а (обязательно 2-й
ветки, потому как на 3-й не запустится), который можно скачать с сайта
http://python.org/download/releases. В первой строке скрипта, как несложно
догадаться, необходимо подставить NET (MCC и MNC, написанные слитно), CID, LAC.
В результате скрипт сформирует запрос на сервер http://www.google.com/glm/mmap и
отправит его. Если базовая станция с этими параметрами есть в базе, то на экран
выведутся координаты, например, «59.200274 39.836925». В противном случае скрипт
выдаст ошибку: «no data in google». Любителям программировать не составит труда
добавить пару строчек, например, по указанным NET и LAC перебрать все варианты
CID (от 1 до 65536), и, посмотрев, какие сектора имеются у Гугла, узнать их
примерные координаты. Если тебе неохота морочить голову скриптами, на наш диск
мы выложили GUI-программу, написанную на C# (исходники прилагаются). В этом
случае ты автоматически получишь еще и ссылку, отображающую координаты на сайте
Google Maps. Ссылки на реализации на других языках смотри в боковом выносе.

Интересно, что на сервер передаются всего лишь три параметра, причем
ключевыми являются только значения LAC и CellID. А MCC/MNC необходимы на тот
случай, если в базе есть несколько пар с одинаковыми LAC, CellID. При этом
телефон может получать намного больше информации о текущей станции – взять хотя
бы мощность сигнала, однако эти параметры в расчетах не используются. Получается
крайне простой алгоритм. Один сектор — одна координата, независимо от того,
находится ли пользователь в 100 метрах от базовой станции или в километре от
нее, координата будет одинаковая!

Отдельно хочу сказать, что замечательный проект «Яндекс.Карты», который я
особенно люблю за возможность отображения точек, имеет точно такой же
функционал. И ровно так же, как и Google, предоставляет своей программе данные о
точке по запросу с указанием Cell ID, LAC, NET параметров:

http://mobile.maps.yandex.net/cellid_location/?&cellid=%d&operatorid=%d&countrycode=%d&lac=%d

Единственное отличие в том, что ответ сервис «Яндекса» возвращает в
XML-формате, который легко и удобно парсится для извлечения любых параметров.

 

О базовых станциях сотовых сетей

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

celldb.org/aboutapi.php
,
www.opencellid.org/api,
gsmloc.org/code,
cellid.telin.nl. Каждый
из них имеет простой API для получения координат с помощью обычного
HTTP-запроса, при этом в качестве параметров указываются традиционные MCC,
MNC, Cell ID и LAC.

Отдельно хочу упомянуть наш русский проект Netmonitor.ru, в котором собрана
инфа о большом количества БС Мегафона, МТС, Билайна, ТЕЛЕ2 и даже Skylink. К
тому же, на сайте располагается еще и крупнейший форум для исследователей
сотовых сетей.

 

Как заставить работать навигационные программы

Какой бы замечательной ни была программа Google Maps, использовать ее в
качестве навигационного инструмента, мягко говоря, затруднительно. Было бы
здорово, пускай и примерные, но все-таки координаты скормить нормальной
программе навигации, с хорошими картами, подробной адресацией и проработанными
алгоритмами прокладки маршрута. Некоторые программы, например, «Навител» и
«Автоспутник» имеют еще один плюс: они умеют подгружать информацию о пробках и
учитывать ее при составлении маршрута. Чисто теоретически, ничего не стоит
написать подобное приложение самому. Алгоритм прост:

  1. Получаем текущие координаты при каждой смене базовой станции;
  2. Отправляя запрос на спутник, получаем примерные координаты;
  3. Эмулируем в системе последовательный порт и в простом формате NMEA,
    который используют GPS-навигаторы, транслируем туда текущие координаты.

Именно этот принцип лежит в программе VirtualGPS (www.kamlex.com),
предназначенной для устройств на платформе Windows Mobile 2003, WM 5, WM 6, WM
6.1. Бесплатная lite версия программы определяет текущее расположение по вышкам
сотовой связи и эмулирует GPS. После запуска прога создает в системе новый порт,
который нужно указать в настройках любимой навигационной программы — и та,
ничего не подозревая, будет считать, что подключена к настоящему GPS-приемнику.

 

На что способен Wi-Fi

Будучи раздосадован тем, что большинство WiFi-точке в городе либо закрыты,
либо платные, подумай о том, что и им можно найти применение. Полагаю, не надо
говорить для чего :). Принцип точно такой же: определив все точки доступа
поблизости, отправляем информацию о MAC-адресах (добавляя при желании
идентификатор сети SSID) на специальный сервис. Тот проверяет их координаты и
выдает тебе твое примерное расположение. Такая технология давно функционирует в
Штатах, где покрытие Wi-Fi зашкаливает настолько, что скрыться от него уже,
похоже, негде. WPS (Wi-Fi Positioning System) предоставляет компания SKYHOOK
Wireless (www.skyhookwireless.com),
разработавшая клиентские приложения для разных платформ и собрав первоначальную
базу с точками доступа. Быстро появились и альтернативные приложения, которые,
используя API-сервиса, получают координаты пользователя. Среди них —
замечательный плагин для Firefox’а Geode (http://labs.mozilla.com/geode_welcome),
который подставляет информацию о текущем местоположении на любом веб-сайте (во
время создания нового поста в блог, например).

Увы, в России хоть как-то заставить работать SKYHOOK мне так и не удалось.
Зато наши соотечественники вплотную взялись за реализацию подобной идеи,
воплотив в жизнь сервис Wi2Geo (www.wi2geo.ru),
который мне почему-то очень хочется назвать Wi2Go :). Ребята уже сейчас
предоставляют приложения для Windows Mobile, Symbian, Windows и Mac OS X, а для
навигации используют базу IP-адресов, информацию о ячейках GSM и, собственно,
точках доступа Wi-Fi. Базы никому не запрещено использовать в своих целях,
воспользовавшись открытым API (http://labs.wi2geo.ru/basicapi.php).
Огорчает только, что проект будет развиваться только в тех городах, где большое
покрытие Wi-Fi. А таковым пока можно назвать только Москву.

 

А как же трекинг?

Выше мы говорили о трекинге пользователя — системе, позволяющей в реальном
времени отследить положение пользователя на карте. Неплохо, если бы подобную
штуку установили на свои телефоны все друзья. Тогда ничего бы не стоило узнать,
кто где, и при необходимости — договориться о встрече. Ребята из Google
реализовали это в функции Google Latitude, с недавнего времени доступной опять
же пользователям мобильных Google Maps. К сожалению, через браузер просмотреть
расположение друзей можно только в Штатах, но ведь ничего не мешает использовать
американский прокси?

Есть и другой вариант. На сайте

http://forum.xda-developers.com/showthread.php?t=340667
совершенно бесплатно
можно скачать специальную программу для трекинга, клиентская часть которой
устанавливается на коммуникатор на базе WM, а серверная — на любой веб-сервер.
Далее положение объекта можно просмотреть через программу Google Earth. Реально
работающее решение для бизнеса, которое с учетом открытых исходников несложно
доработать под себя!

 

WWW

Параметры Google Maps:

http://mapki.com/wiki/Google_Map_Parameters

Делаем GPS-адаптер для мобильного телефона своими руками:

http://tinkerlog.com/2007/07/13/interfacing-an-avr-controller-to-a-gps-mobile-phone

Мануал по получению координат по данным сотовой точки через Yahoo:

http://developer.yahoo.com/yrb/zonetag/locatecell.html

 

Реализация работы с базой данных Google Maps

На PHP:

http://www.witracks.com.br/gmaps.txt

j2me:

http://www.mapnav.spb.ru/site/e107_plugins/forum/forum_viewtopic.php?9736

android:

http://www.anddev.org/poor_mans_gps_-_celltowerid_-_location_area_code_-lookup-t257.html

C#:

http://www.sebbi.de/archives/2008/04/25/google-maps-mylocation-in-c-sharp

На Python для S60:

http://blog.jebu.net/2008/07/google-cell-tower-mapping-with-python-on-s60

На C#:

http://maps.alphadex.de/datafiles/fct0e1b11782832f02.cs

На Java для Android OS:

http://davanum.wordpress.com/2007/12/01/android-much-better-geo-location-from-just-cellidlac

На Delphi:

http://forum.netmonitor.ru/about4470-0-asc-60.html

2 комментария

  1. 14.11.2014 at 01:38

    Добрый вечер! Спасибо за замечательную статью =)
    не могу найти, где же можно найти исходники в других языках?

  2. Konstantin1969

    20.07.2017 at 13:21

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

Оставить мнение

Check Also

Tips’n’Tricks из арсенала андроидовода. Самые интересные, полезные и нестандартные трюки с Android

Многие годы мы рассказывали про самые разные способы оптимизировать, модифицировать и твик…