Всю ночь пинал балду. Пока импортируются данные в постгрес особо не поработаешь, но и уснуть нельзя. Прочел «Антигону» Софокла и неожиданно понравилось. У книги чудовищный перевод, жуткая верстка, но текст гораздо смелее современного пуритантизма. А главное — двадцать пять веков прошло, а мир нисколько не изменился.
Tag Archives for mapnik
Мапник
Каждая установка мапника напоминает операцию профессора Преображенского или запуск ракеты в космос. В обоих случаях длинный обязательный чек-лист. Чайник? — Залит. Кофе? — Под рукой. Табак? — на месте. Удобство стула? — Нормальное. Готов? — Готов. Начинаем.
При всей моей любви к мапнику, при его установке начинаешь думать о необходимости запрета целых направлений в айти в связи с требованиями Женевской конвенции.

Картографический стиль «Y»
В связи с очередным изменением дизайна Яндекс-карт, а также их решительного перехода на векторные тайлы, настало время открыть последний из уцелевших черновиков картографического стиля «Y». Этот xml-файл под мапник стилизует данные OpenStreetMap под стиль Яндекс-карт образца 2016 года.
Файл рабочий, но нет прилагаемого архива с иконками. Оформление кода жуткое и полная дичь в запросах. Надеюсь, сможет послужить хотя-бы в качестве примера стиля под мапник. В связи с лицензионными проблемами предостерегаю от использования в собственных проектах в неизменном виде: я против ничего не имею, но с Яндексом сами разбирайтесь. Выкладываю исключительно в историко-познавательных целях. Ну и еще ради сохранения. Через пару лет и этого файла не останется.
Картографический код как в чудесной алисиной стране: требуется много усилий для того, что-бы он хотя-бы оставался на месте и не деградировал.
Превьюшки картостиля (в левой части картинок оригинальные Яндекс-карты, в правой картостиль «Y» на базе данных OpenStreetMap):

Икеевский Мапник
Иду сегодня по Икее, никого не беспокою. Разглядываю утомительные пейзажи благоустроенного быта, снабженные этикетками на невнятном языке. Вот Юпперлиг, Хемнэс. Тут Свартосэн, Линдвед, Мапник, а это Мюкен… Так, стоп! Какой, нахуй, Мапник? Подошел поближе — точно Мапник:
Да не простой, а олдскульный, розлива середины двухтысячных годов. Сейчас про него уже никто не помнит. Я сам не сразу сообразил: открыл дома OpenStreetMap, а картинка совсем иная:
Хорошо, что в моих коллекциях есть чемоданчик осмера, в котором я сохранил ссылку на проект OSM Then And Now, созданный для демонстрации изменений в OSM c 2007 года. Сходство с Икеевской картиной Пьёттерид не идентичное, но ощутимое:
Над Пьёттеридом висит более дорогой триптих Бьёрнамо, в котором тоже усматривается сходство с OSM-овским стилем, только уже современным. Особенно это видно, если уменьшить насыщенность OSM Mapnik на 35-40 процентов:
Если убрать лишние подписи и поиграть с приоритетом дорог, можно добиться сходства до степени смешения картостилей. Это тем более удивительно, что OSM Mapnik — чудовищный картографический стиль, который плох во всем (и должен таковым быть), а икеевские триптихи выглядят вполне миловидно. Не знаю, черпал ли автор вдохновение в OpenStreetMap или пришел к результату случайно, но первое впечатление от этих карт выглядит как «икеевские дизайнеры совсем охуели».
Но людям нравится.

