о google maps

Средства: FireFox, Firebug, Eclipse (c js-плагином), Proxomitron, VC# express, JSDebugger (глючный плагин для FF), скрипты, заведующие картами, официальная документация google maps.
Результат: программа "booble drugs" экспроприирующая снимки и карты с серверов google в локальный кэш, а затем собирающая из них цельные карты.

Теория

Типы карт

На данный момент, если говорить только о Земле (а google, как известно, кроме Земли делает карты звёздного неба и марса), в google maps существует три вида карт: карта, спутник, спутник+карта. Про себя я их уже назвал: map, satellite, combined.

Полотно любой карты строится из отдельных картинок размером 256x256 пикселей, естественно, что каждая картинка имеет свой "адрес".


спутниковый снимок
прозрачный оверлей для
комбинированной карты
карта

Проекция Меркатора

Карты гугла реализованы в проекции Меркатора. Это означает, что у Земного шара отрезаются полюса (инженеры гугла сделали срезку на широтах ±89.19°) и полученный бочонок проецируется на цилиндр. Проекция сохраняет углы между направлениями. В ней меридианы - равноотстоящие друг от друга вертикальные прямые, а параллели - параллельные прямые, расстояние между которыми быстро увеличивается от экватора к полюсам. Это взаимосвязано с непостоянством масштаба - он также возрастает от экватора к полюсам. Однако в окрестностях произвольной точки вертикальный и горизонтальный масштабы одинаковы (за счёт этого и достигается свойство равноугольности проекции).
проекция Меркатора (изображение взято с www.cultinfo.ru)
Это, конечно же, безобразие, что Гренландия по площади едва ли не больше Африки!

Уровни детализации и блоки

Уровни детализации сродни масштабу. В гугл-картах используется 18 уровней: от 0 до 17. На уровне 0 вся карта - это одна картинка 256х256 пиксель. На следующем уровне она разбивается на 4 части (четыре картинки, каждая 256х256) и так продолжается до 17 уровня. Картинки на иллюстрации ниже уменьшены на четверть, чтоб грузилось быстрее.
zoom=0
zoom=1

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

blockDim = 2zoomLevel


Кстати, я когда узнал про уровни и блоки - полез считать, сколько же блоков будет на последнем 17 уровне. Получилось много.

Преобразование координат

Очевидно, пригодятся формулы для пересчёта координат, заданных в широте/долготе, в координаты X/Y проекции Меркатора и обратно.
Начало координат инженеры гугла расположили в верхнем левом углу.

size = 2zoomLevel * 256 - размер карты на уровне детализации zoomLevel в пикселях;

center = size / 2 - задаёт x и y координаты центра карты в пикселях;


Lat, Lon -> X, Y


x = center + size * (Lon / 360) - координата x точки находящейся на долготе Lon;

ls = sin(lat * Pi / 360) - синус широты;

y = center - 0.5 * Ln[(1 + ls) / (1 - ls)] * [size / ( 2 * Pi)] - координата y точки находящейся на долготе Lat;


X, Y -> Lat, Lon

Lon = (x - center) * 360 / size - долгота точки с координатой x;
Lat = (180 / Pi) * (2 * atan[exp((center - y) * 2 * Pi / size)] - Pi / 2) - широта.

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

Нам ещё пригодится умение определять координаты блока в котором находится заданная точка. Но это очень просто. Формулы писать не буду.

URL

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

URL спутниковых снимков
Выше был приведён адрес произвольного блока спутниковой карты:
http://kh2.google.com/kh?n=404&v=25&hl=ru&t=trtqssrrrrq
Его можно разбить на отдельные смысловые части:

