воскресенье, 29 июля 2012 г.

Настройка базы данных для генератора тайлов Mapnik

Продолжение серии заметок, посвящённых настройке тайлового сервера. Смотрите также предыдущую заметку Подготовка карт для генератора тайлов Mapnik.

Введение

Эта заметка посвящена настройке базы данных для генератора тайлов Mapnik. Генератор тайлов - это программа, которая на основе векторного описания карты и файла описания стилей формирует квадратные растровые картинки с изображением карты.

Генератор тайлов можно использовать в сочетании с различными JavaScript-библиотеками, позволяющими прямо в веб-браузере просматривать карту. Проект OpenStreetMap, в котором используется генератор тайлов Mapnik, пользуется JavaScript-бибилиотекой OpenLayers. Забегая вперёд хочу сказать, что мой выбор остановился на JavaScript-библиотеке Киевского программиста Владимира Агафонкина LeafLet, которая хотя и уступает библиотеке OpenLayers по возможностям, зато проще в использовании и имеет более качественную документацию.

Вообще, о начинке проекта OpenStreetMap могу сказать следующее. Видно что проект динамично развивается и не имеет какой-либо генеральной линии развития. Основные компоненты проекта написаны на самых разных языках: C++ и Python (Mapnik), Java (JOSM и Osmosis), JavaScript (OpenLayers, но тут уж без альтернатив), Ruby On Rails (веб-сайт OpenStreetMap). Одно время сайт OpenStreetMap хранил свои данные в MySQL, в то время как вся географическая информация хранилась в PostgreSQL. Однако, разработчики сайта всё-таки перешли полностью на PostgreSQL, отказавшись от MySQL.

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

Для облегчения настройки я советую взять Debian 7.0 Wheezy, хотя и на Debian 6.0 Squeeze настройка тоже возможна, но она сопряжена с бОльшими усилиями (подключение сторонних репозиториев, пересборка пакетов и т.п.). Всё дальнейшее описание делается применительно именно к Debian 7.0 Wheezy.

Установка СУБД

Установим пакеты, необходимые нам на этом этапе:
# apt-get install postgresql postgresql-contrib postgresql-9.1-postgis osm2pgsql
Настраиваем авторизацию по паролю в файле /etc/postgresql/9.1/main/pg_hba.conf, заменив первую строчку на вторую:
local all all peer
local all all password
Теперь выполним тюнинг ядра Linux для увеличения скорости работы PostgreSQL:
# sysctl kernel.shmmax=268435456
И пропишем такую же настройку в файле /etc/sysctl.conf:
kernel.shmmax=268435456
После тюнинга ядра можно произвести тюнинг самого сервера PostgreSQL. Для этого в файле /etc/postgresql/9.1/main/postgresql.conf изменим следующие строчки:
shared_buffers = 128MB
checkpoint_segments = 20
maintenance_work_mem = 256MB
autovacuum = off
Перезапустим сервер PostgreSQL, чтобы новые настройки вступили в силу:
# /etc/init.d/postgresql restart
Создание базы данных для Mapnik.

Теперь создадим пользователя, базу данных, установим в неё расширения, необходимые для работы Mapnik. Войдём под администратором PostgreSQL:
# su - postgres
Создадим пользователя:
$ createuser -PRDS osm
Создадим базу данных, принадлежащую только что созданному пользователю:
$ createdb -E UTF8 -O osm osm
Установим в базу данных расширение для индексирования геометрических объектов, находящееся в пакете postgresql-contrib:
$ psql -d osm -c "CREATE EXTENSION btree_gist;"
Установим в базу данных расширение PostGIS, необходимое для осуществления различных операций над геометрическими объектами. Расширение находится в пакете postgresql-9.1-postgis. Подробнее почитать о функциях, добавляемых PostGIS в PostgreSQL, можно на официальном сайте проекта: PostGIS 1.5.4 Manual.
$ psql -d osm -f /usr/share/postgresql/9.1/contrib/postgis-1.5/postgis.sql
Делаем пользователя osm владельцем таблиц geometry_columns и spatial_ref_sys, чтобы osm2pgsql мог импортировать карты от имени пользователя osm:
$ psql -d osm -c "ALTER TABLE geometry_columns OWNER TO osm; ALTER TABLE spatial_ref_sys OWNER TO osm;"
Теперь нужно установить описания проекций. Самому Mapnik'у нужна лишь одна проекция - 900913, проекция Меркатора. Установить её можно с помощью следующей команды:
$ psql -d osm -f /usr/share/doc/osm2pgsql/examples/900913.sql
Я же установил все доступные проекции, так как в дальнейшем я с помощью SQL-запросов извлекал геометрическую информацию в проекции 4326 WGS84 (обычные широта и долгота), преобразовывая проекцию объектов с помощью функции PostGIS ST_Transform.
$ psql -d osm -f /usr/share/postgresql/9.1/contrib/postgis-1.5/spatial_ref_sys.sql
На этом настройка базы данных завершается, можно выйти из сеанса пользователя postgres, открытого командой su.