Установка и настройка OGCServer-master
В прошлый раз мы подняли свой TMS-сервер на базе mapnik. Самое время развернуть на той-же основе свой WMS. Для этого, мы используем библиотеку OGCServer-master написанную Жаном Франсуа Дойоном. Библиотека написана на питоне специально под мапник со следующими ТТХ:
— Поддерживает WMS 1.1.1 и 1.3.0
— CGI/FastCGI, WSGI, mod_python
— Поддерживает все 3 запроса: getcapabilities, getmap и getfeatureinfo
— Выходные файлы в формате JPEG и PNG (только PNG256)
— Обрабатывают ошибки XML/INIMAGE/BLANK
— Поддерживает несколько именованных картографических стилей
— Поддерживает перепроецирование
— Поддерживаются метаданные слоя: title, abstract
— Существует возможность запросить все слои с помощью LAYERS=__all__
При использовании библиотеки следует помнить, что Getfeatureinfo поддерживает только простой текст, не поддерживаются 8-битные растры png (только 256 цветов) и для CGI/FastCGI должна быть доступна запись tempfile.gettempdir() (обычно пишется в «/tmp»). Кроме того, OGCServer-master требует установленных питоновских зависимостей мапника, питоновскую библиотеку для визуализации PIL и модули jonpy.
Подробные инструкции по настройке библиотеки можно почерпнуть из аутентичной страницы гит-хаба. Сама установка элементарна, требуется лишь закачать библиотеку на сервер, после чего в корневой директории библиотеки (она содержит файл setup.py) выполнить команду:
sudo python setup.py install
У библиотеки OGCServer-master есть ряд подводных камней о которых желательно знать до установки. Во-первых, перед установкой рекомендуется исправить имена и заголовки WMS, поскольку их дефолтные значения содержат в себе пробелы. QGis такие записи воспринимает нормально, но у других программ (например, FME) по этой причине могут возникать проблемы с загрузкой WMS-слоев. Для исправления, следует внести правки в шесть файлов из директории ogcserver. Исправленные строки в файлах (прописано «newname») будут выглядеть так:
Файл OGCServer-master\ogcserver\default.conf (2 правки): Строка 95: wms_name = newname Строка 98: wms_abstract = newname Файл OGCServer-master\ogcserver\wms111.py (2 правки): Строка 147: rootlayertitle.text = 'newname' Строка 154: rootlayerabstract.text = 'newname' Файл OGCServer-master\ogcserver\wms130.py (2 правки): Строка 154: rootlayertitle.text = 'newname' Строка 161: rootlayerabstract.text = 'newname'
Во-вторых, OGCServer-master более чувствителен к xml-файлу стиля чем сам мапник. Это значит, что при наличии ошибок в файле стиля, которые при старте рендеринга TMS проигнорируются, например line-opacity, сервис WMS не запустится, а выдаст ошибку с указанием всех строк, подлежащих исправлению. С одной стороны, это требует более тщательной работы над стилем, с другой стороны, позволяет легко отловить ошибку. По этой причине, я использую OGCServer-master даже в тех случаях, когда требуется исключительно создание TMS.
После установки, запустить WMS можно с помощью команды
ogcserver путь_к_стилю.xml
Если вы работаете через ssh, можете прописать перед командой запуска «nohup» для того, что-бы после разъединения сервер продолжал работать. После этого можно запрашивать слои в браузере командой:
http://localhost:8000/?LAYERS=__all__&STYLES=&FORMAT=image%2Fpng&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&SRS=EPSG%3A3857&BBOX=-20037508.34,-20037508.34,20037508.3384,20037508.3384&WIDTH=256&HEIGHT=256
Либо, через стандартный интерфейс QGis или любой другой программы.
Одним из самых больших недостатков библиотеки, является отсутствие кеша, что значительно замедляет работу. Впрочем, решение этой задачи стоит одним из первых в TODO-листе.