kh2
Бывает kh0, kh1, kh2, kh3. Если оставшаяся часть адреса неизменна, то со всех поддоменов приходит одна и та же картинка. Очевидно, гугл использует несколько поддоменов для распределения нагрузки между различными серверами.
n=404
Если этот параметр присутствует, то при отсутствии запрошенной картинки в базе данных, сервер вернёт не код 404 (запрашиваемый ресурс не найден), а какой-то (не запоминал) удобоваримый пользователем текст.
v=25
в базу данных гугл мэпс постоянно добавляются новые снимки, возможно обновляются существующие. Указывая последнюю на данный момент версию, мы получаем самые свежие из имеющихся снимков.
hl=ru
Ну типа, мы русские.
t=trtq...
Самая интересная часть. Кодирует позицию блока на проекции. По количеству букв определяется текущий уровень детализации.
На нулевом уровне детализации нам доступна только одна картинка, кодируется аргументом t=t.
На уровне детализации 1, доступны 4 картинки. t=tq - верхний левый угол; t=tr - верхний правый угол; t=tt - нижний левый угол; t= ts - нижний правый угол.
На втором уровне детализации всё ещё хуже:
tqq
tqr
trq
trr
tqt
tqs
trt
trs
ttq
ttr
tsq
tsr
ttt
tts
tst
tss
Но логика понятна. Зная координаты X,Y некоторой точки, можно несложной процедурой составить код блока в котором она располагается.

URL оверлея

Для разбора возьмём приведённую выше ссылку.

http://mt2.google.com/mt?n=404&v=w2t.69&hl=ru&x=638&y=352&zoom=7&s=Ga

mt2
Бывает mt0, mt1, mt2, mt3 - поддомены. Также, как и для спутниковых снимков, с разных поддоменов приходят одинаковые изображения.
n=404То же, что и для спутников.
v=w2t.69
Версия оверлея. Смысл цифр понять не решился я. Всегда (другого не случалось) по цифрам версия оверлея совпадает с версией карты. По буквам отличается введением буквы "t", по-видимому от слова transparent (карты, в отличии от оверлеев, не прозрачны).
hl=ruРаша.
x=638
Удивительным образом совпадает с x-координатой картинки.
y=352
Совпадает с y-координатой картинки.
zoom=7
Уровень детализации.
s=Ga
Бывает просто s=, бывает s=Gal, бывает s=Galileo. Смысла не имеет ровным счётом никакого. Я не думаю, что это в честь учёного Галилея, но может быть в честь спутника или ещё чего. Место обрыва выбирается отнюдь не случайно, а рассчитывается в зависимости от координат блока, что совсем смешно.

URL карты
Возьмём, приведённую выше, ссылку на фрагмент карты
http://mt2.google.com/mt?n=404&v=w2.69&hl=ru&x=638&y=352&zoom=7&s=Ga
Подвергать её разбору не имеет смысла: здесь всё то же, что и в адресе оверлея, за исключением версии. В версии карты нет буквы "t": v=w2.69.

booble drugs

По результатам исследования была написана программка "booble drugs". Для запуска требует .net framework 2.0. Умеет для заданного региона закачивать с серверов google maps нужные изображения на произвольном уровне детализации, сохранять загруженные блоки в кэше и формировать цельную (или разбитую на крупные блоки) карту. Программа находится в стадии beta.
В ближайшее время (это значит от месяца и более (всё зависит от интереса к программе)) будут:

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

Как пользоваться программой

1. Нам необходим Google Earth для того, чтобы задать регион интереса.

Для этого открываем Google Earth и используя пункт меню Добавить -> Многоугольник выделяем интересующую область. Чем меньше точек вы при этом используете, тем быстрее будет работать booble drugs при перерасчётах.

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

Регион переименуем (если есть желание) и сохраним в файл kml.


сохранение переименованного региона в файл с расширением kml


2. Настройка booble drugs и старт закачки.
Все элементы управления в программе имеют всплывающие подсказки. Для того, что открыть созданный kml-файл, нужно сделать двойной щелчок в верхнем текстовом поле. Появится диалог выбора файла, а после его закрытия, окно программы будет выглядеть примерно так:
В списке отображаются имена всех найденных в kml-файле регионов (их может быть несколько).
Инкрементное поле задаёт уровень детализации с которого вы решили скачивать картинки.
Первый ряд флажков позволяет указать тип скачиваемых картинок.
Всё выбрали? - Жмём download!
во время загрузки отображается прогресс и дополнительное окошко в котором могут появляться разные загадочные надписи

3. Построение карты.
По завершении скачивания, воспользуемся вторым рядом флажков для выбора типа карты, которую нужно создать, и нажмём кнопку build map.
выбрано разбитие карты на 3 блока по каждому измерению + остатки;
видно, что каждый блок имеет размер 768x768px

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