Мега-карта для iPhone:
как сделать свою сложную карту для айфона

English users sorry. Currently I have no plans with translation. I will be thankful if someone would translate the article to English and publish it with a link to original.

В статье объясняется, как изготовить свою собственную сложную карту для iPhone 3G (jailbreak, OS 2.2+). Сложная карта включает в себя разные масштабы, разные слои и разные источники картографической информации с наложением. В статье описывается процесс создания своей карты на примере Мега-карты для iPhone с обзорной картой мира, России, подробной карты Ленинградской области и Московской области, детальных планов Санкт-Петербурга и Москвы, карт России и двух столиц из Яndex, а также слоя транспортной схемы Google Transit для Санкт-Петербурга и Москвы. Объясняется, как сделать индекс улиц для поиска из базы данных OpenStreetMap.

Создание сложных карт для iPhone

© Gregory A. Pozhvanov, 2010. При перепечатке или копировании ссылка на первоисточник обязательна.
Благодарности и вопросы приветствуются! Форма внизу страницы.
Итак, поехали.
Изготовление карты и индекса улиц для iPhone в конечном счёте сводится к созданию двух файлов: MapTiles.sqlitedb - карта, и bookmarks.plist - индекс улиц. Первый файл - база данных в формате SQLite3, второй - двоичный (желательно) PrefsList-файл, оба формата широко используются в телефоне в системных и прикладных программах.

Карту я делал на компьютере Apple в среде Mac OS X, что, впрочем, не мешает проделать то же самое в Windows. Только со скриптом придётся повозиться.

Нам понадобятся:
SAS.Planet - программа для закачки карт и экспорта для iPhone;
SQLiteStudio - программа-редактор баз данных SQLite;
BBedit - продвинутый текстовый редактор;
MapsOfflineUtilities (Box.net | Deposit Files) - преобразователь сырых данных из OpenStreetMap в файл индекса улиц;
AppleScript Editor - редактор скриптов в Mac OS X;
Adobe Photoshop - редактор растровой графики для наложения тайлов.

Часть I. Карта

На этом этапе создадим файл MapTiles.sqlitedb, который является кэшем приложения Maps (Карты) в iPhone.

1. Загрузка карт

Работать с картами мы будем в приложении SAS.Planet. Это windows-программа, и, к сожалению, Mac-версия отсутствует (и вряд ли будет). Однако SAS.Planet превосходно работает как в Crossover (Mac-эмулятор окружения Windows), так и в Windows, запущенной в виртуальной машине Parallels. Раз уж у меня сейчас запущена виртуалка, скриншоты будут из неё.

Установите приложение SAS.Planet, откройте главное окно. Вы увидите карту мира, по которой можно перемещаться, зумировать и пр. Сверху находится переключатель режима работы онлайн/оффлайн и переключатель картографических источников. Кроме того, в левой части панели инструментов есть инструмент выделения - это понадобится при загрузке карты на Ваш компьютер в кэш.

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

Опыт показывает, что для удобного просмотра достаточно: карты мира на увеличении до 9x, карты России до 10-11x (в Яndex.картах европейской части - до 12x), карты Вашей области - 12х в Google.Maps и до 14x в Яndex.картах (ЛО и МО, европейская часть России, другие менее подробны). Карту города имеет смысл скачивать с Google и Яndex в увеличении до 17x (и 18x, если Вы не различаете по карте меньшего масштаба, у какого конца дома стоите).


Масштабы карты Google от 5x - карта Европы - до 17x - номера домов в Санкт-Петербурге.

Возьмите листок бумаги и составьте список областей карты, которые Вы собираетесь включить в итоговую карту, с пометками минимального и максимального увеличения.
Например:
Карта Мира: 1x - 9x
Карта Европы: 10x
Карта России: 11x
Ленинградская область: 12x - 13x
Санкт-Петербург: 14x - 17x.
Заметьте, нет смысла загружать, скажем, для Санкт-Петербурга слой с масштабом 10x или 13x - они входят в состав более крупных площадей.

Теперь можно загружать карту в SAS.Planet'е. У любого поставщика интернет-картографии из доступных в программе, карты представлены в виде растровых изображений, разбитых на квадраты в соответствии с координатной сеткой. Они называются тайлы (от англ. Tile). При увеличении карты вместо одного тайла масштаба 1x подставляются четыре тайла 2x, и так далее.