Установка тайлового сервера на Debian 8 Jessie
Введение
Данная статья представляет собой перевод руководства по установке TMS сервиса, дополненный моими личными замечаниями.
Если говорить грубо и утрированно, отличие TMS от WMS в том, что первый отдает тайлы каждого зума в виде однослойной плитки, а WMS отдает каждый тайл зума в виде набора прописанных в стиле слоев. Например, если ваши геоданные содержат только слой земли и слой дорог, TMS сделает из них одну картинку территории с дорогами. WMS отрендерит каждый слой отдельно, благодаря чему у вас будет отдельная картинка с землей, отдельная с дорогами.
Если вам требуется изменять наполнение карты путем включения/отключения какого-либо слоя, без WMS не обойтись. Но с другой стороны TMS проще, быстрее и в большинстве случаев предпочтительней, поэтому мы начнем именно с него.
Отдельно замечу: в тексте оригинальной статьи большое количество действий выполняется из под рута. Я не стал это исправлять, но призывая к внимательности и осторожности, снимаю тем самым с себя всякую ответственность за падение вашей операционной системы.
В тексте статьи большое количество команд, поэтому буду рад, если вы укажете на неточность или предложите более простые пути реализации поставленной задачи.
Инструменты
Операционной системой для этих опытов послужит Linux Debian 8 Jessie. TMS будем разворачивать на библиотеке mapnik. Облигантных инструментов для этой работы нет. Под виндой я обычно использую TotalCommander Grey Pack (спасибо за него диаволу на пятнашке) с плагином Secure FTP Connections и программу Putty. Под линуксом я юзаю тильду для ssh-соединения и любой вменяемый файловый менеджер с поддержкой сетевого соединения.
Итак, погнали. У нас в наличии ssh-доступ к серверу с девственно чистой Дебиан Джесси. Рекомендую сразу установить консольный редактор nano:
sudo apt-get install nano
и консольный файловый менеджер mc:
sudo add-apt-repository ppa:eugenesan/ppa sudo apt-get update sudo apt-get install mc
Это не обязательно, но поверьте, потом еще не раз пригодится.
Установка и создание базы данных
Начнем с установки пакетов postgresql-9.4-postgis-2.1 и postgresql-contrib-9.4
Входим под рутом и запускаем:
apt install postgresql-9.4-postgis-2.1 postgresql-contrib-9.4
Теперь создадим базу данных. Переключаемся в постгрес:
su postgres
и для избежания возможных проблем переходим к домашней директории:
cd ~
Создадим пользователя c именем «osm»:
createuser osm
и базу данных с названием «map»:
createdb -E UTF8 -O osm greatbritain psql -c "CREATE EXTENSION hstore;" -d map # Should result in CREATE EXTENSION psql -c "CREATE EXTENSION postgis;" -d map # Should result in CREATE EXTENSION
Если все прошло удачно, выходим из постгреса:
exit
Добавление пользователя
Для того, чтобы избежать работы под рутом, добавим в систему пользователя osm с помощью команды adduser:
adduser osm
Теперь добавим пользователя osm в группу sudo. Для этого воспользуемся редактором nano (вы же его установили, верно?)
su вводим пароль nano /ets/sudoers
Находим строку # User privilege specification
после
root ALL=(ALL:ALL) ALL
вставляем строку
osm ALL=(ALL:ALL) ALL
и сохраняем документ последовательностью хоткеев ctrl+o, Enter , ctrl+x
Импорт картографического стиля
Мы будем использовать стандартный стиль mapnik osm. В дальнейшем, при желании, вы всегда сможете его изменить на свой вкус. Перейдем в домашнюю директорию и скачаем стиль с гит-хаба:
su osm cd ~ wget https://github.com/gravitystorm/openstreetmap-carto/archive/v2.29.1.tar.gz tar -xzf v2.29.1.tar.gz
Теперь в домашней директории должна появиться папка с названием: Теперь вы должны иметь папку с названием «openstreetmap-carto-2.29.1». После этого можно переходить к импорту геоданных.
Импорт геоданных
Нам потребуется пакет osm2pgsql. Для этого переключимся на рута и выполним команду:
exit apt install osm2pgsql
Теперь можно переходить непосредственно к импорту dbf-файла с данными. Самое простое решение — это импортировать всю планету OpenStreetMap целиком. Но у такого подхода есть очевидные недостатки: во-первых, объем диска у вас не безграничен, во-вторых, даже на простое скачивание планеты может уйти изрядное количество времени, а в третьих, информация о улицах какой-нибудь Зулусии вам может быть совершенно не нужна. Приходится вырезать нужный регион из дампа самому, либо использовать готовые данные. Сейчас их можно получить у GeoFabrik, CloudMade или Гис-лаб (НексГИСа). В выгрузке геофабрики напрочь отсутствовали реки. В выгрузке НексГИСа отсутствовали части объектов, пересекаемые государственной границей, из-за чего некоторые пограничные озера при рендере пропадали, но острова на них закрашивались цветом воды. Выгрузки регулярно обновляются, так что это вполне могут быть временные случайные баги. С выгрузками CloudMade я активно не работал, поэтому комментарий дать не могу.
Скачаем архив на территорию России с сайта гис-лаб. Если вы все это проделываете в экспериментальных целях — рекомендую для начала скачать не Россию целиком, а только один из регионов — этим вы сэкономите себе уйму времени. Например, возьмем Ростовскую область.
su osm cd ~ wget href="http://data.gis-lab.info/osm_dump/dump/latest/RU-ROS.osm.pbf"
Теперь импортируем скачанные данные в постгрес. Делается это так: запускаете команду:
osm2pgsql --slim -d map -C 1600 --hstore -S openstreetmap-carto-2.29.1/openstreetmap-carto.style RU-ROS.osm.pbf
и идете пить чай, играть в футбол и гонять балду. Процесс, особенно в некоторых случаях, например при импорте объемного файла, занимает ну очень много времени. Не забудьте, что все это вы делаете через ssh, а значит либо не выключайте компьютер и не отключайтесь от сети, либо используйте соответствующие команды.
Иногда на данном этапе возникают следующие проблемы:
Error: Connection to database failed: could not connect to server: No such file or directory
Тут, возможно, вам пригодиться фраза из оригинальной статьи: «Is the server running locally and accepting connections on Unix domain socket «/var/run/postgresql/.s.PGSQL.5432»?
Кроме того, если вы установили PostgreSQL 9.3 вместе с 9.1 на 9.3 может быть использован другой порт. Необходимо найти его и использовать флаг -p, при запуске osm2pgsql.
Поздравляю. Вы заполучили базу OpenStreetMap на выбранный регион. Проверить это можно командой:
psql -d map -c "select name from planet_osm_point where place='city';"
Создание тайлового сервиса
Установим пакет mod_tile. Пока он недоступен в репозитории Дебиан, поэтому нам потребуется предварительно скачать его с гит-хаба и распаковать в домашней директории:
wget https://github.com/openstreetmap/mod_tile/archive/6c2cb243e4c8b047950ab8062cd66245f20a5d2f.tar.gz -O mod_tile.tar.gz tar -xzf mod_tile.tar.gz
Теперь установим пакеты autoconf, libtool, libmapnik-dev и apache2-dev:
su apt install autoconf libtool libmapnik-dev apache2-dev exit
Перейдем в каталог mod_tile и запустим:
cd mod_tile-6c2cb243e4c8b047950ab8062cd66245f20a5d2f/ ./autogen.sh ./configure make
Теперь запустим из под рута следующую команду:
su make install make install-mod_tile exit cd ..
Создание xml стиля Mapnik
Нам потребуются пакеты curl, unzip, gdal-bin, mapnik-utils и node-carto, для установки которых выполним под рутом:
su apt install curl unzip gdal-bin mapnik-utils node-carto exit
Вернемся в пользователя osm и загрузим необходимые шейп-файлы. Для справки: база osm не хранит в себе континенты и некоторые другие объекты, отображающиеся на низких зумах. Эти полигоны и линии подгружаются и прописываются в стиле с помощью команды:
cd ~/openstreetmap-carto-2.29.1/ ./get-shapefiles.sh
Для смены имени базы данных можно выполнить команду:
sed -i 's/"dbname": "gis"/"dbname": "map"/' project.mml
Для того, что-бы сформировать xml-файл, непосредственно отвечающий за стиль, запустите:
carto project.mml > style.xml
Настройка рендера
Откройте в редакторе nano файл /usr/local/etc/renderd.conf (потребуется использовать sudo). Напротив XML пропишите путь к вашему xml-файлу картостиля. Напротив HOST пропишите localhost.
Либо, вы можете внести эти изменения автоматически, выполнив под рутом:
su
sed -i 's/XML=\/home\/jburgess\/osm\/svn\.openstreetmap\.org\/applications\/rendering\/mapnik\/osm\-local\.xml/XML=\/home\/osm\/openstreetmap-carto-2.29.1\/style.xml/' /usr/local/etc/renderd.conf sed -i 's/HOST=tile\.openstreetmap\.org/HOST=localhost/' /usr/local/etc/renderd.conf
После этого, файл /usr/local/etc/renderd.conf должен выглядеть так:
[default] URI=/osm_tiles/ TILEDIR=/var/lib/mod_tile XML=/home/osm/openstreetmap-carto-2.29.1/style.xml HOST=localhost TILESIZE=256 ;HTCPHOST=proxy.openstreetmap.org ;** config options used by mod_tile, but not renderd ** ;MINZOOM=0 MAXZOOM=19 ;TYPE=png image/png ;DESCRIPTION=This is a description of the tile layer used in the tile json request ;ATTRIBUTION=©<a href=\"http://www.openstreetmap.org/\">OpenStreetMap</a> and <a href=\"http://wiki.openstreetma$ ;SERVER_ALIAS=http://localhost/ ;CORS=http://www.openstreetmap.org ;ASPECTX=1 ;ASPECTY=1
Теперь измените директорию плагинов (plugins_dir) и местоположение пакета (match debian package location) mapnik. Сделать это можно вручную, либо с помощью команд:
sed -i 's/plugins_dir=\/usr\/lib\/mapnik\/input/plugins_dir=\/usr\/lib\/mapnik\/2.2\/input\//' /usr/local/etc/renderd.conf
[mapnik] plugins_dir=/usr/lib/mapnik/2.2/input/ font_dir=/usr/share/fonts/truetype font_dir_recurse=1
Скопируйте скрипт renderd.init и установите право доступа к файлу renderd:
cd /home/osm cp mod_tile-6c2cb243e4c8b047950ab8062cd66245f20a5d2f/debian/renderd.init /etc/init.d/renderd chmod a+x /etc/init.d/renderd
Исправьте пути в скрипте init
sed -i 's/DAEMON=\/usr\/bin\/$NAME/DAEMON=\/usr\/local\/bin\/$NAME/' /etc/init.d/renderd sed -i 's/DAEMON_ARGS=""/DAEMON_ARGS=" -c \/usr\/local\/etc\/renderd.conf"/' /etc/init.d/renderd sed -i 's/RUNASUSER=www-data/RUNASUSER=osm/' /etc/init.d/renderd mkdir -p /var/lib/mod_tile chown osm:osm /var/lib/mod_tile
Теперь запустите rederd:
systemctl daemon-reload service renderd start
Установка и настройка Apache и mod_tile
Установите апач с помощью команды:
apt install apache2
Конфигурация апача и загрузка mod_tiles выполняется командой:
echo "LoadModule tile_module /usr/lib/apache2/modules/mod_tile.so" > /etc/apache2/mods-available/tile.load ln -s /etc/apache2/mods-available/tile.load /etc/apache2/mods-enabled/
Добавьте следующий ниже текст с помощью редактора nano перед тегом <?/VirtualHost> в /etc/apache2/sites-enabled/000-default.conf
LoadTileConfigFile /usr/local/etc/renderd.conf ModTileRenderdSocketName /var/run/renderd/renderd.sock # Timeout before giving up for a tile to be rendered ModTileRequestTimeout 0 # Timeout before giving up for a tile to be rendered that is otherwise missing ModTileMissingRequestTimeout 30
и перезапустите апач:
service apache2 restart
Проверка отдачи тайлов
Перейдите в браузере по адресу http://localhost/osm_tiles/0/0/0.png напрямую , либо с использованием порта 8080. Если все прошло успешно, вы увидете в браузере вот такую картинку:
Теперь можно приступать к редактированию картографического стиля. Для этого, прежде всего, запомните команды:
sudo service renderd stop rm -r /var/lib/mod_tile/default sudo service renderd start
На ближайшие месяцы это будут единственные команды, которые вам потребуются в консоли.
Про косяк отображения данных OpenStreetMap
Сижу вот, рисую домики на Новой Азовке. И вдруг: что за хуйня? Почему я только что обрисованный домик не вижу? Неужели косяк mapnik-а? Или надо пиво пить прекращать? Ан нет. Точно косяк мапника. На всех масштабах кроме максимального, дороги прилегающие к зданию ложатся верхним слоем, скрывая здание частично, а в отдельных случаях полностью. Интересно, из каких соображений приоритет отображения дорог выше приоритета отображения зданий?