Заливка данных в базу данных Mapnik

Осталось залить карты в базу данных. Для этого можно воспользоваться утилитой из одноимённого пакета osm2pgsql:
$ osm2pgsql -U osm -d osm -W /home/stupin/Downloads/RU-BA_TA_ORE.pbf

воскресенье, 22 июля 2012 г.

Подготовка карт для генератора тайлов Mapnik

Это - первая заметка, посвящённая настройке и использованию генератора тайлов Mapnik. Генератор тайлов - это программа, создающая квадратные растровые изображения фрагментов карты, по её векторному описанию. Прежде чем настраивать сам генератор тайлов, нужно подготовить для него данные, чем мы и займёмся в этой заметке.

Заливка карт в базу данных Mapnik на первый взгляд не должна представлять каких-то сложностей - достаточно взять карту в формате с расширением osm, вооружиться утилитой osm2pgsql и вперёд. Но на самом деле даже в этом, на первый взгляд простом, деле, не имея никакого опыта, можно довольно долго ходить по плотно разложенным граблям.

Мне нужно было скачать и залить в базу данных Mapnik карты Башкирии, Татарстана и Оренбургской области. Я нашёл их на сайте gis-lab.ru, по ссылке http://gis-lab.info/projects/osm_dump/. Попробовал залить их в базу данных и был несколько разочарован - карты, выложенные там, устарели.

Дело в том, что сайт OpenStreetMap с 1 апреля 2012 года приостановил публикацию файлов карты планеты из-за смены лицензии: http://gis-lab.info/blog/2012-03/osm-license-change/. Была уже середина июня, а данные на сайте gis-lab.ru по-прежнему толком не обновлялись. И я решил вырезать из последнего дампа планеты интересующие меня области самостоятельно.

Для различных операций по обработке карт osm нам понадобится утилита osmosis. Лучше всего установить osmosis версии не ниже 0.40. Я поставил эту утилиту из репозитория Debian Wheezy (7.0), который на момент написания заметки был тестовой веткой Debian.

Скачиваем и готовим карту планеты

На скачивание архива размером 23 гигабайта со страницы http://planet.openstreetmap.org/ у меня ушло примерно 6 часов. Ещё 12 часов ушло на разжатие архива, а разжатый файл занял примерно 330 гигабайт.

В интернете я наткнулся на заметку *.osm or *.pbf ?, в которой сравнивались размеры файлов в этих форматах. Чтобы освободить место на диске и ускорить обработку данных, я решил преобразовать файл планеты в двоичный формат:
$ osmosis --read-xml file="planet-latest.osm" --write-pbf file="planet-latest.pbf" omitmetadata="yes"
Преобразование заняло примерно 25 часов, а двоичный файл занял всего-лишь 14 гигабайт.

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

Готовим полигон для обрезки карты

Теперь нам понадобятся файлы полигонов для обрезки интересующих нас областей. Я взял интересующие меня файлы с сайта gis-lab.ru, всё на той же странице http://gis-lab.info/projects/osm_dump/ по ссылке http://data.gis-lab.info/osm_dump/poly/.

Ещё нам понадобятся утилиты для преобразования файлов полигонов в файлы osm и обратно, которые можно взять здесь: http://svn.openstreetmap.org/applications/utils/osm-extract/polygons/ и редактор JOSM, который можно установить из дистрибутива.

