Mapnik

一、 Mapnik 介绍

Mapnik 是一个开源的 Python/C++ 地图渲染引擎,他的功能是把数据形式的地图,包含一些地理对象,如地图、层、数据源、特征和地理几何等,通过 一个样式表的定义,渲染成位图格式,用来提供 WMS 服务。其核心是一个 C++ 的共享库提供空间数据访问和可视化的算法和模式。该共享库支持多种操作系统,可以在多线程环境下很好的运行,主要面向一些提供 GIS 服务的 Web 应用开发。图一为使用 mapnik 渲染出来的街区图:

图一

二、 地图数据组织

Mapnik 数据组织包括地图、图层、风格、规则、符号等,其具体以渲染地图文件的方式或者是编程实现的方式予以提供,其地图文件的组织结构如下图二:

图二

备注:地图中可以包含多个风格( Style )、多个图层( Layer ),图层包含对应一个数据源及多个风格,风格包含多个规则,一个规则可以包含多种符号,不同的符号包含不同的属性设置,以 LineSymbolizer 为例,包含 stroke (颜色)、 stroke-width (宽度)、透明度( stroke-opacity )、线相交处模式( stroke-linejoin )、线头模式( stroke-linecap )、线段绘制迭代间隔( stroke-dasharray )。不同的符号之间也有一些相同的属性如 line_pattern_symbolizer 、polygon_pattern_symbolizer 、point_symbolizer 都需要一个file 属性来作为填充图片!

以下是一个仅有路(Road )表述信息的Mapnik 配置文件,可以对map 文件有初步的了解:

<?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 +no_defs" bgcolor="rgb(247,239,239)">

<Style name="highway-border">

<Rule>

<Filter>([NR]&lt;=3)</Filter>

<LineSymbolizer stroke="rgb(188,149,28)" stroke-width="7" stroke-linejoin="round" stroke-linecap="round"/>

</Rule>

</Style>

<Style name="highway-fill">

<Rule>

<Filter>([NR]&lt;=3)</Filter>

<LineSymbolizer stroke="rgb(242,191,36)" stroke-width="5" stroke-linejoin="round" stroke-linecap="round"/>

</Rule>

</Style>

<Style name="road-border">

<Rule>

<Filter>(([NR]=4) or ([NR]=5)or ([NR]=6))</Filter>

<LineSymbolizer stroke="rgb(171,158,137)" stroke-width="5" stroke-linejoin="round" stroke-linecap="round"/>

</Rule>

</Style>

<Style name="road-fill">

<Rule>

<Filter>(([NR]=4) or ([NR]=5)or ([NR]=6))</Filter>

<LineSymbolizer stroke="rgb(255,250,115)" stroke-width="3" stroke-linejoin="round" stroke-linecap="round"/>

</Rule>

</Style>

<Style name="highway-label">

<Rule>

<Filter>([NR] = 1)</Filter>

<TextSymbolizer name="[STNAMEC]" face_name="Microsoft YaHei Regular" size="12" fill="rgb(0,0,200)" placement="line" halo_radius="1" max_char_angle_delta="60" halo_fill="rgb(255,255,200)" line_spacing="100" character_spacing="3"  avoid_edges="1" allow_overlap="0"  min_distance="50" spacing="500" />

</Rule>

<Rule>

<Filter>(([NR]&lt;=6) and ([NR] &gt;= 2))</Filter>

<TextSymbolizer name="[STNAMEC]" face_name="Microsoft YaHei Regular" size="9" fill="rgb(10,10,150)" placement="line" halo_radius="1" halo_fill="rgb(255,255,200)" line_spacing="100" character_spacing="1" avoid_edges="1" allow_overlap="0"  min_distance="20"

spacing="300" max_char_angle_delta="35"/>

</Rule>

</Style>

<Layer name="Roads" 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 +no_defs">

<StyleName>road-border</StyleName>

<StyleName>road-fill</StyleName>

<StyleName>highway-border</StyleName>

<StyleName>highway-fill</StyleName>

<StyleName>highway-label</StyleName>

<Datasource>

<Parameter name="encoding">GB2312</Parameter>

<Parameter name="file">F:/BeijingM/Pathline1-6</Parameter>

<Parameter name="type">shape</Parameter>

</Datasource>

</Layer>

</Map>

三、 Mapnik 主要架构类关系图

图三

图三右边 feature_type_style 部分,为一系列的参数描述,主要是承载地图渲染所需要的相关绘制参数信息; Map 为组织图层数据及绘制风格的载体; feature_style_processor 为地图渲染的抽象基类, agg_renderer 、 cairo_renderer 就是具体负责渲染绘制的类,在绘制时,需要一个用来绘制的设备,如 agg_renderer 需要一个 image_32 的内存图像缓冲区,来承载最终绘制的图片,然后可以使用 save_to_file<image_data_32>() 函数将内存图片保存成最终文件格式!