В SAS.Planet'е установите область карты, которая Вас интересует, и выберите площадь для скачивания. Делается это командой Operations > Select > Poligonal Area или выбором инструмента на панели:

Когда завершите выделение, щёлкните OK, и откроется диалоговое окно загрузки карты. Не забудьте сохранить выделение (в файле .hlg, диалог по щелчку на значке дискетки внизу):

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

Таким образом, у Вас будут накоплены в кэше SAS.Planet тайлы для будущей карты iPhone, и если Вы не хотите заниматься разными хитростями, как например создание слоя транспортной схемы, наложенной на карту, или других гибридных слоёв, можете смело переходить к разделу 4.

2. Настройка SAS.Planet'ы и загрузка транспортной схемы

Теперь мы собираемся загрузить из интернета транспортную схему Google.Maps. Для начала убедитесь на Google.Maps, что для Вашего города такая схема вообще есть. Полноценная схема транспорта в России сейчас есть только для Санкт-Петербурга и Москвы, в остальных городах, правда, отмечены линии метро.

В SAS.Planet'е не предусмотрен слой транспорта, поэтому эту функциональность Вам придётся обеспечить самим. Позаимствуем для этого слой Hybrid (Google). Откройте окно Parameters > Settings, и в открывшемся окне настроек в первой же вкладке отыщите нужный нам пункт Hybrid (Google):

Теперь нажмите кнопку Parameters, и Вы увидите параметры по умолчанию:

Вам нужно поменять значения параметров URL и Name in cache:

Значение URL измените на
http://mt3.google.com/mapslt?lyrs=transit&imgtp;=png32≷=ru&hl;=ru,
и Name in cache на gtrans.

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

С апреля 2010 в Google.Maps изменился транспортный слой. Теперь не нужно производить наложение тайлов, и раздел 3 можно пропустить в большинстве Ваших задач.
Новое значение параметра URL для транспортного слоя:
< br />http://mt0.google.com/vt/lyrs=m@121,transit%7Cvm:1&hl;=ru

3. Слияние слоёв мега-карты в Adobe Photoshop

Придётся повозиться с изготовлением комбинированного слоя карты (в моём примере - транспортная схема с линиями метро, маршрутами троллейбусов, трамваев и автобусов). Причин тому есть две. Во-первых, приложение на iPhone не резиновое, и в карте можно задействовать не больше 3-х слоёв для разных картографических источников. Во-вторых, SAS.Planet'а не умеет (во всяком случае пока) экспортировать прозрачные тайлы формата PNG, которые iPhone мог бы сам накладывать на тайлы, содержащиеся в слое Satellite, на лету при просмотре карты. Максимум, что Вы получите на выходе - линии метро на сером фоне. Это неинформативно. Посмотрите на айфон под заголовком статьи - вот так надо!

Идея дальнейшей работы проста: нужно наложить (например, в фотошопе) десятки тысяч тайлов транспортной схемы на тайлы карты, причём не как попало, а один точно на другой. К счастью, в кэше программы SAS.Planet имя и адрес тайла из разных слоёв провайдера карты одинаков, только они хранятся в разных папках. В нашем случае тайлы транспортной схемы сохранены в папке gtrans, а карты - в MAP.

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

global trans_folder

global map_folder

global txtfiles

global txtfolders

global subfolders

global map_file_ext

global trans_file_ext

global enable_logging

 

set trans_folder to (choose folder with prompt "Select folder with Google Public Transport layer images:" )

set map_folder to (choose folder with prompt "Select folder with Google Map layer images:" )

set txtfiles to ""

set txtfolders to ""

set map_file_ext to ".png" -- extension of map image files

set trans_file_ext to ".png" -- extension of overlay image files

set enable_logging to true -- will show you log in blank TextEdit application window

 

if enable_logging then

      tell application "TextEdit"

            set text of document 1 to "Script log:

 

 

"

      end tell

end if

 

to searchReplace(thisText, searchTerm, replacement)

      set AppleScript's text item delimiters to searchTerm

      set thisText to thisText's text items

      
set
AppleScript's text item delimiters to replacement

      set thisText to "" & thisText

      set AppleScript's text item delimiters to {""}

      return thisText

end searchReplace

 