Скачаем и подготовим к использованию скрипты:
$ wget http://svn.openstreetmap.org/applications/utils/osm-extract/polygons/poly2osm.pl
$ wget http://svn.openstreetmap.org/applications/utils/osm-extract/polygons/osm2poly.pl
$ chown +x poly2osm.pl osm2poly.pl
Установим редактор JOSM и его плагины:
# apt-get install josm josm-plugins
Программа постоянно обновляется, а свежую версию JOSM можно скачать с сайта josm.ru. Я рекомендую скачивать последнюю протестированную версию. Запустить её можно так:
$ java -jar josm-tested.jar
Преобразуем файлы полигонов в формат osm:
$ ./poly2osm.pl RU-BA.poly > RU-BA.osm
$ ./poly2osm.pl RU-TA.osm > RU-TA.osm
$ ./poly2osm.pl RU-ORE.osm > RU-ORE.osm
Теперь запустим редактор JOSM, и откроем в нём все три получившихся файла в отдельных слоях. Объединим слои, а затем воспользуемся инструментом "Объединить накладывающиеся полигоны". Выделим два любых полигона и нажмём Shift-J. Повторим операцию для всех оставшихся полигонов. В итоге получим один полигон, который сохраним в файл с расширением osm. Я сохранил под имененм RU-BA_TA_ORE.osm.


Осталось преобразовать файл из формата osm в формат полигона:
$ ./osm2poly.pl RU-BA_TA_ORE.osm > RU-BA_TA_ORE.poly
Вырезаем из карты планеты интересующую область

Теперь нужно обрезать карту планеты по полигону. Как выяснилось, в процессе обрезки карты планеты по полигону, osmosis создаёт временные файлы в каталоге /tmp. У меня этот каталог находится на корневом разделе, на котором было свободно всего 6 гигабайт. Программа работала довольно долго, а обнаружил я её уже завершившейся с сообщением о нехватке места без какой бы то ни было конкретики. При втором запуске я стал следить за местом на дисках, надеясь что программе не хватило именно его, а не места в оперативной памяти. Спустя несколько часов я увидел, что программа начала занимать место на корневом диске и нашёл её временные файлы в каталоге /tmp. Я поискал ответа в интернете и нашёл совет воспользоваться переменной окружения JAVACMD_OPTIONS. Как я узнал потом, временные файлы занимали примерно 24 гигабайта.

Кроме того, на карте могут существовать объекты, частично выходящие за границы полигона. Для того, чтобы эти объекты целиком попали в результирующую карту, нужно указать опции completeWays=true - дороги полностью и completeRelations=true - все объекты, относящиеся к вырезаемым (смысл этой опции мне не совсем понятен).