四、 Mapnik 使用示例

Mapnik 开发主要流程:

l  定义 Map 对象,设置绘制使用的设备大小,及投影信息

l  加载 Map 的配置信息

l  设置 Map 绘制的地理范围

l  定义绘制使用的设备( agg_renderer 为内存图片缓冲区)

l  使用 agg_renderer 或者 cairo_renderer 渲染

l  保存到文件(可选,对于 cairo_renderer 渲染到 pdf 及 svg 等矢量文件时不需要)

具体示例代码如下:

#include <mapnik/map.hpp>

#include <mapnik/datasource_cache.hpp>

#include <mapnik/font_engine_freetype.hpp>

#include <mapnik/agg_renderer.hpp>

#include <mapnik/image_util.hpp>

#include <mapnik/config_error.hpp>

#include <mapnik/box2d.hpp>

#include <iostream>

#include <mapnik/save_map.hpp>

#include "mapnik/load_map.hpp"

int main ( int argc , char** argv)

{

using namespace mapnik;// 使用 mapnik 命名空间

try {

std::cout << " running demo ... /n";

// 注册数据源插件

datasource_cache::instance()->register_datasources("F:/work/mapnik/trunk/builds/win32/Bin");

// 注册字体

freetype_engine::register_font("F:/work/fonts/simkai.ttf");

freetype_engine::register_font("F:/work/fonts/msyh.ttf");

std::vector<std::string> names = freetype_engine::face_names();

std::cout << "face names size:" << names.size() << "/n";

for (unsigned i = 0; i < names.size(); ++i){

std::cout << names[i] << "/n";

}

// 声明 Map 对象,包括绘制使用的设备大小,及投影信息

Map m(1024,1024,"+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 +no_defs");

//m.set_background(color_factory::from_string("white"));

// 加载 Map 配置文件

load_map(m,"mapconfig.xml");

// 设置地图绘制地理范围

m.zoomToBox(box2d<double>(12934400,4862620,12944200,4872400));

// 定义具体绘制的内存图片缓冲区

image_32 buf(m.getWidth(),m.getHeight());

// 使用 agg_renderer 渲染绘制

agg_renderer<image_32> ren(m,buf);

ren.apply();

//save_map(m,"mapconfig.xml");

//save_to_file<image_data_32>(buf.data(),"demo.jpg","jpeg");

//save_to_file<image_data_32>(buf.data(),"demo.png","png");

// 保存到文件

save_to_file<image_data_32>(buf.data(),"demo256.png","png256");

//save_map(m,"map.xml",false);

std::cout << "One maps have been rendered using AGG in the current directory:/n"

"Have a look!/n";

}

catch ( const mapnik::config_error & ex )

{

std::cerr << "### Configuration error: " << ex.what() << std::endl;

return EXIT_FAILURE;

}

catch ( const std::exception & ex )

{

std::cerr << "### std::exception: " << ex.what() << std::endl;

return EXIT_FAILURE;

}

catch ( ... )

{

std::cerr << "### Unknown exception." << std::endl;

return EXIT_FAILURE;

}

return EXIT_SUCCESS;

}

五、 总结

Mapnik 作为一个开源的地图渲染引擎,拥有良好的技术架构,并使用了很多成熟的开源技术如 proj4 、 freetype 、 libxml2 、 GDAL 、 Boost 、 ltdl 等,并使用 AGG 、 Cairo-Graphics 来具体渲染绘制,具有良好的反锯齿效果!大量使用了 Boost 库特有的 C++ 技术,如 variant 、 tuple ,并利用 C++ STL (仿函数等)、泛型编程技术及相关设计模式(单件模式、访问者模式等),使用插件式的数据源开发方式,使 Mapnik 可以灵活扩展出针对自己的数据格式插件!

然而对于开发人员, mapnik 采用的属性与具体渲染操作分开的模式,屏蔽了内部复杂的实现细节,而对外提供的接口确是简单易用!

