Тысячи лет назад о такой штуке, как 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

LUKS container vs Border Patrol Agent. Как уберечь свои данные, пересекая границу

Не секрет, что если ты собрался посетить такие страны как США или Великобританию то, прежд…