Для ускорения процесса вырезки карты рекомендуют воспользоваться опцией idTrackerType=BitSet, которая позволяет эффективно отслеживать идентификаторы объектов при вырезании из карты больших фрагментов. По умолчанию используется idTrackerType=idList, которая обладает какими-то ошибками в реализации, приводящими к высоким затратам времени на обрезку карты. Важно, что эту опцию необходимо указывать для каждой опции-фильтра (взята эта рекомендация отсюда: http://fprog.livejournal.com/5508.html?thread=166276). На моём компьютере osmosis при использовании этой опции завершался с ошибкой нехватки оперативной памяти, поэтому я не смог оценить прирост скорости обрезки карты.

Итоговая команда для обрезки карты у меня получилась такой:
$ env JAVACMD_OPTIONS="-Djava.io.tmpdir=/home/stupin/Downloads" \
osmosis --read-pbf file=planet-latest.pbf \
--bounding-polygon file=RU-BA_TA_ORE.poly completeWays=true \
--write-pbf file=RU-BA_TA_ORE.pbf omitmetadata=true

воскресенье, 15 июля 2012 г.

TwinView: монитор и телевизор

Почти ровно год назад я писал о настройке двухмониторной конфигурации X-сервера в заметке Xinerama: монитор и телевизор.

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

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

К сожалению, настроить двухмониторную конфигурацию с помощью Xrandr мне не удалось - проприетарный драйвер nvidia, которым я пользуюсь, не поддерживает XRandr. (Тут я оставлю место для тухлых помидоров.) В своё оправдание могу сказать, что моему компьютеру уже почти 6 лет, а 6 лет назад покупка видеокарты ATI для компьютера с Linux неизбежно приводила к захватывающим приключениям на мягкое место. Хотя, говорят, что совсем недавно nvidia всё-таки сподобилась выпустить драйверы с поддержкой XRandr (Тестовая версия проприетарного драйвера NVIDIA 302.07 с поддержкой RandR 1.2/1.3), но эта новость скорее всего не работает для моего случая с видеокартой, которая поддерживается только legacy-драйвером nvidia. Но зато в проприетарном драйвере nvidia есть свой собственный велосипед для двухмониторых (и только) конфигураций под названием TwinView. Его-то я и попробовал настроить.

Это оказалось довольно простым делом, если вооружиться Переводом документации драйвера NVIDIA для Linux. Всё нужное у меня уже было готово после настройки Xinerama. Что я сделал:

1. Закоментировал опции
Screen     1   "Screen1" RightOf "Screen0"
и
Option         "Xinerama" "On"
в секции ServerLayout,

2. Закоментировал секции Device, Monitor и Screen, связанные с настройками второго монитора (то бишь телевизора),

3. Вписал в оставшуюся секцию Device следующие опции:
Option      "TwinView"
Option      "TwinViewOrientation" "RigthOf"
Option      "SecondMonitorHorizSync" "15.625 - 15.625"
Option      "SecondMonitorVertSync"  "50.0 - 50.0"
Option      "MetaModes" "1280x1024,800x600; 1024x768, 800x600; 800x600, 800x600; 640x480, 800x600"
4. Перезапустил дисплейный менеджер.

Как это ни странно, но всё заработало. Появились даже несколько плюсов. Поскольку у двух экранов разное разрешение по вертикали, то под вторым экраном образовывалась некая область, которую я условно назвал "мёртвая зона":
.________________.___________.
|                |           |
|                | Телевизор |
|    Монитор     |___________|
|                |  Мёртвая  |
|________________|___зона____|

Плюс первый - теперь мышь не уезжает из монитора в мёртвую зону, а останавливается прямо перед "мёртвой зоной", на краю экрана монитора. Если же мышь поднять повыше, то она легко проваливается на экран телевизора. Это удобно, потому что так мышь не теряется там, где ей нечего делать.

Плюс второй - раньше программы для снятия снимков экрана в "мёртвой зоне" помещали какую-то искажённую копию изображения на мониторе. Теперь в этой области на снимках виден просто чёрный прямоугольник (см. снимок ниже).

Ну и третий плюс - программы перестали ругаться на отсутствие поддержки XRandr.

Теперь снимки экрана выглядят вот так:

А мой третий файл конфигурации X-сервера для случая настройки двухмониторной конфигурации с использованием TwinView, выглядит вот так (закоментированные фрагменты вырезаны):
Section "ServerFlags"
  Option "AutoAddDevices" "False"
  Option "AllowEmptyInput" "False"
  Option "DontZap" "False"
EndSection

Section "ServerLayout"
  Identifier     "X.org Configured"
  Screen      0  "Screen0" 0 0
  InputDevice    "Mouse0" "CorePointer"
  InputDevice    "Keyboard0" "CoreKeyboard"
EndSection

Section "Files"
  #RgbPath      "/etc/X11/rgb"
  ModulePath   "/usr/lib/xorg/modules"
  FontPath     "/usr/share/fonts/X11/misc"
  FontPath     "/usr/share/fonts/X11/Type1"
  FontPath     "/var/lib/defoma/x-ttcidfont-conf.d/dirs/TrueType"
EndSection

Section "Module"
  Load  "dri"
  Load  "GLcore"
  Load  "glx"
  Load  "dbe"
  Load  "record"
  Load  "extmod"
  Load  "xtrap"
EndSection

Section "InputDevice"
  Identifier  "Keyboard0"
  Driver      "kbd"
  Option      "XkbRules" "xorg"
  Option      "XkbModel" "pc104"
  Option      "XkbLayout" "us,ru"
  Option      "XkbOptions" "grp:alt_shift_toggle"
  Option      "XkbVariant" ",winkeys"
  Option      "AutoRepeat" "250 30"
EndSection

Section "InputDevice"
  Identifier  "Mouse0"
  Driver      "mouse"
  Option      "Protocol" "auto"
  Option      "Device" "/dev/input/mice"
  Option      "ZAxisMapping" "4 5 6 7"
EndSection

Section "Monitor"
  DisplaySize  338 270 # mm
  Identifier   "Monitor0"
  VendorName   "LG"
  ModelName    "Flatron L1730S"
  ### Comment all HorizSync and VertRefresh values to use DDC:
  HorizSync    30.0 - 80.2
  VertRefresh  56.0 - 75.0
  Option       "DPMS"
  # 1280x1024 @ 75.00 Hz (GTF) hsync: 80.17 kHz; pclk: 138.54 MHz
  Modeline "1280x1024_75.00"  138.54  1280 1368 1504 1728  1024 1025 1028 1069  -HSync +Vsync
  # 1024x768 @ 75.00 Hz (GTF) hsync: 60.15 kHz; pclk: 81.80 MHz
  Modeline "1024x768_75.00"  81.80  1024 1080 1192 1360  768 769 772 802  -HSync +Vsync
  # 800x600 @ 75.00 Hz (GTF) hsync: 47.02 kHz; pclk: 48.91 MHz
  Modeline "800x600_75.00"  48.91  800 840 920 1040  600 601 604 627  -HSync +Vsync
  # 640x480 @ 75.00 Hz (GTF) hsync: 37.65 kHz; pclk: 30.72 MHz
  Modeline "640x480_75.00"  30.72  640 664 728 816  480 481 484 502  -HSync +Vsync
EndSection

Section "Device"
  Identifier  "Card0"
  Driver      "nvidia"
  VendorName  "nVidia Corporation"
  BoardName   "NV43 [GeForce 6600]"
  BusID       "PCI:5:0:0"
  Option      "TwinView"
  Option      "TwinViewOrientation" "RigthOf"
  Option      "SecondMonitorHorizSync" "15.625 - 15.625"
  Option      "SecondMonitorVertSync"  "50.0 - 50.0"
  Option      "MetaModes" "1280x1024,800x600; 1024x768, 800x600; 800x600, 800x600; 640x480, 800x600"
EndSection

Section "Screen"
  Identifier "Screen0"
  Device     "Card0"
  Monitor    "Monitor0"
  DefaultDepth    24
  SubSection "Display"
    Viewport   0 0
    Depth     24
    Modes "1280x1024_75.00" "1024x768_75.00" "800x600_75.00" "640x480_75.00"
  EndSubSection
EndSection

суббота, 7 июля 2012 г.

Настройка 3G-модема E352 от Мегафон в Debian Wheezy

Технологии беспроводного доступа в интернет очень удобны своей мобильностью, однако они по-прежнему уступают проводным технологиям по скорости и надёжности. Дома удобнее и дешевле пользоваться услугами проводных провайдеров, однако проводные провайдеры обходят стороной частные дома и дома с малым количеством квартир. В таких случаях не остаётся ничего лучшего, чем воспользоваться технологиями беспроводного доступа. Мне повезло и я могу пользоваться услугами проводного провайдера. Однако, получилось так, что в мои руки попал 3G-модем от Мегафона, который я незамедлительно решил опробовать на своём домашнем компьютере под Debian.

Если окинуть взглядом просторы интернета, то практически на поверхности можно легко найти описание процедуры настройки 3G-модема E352 от Мегафона. Процедура проста до безобразия:

1. Ставим пакеты usb-modeswitch и ppp:
# apt-get install usb-modeswitch ppp
2. Создаём файл настройки для демона PPP в файле /etc/ppp/peers/megafon-3g:
connect "usr/sbin/chat -f /etc/chatscripts/megafon-3g" /dev/ttyUSB0
crtscts
noauth
usepeerdns
defaultroute
user ""
password ""
3. Создаём скрипт /etc/chatscripts/megafon-3g для программы chatscript:
TIMEOUT 35
ECHO ON
ABORT '\nBUSY\r'
ABORT '\nERROR\r'
ABORT '\nNO ANSWER\r'
ABORT '\nNO CARRIER\r'
ABORT '\nNO DIALTONE\r'
ABORT '\nRINGING\r\n\r\nRINGING\r'
ABORT '\nUsername/pASSWORD Incorrect\r'
''  \rAT
OK  'AT+CGDCONT=1,"IP","internet"'
OK  ATD*99***1#CONNECT  ""
4. Пробуем установить подключение:
# pon megafon-3g
Если подключение установлено, светодиод на модеме перестанет мигать зелёным цветом и загорится голубым цветом, как на фотографии:



5. Если модем будет постоянно включен, а при каждой загрузке необходимо автоматически устанавливать подключение, в файл /etc/network/interfaces прописываем следующие строки:
auto megafon-3g
iface megafon-3g inet ppp
  provider megafon-3g
Скорость, судя по интернет-пузомерке internet.yandex.ru для беспроводной сети, по моему мнению, очень даже приличная:

Входящая - 943 Кбит/с, исходящая - 663 Кбит/с.

Ещё одним приятным бонусом является наличие у этого модема разъёма для карт microSD - модем может выполнять функции флешки или адаптера для карт microSD.