Домой О курсе [Mapnik](http://mapnik.org/) - это открытая библиотека для рендеринга растровых карт. Она была разработана специально для проекта [OpenStreetMap](http://www.openstreetmap.org/) нашим соотечественником Артемом Павленко, и сегодня используется в том числе и другими ресурсами. Основная заявленная цель Mapnik - получение красивых карт. Mapnik предоставляет Python API, что делает возможным вызов функций Mapnik (написанного на C++) из Python. Реализовано это в виде так называемых байндингов — специальных обёрток, позволяющих использовать возможности библиотек, написанных на одном языке программирования в приложениях, написанных с использованием другого (для Mapnik существуют байндинги для таких языков программирования как JavaScript, Ruby и Java). Установка Mapnik ---------------- Для установки Mapnik выполним следующую команду: sudo apt install libmapnik3.0 mapnik-utils Чтобы убедиться в том, что Mapnik установился успешно, выполните команду: python -c "import mapnik" Если в ответ на эту команду не последует никаких сообщение об ошибках, значит Mapnik установился корректно. Работа с Mapnik из Python ------------------------- Mapnik поддерживает 2 способа конфигурирования - с помощью команд Python и с помощью специального *.xml файла. Рассмотрим первый вариант. Создадим файл `test.py` следующего содержания: import mapnik m = mapnik.Map(1024, 768) m.srs = '+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs' m.background = mapnik.Color('steelblue') s = mapnik.Style() r = mapnik.Rule() polygon_symbolizer = mapnik.PolygonSymbolizer() polygon_symbolizer.fill = mapnik.Color('rgb(206,154,156)') r.symbols.append(polygon_symbolizer) line_symbolizer = mapnik.LineSymbolizer() line_symbolizer.stroke = mapnik.Color('rgb(106, 106, 106)') r.symbols.append(line_symbolizer) s.rules.append(r) m.append_style('My Style',s) layer = mapnik.Layer('Buildings') layer.datasource = mapnik.PostGIS(host='10.22.0.9',user='pguser',password='topsecret',dbname='dbvega',table='building_polygon',geometry_field='webmercator') layer.styles.append('My Style') layer.srs = '+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs' m.layers.append(layer) extent = mapnik.Box2d(3371223.3058836325071752,8390678.2413386497646570,3374529.0786556685343385,8391677.5805971417576075) m.zoom_to_box(extent) mapnik.render_to_file(m,'world.png', 'png') print "rendered image to 'world.png'" После чего выполним его: python test.py В результате в той же директории появится файл `world.png`, содержащий следующее изображение: ![][03-mapnik-01] В данном пример Mapnik подключился к PostGIS, запросил необходимый охват данных и отрисовал их соответствующим стилем, определенным всё в том же файле `test.py`. Выгрузка конфига в *.xml ------------------------ Познакомимся со вторым способом хранения настроек Mapnik. Запустите выполнение скрипта `test.py` следующим образом: python -i test.py После того как скрипт отработает - появится строка приглашения Python, введите команду: mapnik.save_map(m, 'mapnik-config.xml') В результате чего в файле `mapnik-config.xml` будут сохранены настройки Mapnik: <?xml version="1.0" encoding="utf-8"?> <Map srs="+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs" background-color="rgb(70,130,180)"> <Style name="My Style"> <Rule> <PolygonSymbolizer fill="rgb(206,154,156)"/> <LineSymbolizer stroke="rgb(106,106,106)"/> </Rule> </Style> <Layer name="Buildings" srs="+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs"> <StyleName>My Style</StyleName> <Datasource> <Parameter name="dbname">dbvega</Parameter> <Parameter name="geometry_field">webmercator</Parameter> <Parameter name="host">10.22.0.9</Parameter> <Parameter name="password">topsecret</Parameter> <Parameter name="table">building_polygon</Parameter> <Parameter name="type">postgis</Parameter> <Parameter name="user">pguser</Parameter> </Datasource> </Layer> </Map> Рассмотрим теперь как можно воспользоваться данным файлом. Откройте файл `test.py` и приведите его к следующему виду (удалив или закомментировав лишние строки): import mapnik2 as mapnik m = mapnik.Map(640,480) m.background = mapnik.Color('steelblue') mapnik.load_map(m, 'mapnik-config.xml') extent = mapnik.Box2d(3371223.3058836325071752,8390678.2413386497646570,3374529.0786556685343385,8391677.5805971417576075) m.zoom_to_box(extent) mapnik.render_to_file(m,'world.png', 'png') print "rendered image to 'world.png'" Выполните команду: python test.py В результате чего должно быть сгенерировано изображение аналогичное тому, что было получено в первом случае. Отредактируйте файл `mapnik-config.xml`, приведя его к следующему виду: <?xml version="1.0" encoding="utf-8"?> <Map srs="+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs" background-color="rgb(255,255,255)"> <Style name="My Style"> <Rule> <BuildingSymbolizer fill="rgb(206,154,156)" height="16" fill-opacity="1" /> </Rule> </Style> <Layer name="world" srs="+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs"> <StyleName>My Style</StyleName> <Datasource> <Parameter name="dbname">dbvega</Parameter> <Parameter name="geometry_field">webmercator</Parameter> <Parameter name="host">10.22.0.9</Parameter> <Parameter name="password">topsecret</Parameter> <Parameter name="table">building_polygon</Parameter> <Parameter name="type">postgis</Parameter> <Parameter name="user">pguser</Parameter> </Datasource> </Layer> </Map> И снова выполните команду: python test.py В результате чего должно быть получено следующее изображение (псевдо 3D): ![][03-mapnik-02] Подключение Mapnik в Mapproxy ----------------------------- Аналогично тому, как осуществляется прямой вызов рендерера MapServer, происходит работа и с Mapnik. Одна особенность - Mapnik должен быть установлен в то же виртуальное окружение, что и MapProxy. Заметим, что это - не тривиальная задача. Наиболее простой способ проверить как работает MapProxy с Mapnik - установить MapProxy в систему, в этом случае он будет видеть Mapnik и проблем не должно возникнуть. Пример описания источника данных `mapnik`: my_mapnik_source: type: mapnik mapfile: /path/to/mapnik.xml [03-mapnik-01]: ../img/03-mapnik-01.png [03-mapnik-02]: ../img/03-mapnik-02.png