on overlay_inPhotoshop(transImage, mapImage)

      tell application "Finder"

            set current_trans_file to (transImage as POSIX file) as alias

            set current_map_file to (mapImage as POSIX file) as alias

      end tell

      tell application "Adobe Photoshop CS4"

            set err_msg to ""

            activate

            

            open current_map_file

            set this_image_map to current document

            tell this_image_map

                  activate

                  --change mode to RGB

                  select all

                  copy

                  set img_width to width of this_image_map

                  set img_height to height of this_image_map

                  --save as PNG in trans_image_file_path

                  close saving no

            end tell

            

            open current_trans_file

            set this_image_transit to current document

            tell this_image_transit

                  --set trans_image_file_path to file path

                  activate

                  change mode to RGB

                  if width of this_image_transit < 2 then

                        resize canvas this_image_transit width img_width height img_height anchor position middle center

                  end if

                  paste

                  move first layer to after last layer

                  flatten

                  save

                  close

            end tell

            

            

      end tell

      return err_msg

end overlay_inPhotoshop

 

on process_subfolders(folder_name)

      tell application "Finder"

            set subfolderslist to folders in folder_name

      end tell

      if length of subfolderslist > 0 then

            repeat with an_item in subfolderslist

                  tell application "Finder"

                        set current to an_item as alias

                  end tell

                  copy (txtfolders & (POSIX path of current as text) & "

") to txtfolders

                  process_files(an_item)

                  process_subfolders(an_item)

            end repeat

            return subfolderslist

      else

            return ""

      end if

end process_subfolders

on process_files(folder_name)

      tell application "Finder"

            set files_list to files in folder_name

      end tell

      if length of files_list > 0 then

            repeat with an_item in files_list

                  tell application "Finder"

                        set current to an_item as alias

                  end tell

                  if (POSIX path of current as text) ends with trans_file_ext then

                        set current_trans to POSIX path of current as text

                        set current_map to searchReplace(searchReplace(POSIX path of current as text, POSIX path of trans_folder as text, POSIX path of map_folder as text), trans_file_ext, map_file_ext)

                        copy (txtfiles & current_trans & "

") to txtfiles

                        copy (txtfiles & current_map & "

") to txtfiles

                        

                        set error_msg to ""

                        tell application "Finder"

                              if exists current_map as POSIX file then

                                    set error_msg to ""

                              el
se

                                    set error_msg to "file "" & current_map & "" does not exist"

                              end if

                        end tell

                        

                        if error_msg is equal to "" then

                              set error_msg to overlay_inPhotoshop(current_trans, current_map)

                        end if

                        

                        if enable_logging then

                              tell application "TextEdit"

                                    set paragraph 2 of document 1 to ("Items processed: " & ((number of paragraphs in txtfiles) - 1) / 2) & "

"

                                    set paragraph 3 of document 1 to ("Current item: " & POSIX path of current as text) & "

"

                                    set paragraph 4 of document 1 to ("Errors: " & error_msg)

                              end tell

                        end if

                  end if

            end repeat

            return files_list

      else

            return ""

      end if

end process_files

 

process_subfolders(trans_folder)

Скопируйте скрипт из таблицы, запустите редактор AppleScript (находится в Mac OS X по адресу /Applications/Utilities/AppleScript Editor.app) и вставьте текст в окно пустого документа. Скрипт можно сохранить в файле, а можно сразу запустить на исполнение. Заметьте, что его можно использовать и для наложения слоя гибрид на спутник, транспортной схемы на спутник, и т.п., единс

Мега-карта для iPhone: как сделать свою сложную карту для айфона: 6 комментариев

  1. Для iPad тоже, естественно, работает.
    Нужно будет после изготовления отдельных слоёв c флажком 2 сконвертировать их по очереди в формат карт для iPad с помощью Mapv4v5Converter: http://imapsmanager.com/mapConverter/mapConverter.htm
    и потом уже в SQLite Studio присвоить им новые флажки, соответствующие слоям в финальной карте, после чего объединить в один большой файл.

  2. Цель не только в оффлайн доступе (и в роуминге!), но и в том, чтобы иметь такие карты, которые самим функционалом не предусмотрены. Предусмотрен только Google, а вручную можно напичкать те карты, которые нужны. В Москве мне очень пригождается транспортная схема, ведь если метро в СПб я объездил всё, то в Мск не помню, где какая станция..

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