Mapnik简要介绍相关推荐

  1. Hadoop学习笔记一 简要介绍

    Hadoop学习笔记一 简要介绍 这里先大致介绍一下Hadoop.     本文大部分内容都是从官网Hadoop上来的.其中有一篇介绍HDFS的pdf文档,里面对Hadoop介绍的比较全面了.我的这一 ...

  2. 数据结构的简要介绍:图形如何工作

    by Michael Olorunnisola 通过Michael Olorunnisola 数据结构的简要介绍:图形如何工作 (A Gentle Introduction to Data Struc ...

  3. R语言效用分析 ( 效能分析、Power analysis)、除了pwr包之外还有其它包、例如、基因研究中的效能分析、MBESS包可用于各种形式的效能分析和最少样本量确定、其他效用分析包的简要介绍

    R语言效用分析 ( 效能分析.Power analysis).除了pwr包之外还有其它包.例如.基因研究中的效能分析(power analysis).MBESS包可用于各种形式的效能分析(power ...

  4. 简要介绍一下贝叶斯定理( Bayes‘ theorem)

    简要介绍一下贝叶斯定理( Bayes' theorem) 在引出贝叶斯定理之前,先学习几个定义: 条件概率(又称后验概率)就是事件A在另外一个事件B已经发生条件下的发生概率.条件概率表示为P(A|B) ...

  5. 各种编程语言功能综合简要介绍(C,C++,JAVA,PHP,PYTHON,易语言)

    各种编程语言功能综合简要介绍(C,C++,JAVA,PHP,PYTHON,易语言) 总结 a.一个语言或者一个东西能火是和这种语言进入某一子行业的契机有关.也就是说这个语言有没有解决社会急需的问题. ...

  6. [翻译]敏捷软件开发 一 之简要介绍

    敏捷软件开发一之简要介绍       原则.模式与实践是重要的,但是这三个要素都要由人来使得它们协同工作.正如Alistair Cockburn所说:"一个成功的项目,过程与技术永远都是排第 ...

  7. 导向滤波python_导向滤波(Guided Filter)简要介绍

    1.介绍 提到导向滤波,首先想到的是"何恺明",他的确是真大神,在图像领域,是中国人的骄傲,深度学习流行的时候,也是提出各种新算法,比如ResNets,而最近两年,深度学习的发展已 ...

  8. Android系统匿名共享内存Ashmem(Anonymous Shared Memory)简要介绍和学习计划

    在Android系统中,提供了独特的匿名共享内存子系统Ashmem(Anonymous Shared Memory),它以驱动程序的形式实现在内核空间中.它有两个特点,一是能够辅助内存管理系统来有效地 ...

  9. Android进程间通信(IPC)机制Binder简要介绍和学习计划

    在Android系统中,每一个应用程序都是由一些Activity和Service组成的,这些Activity和Service有可能运行在同一个进程中,也有可能运行在不同的进程中.那么,不在同一个进程的 ...

最新文章

  1. spring之DelegatingFilterProxy
  2. 公司喜欢什么样的程序员?三个特点吸引HR!
  3. 分享自制的C#和VB Code互转工具
  4. sql server死锁的查询和解除
  5. kotlin学习目录
  6. SAP UI5 应用开发教程之四十五 - 如何在 SAP UI5 应用里使用 jQuery 和原生的 DOM API
  7. html5 测评游戏,暗黑之王评测:HTML5游戏铸就最华丽ARPG冒险
  8. java alert跳页面_JavaScript中通过提示框跳转页面的方法
  9. c语言sin程序怎么写_用数控铣床加工六芒星,程序应该怎么写?
  10. 计算机用手机的网络,电脑做热点让手机上网_电脑开热点给手机用
  11. [常用知识]如何在Eclipse、myEclipse中分别配置Tomcat和JBoss应用服务器
  12. UML系列——OO Unit4分析和学期总结
  13. 金蝶EAS BOS开发常用的代码说明及常见问题
  14. c语言函数调用后必须带回返回值?
  15. Qt下PDF阅读器的开发
  16. 如何给页面添加背景音乐
  17. time(0) 是什么意思?
  18. 来看看未来最有前景的行业
  19. PMEdit一个富文本框可以编辑文本、并可以显示GIF动画
  20. 经验总结|一个移动端数据产品的设计思路

热门文章

  1. C语言入门 —C语言基本数据类型, C语言可以用来干嘛?
  2. win7怎样将便签内容添加到桌面
  3. Microsoft Word中添加MathType选项
  4. 模型训练时测试集上正确率大于训练集
  5. 【网络安全】Cloudopt Extension - 5分钟告诉你强在哪
  6. Android 9.0 修改搜狗为默认输入法,并且授予运行权限
  7. 改纸盒大小_【亲子手工】废旧纸盒大改造,孩子们超级喜欢玩.......
  8. python飞机大战游戏代码_python实现飞机大战游戏
  9. 三星980处理器和骁龙855_A12、麒麟980、骁龙855性能比拼 顶级旗舰之间能差多少?...
  10. 【省流版】延年益寿 | 减肥 | 证据 | 防杠