[原]使用node-mapnik生成openstreetmap-carto风格的瓦片

news/2024/11/15 1:50:12/

上回说到如何在CentOS上部署node-mapnik,本想着接下来学习如何使用node-mapnik生成openstreetmap的瓦片图,没想到在接下来的近40天的时间里忙成了狗!好不容易等到元旦终于有两天属于自已的时间了。经过一天时间折腾,终于可以初步实现node-mapnik生成openstreetmap-carto风格的瓦片了。

本文涉及的内容较多,而且要用到很多之前的文章中的内容,如有对其中某一个环节不明白,建议可先看前几篇文章。

现在的情况是:

1. PostgreSQL和PostGis安装好了;

2. 使用osm2pgsql将全中国的数据导入到PostGis中,库名为:gis;

    (要下载全中国地图请到这里,如果是测试的话,建议不要下载过大的数据,不然导入到PostGis会非常耗时)

3. 安装了mapnik和open-mapnik;

 

现在的需求是:

1. 使用node-mapnik渲染地图;

2. 地图样式要和openstreetmap官方的一样;

3. 能够通过web方式获取地图瓦片;

 

下面详细介绍实现方法

一、配置openstreetmap官方配图样式

openstreetmap官方的样式下载是https://github.com/gravitystorm/openstreetmap-carto

 

建议下载百度网盘里的文件,因为官方最新(2017年1月1日)的版本有bug

链接:http://pan.baidu.com/s/1jHQwq9o 密码:vgla

 

下载后先进行必要的配置

1. 在导入osm数据时指定样式文件,请参考CentOS7部署osm2pgsql第六节内容。

2. 建立索引。

psql -d gis -f path/indexes.sql

3. 下载shape文件,这些文件包含世界地图,当地图级别低于9级时就不访问数据库,直接使用shape文件中数据了。

python scripts/get-shapefiles.py

不过不建议使用这个自动化工具下载,因为这些数据都在国外的服务器上,如果没有梯子就直接下,估计你一个周末就黄了,最好的方式是下载下列网盘里面的文件。

world_boundaries-spherical.tgz

链接:http://pan.baidu.com/s/1kVsK7uJ 密码:tdfc

ne_110m_admin_0_boundary_lines_land.zip

链接:http://pan.baidu.com/s/1slOwvvR 密码:z7t0

simplified-land-polygons-complete-3857.zip

链接:http://pan.baidu.com/s/1mhQYmog 密码:5tbz

land-polygons-split-3857.zip

链接:http://pan.baidu.com/s/1c2OgSYO 密码:wdpt

antarctica-icesheet-polygons-3857.zip

链接:http://pan.baidu.com/s/1nvdNvcP 密码:fzjl

antarctica-icesheet-outlines-3857.zip

链接:http://pan.baidu.com/s/1eSifwUA 密码:isdm

下载好后,在openstreetmap-carto目录中手工建一个名为 data 的文件夹,然后将这些文件放进行,一一解压,就OK了。

 

4. 安装Noto字体,安体下载地址是:https://noto-website-2.storage.googleapis.com/pkgs/Noto-hinted.zip

下载好后,相办法传到CentOS的 /usr/share/fonts 目录中,然后:

cd /usr/share/fonts

sudo mkdir noto && cd notosudo mv ../Noto-hinted.zip Noto-hinted.zipsudo unzip Noto-hinted.zipsudo yum install fontconfig -yfc-cache -fv

sudo chmod -R 755 /usr/share/fonts

sudo rm Noto-hinted.zip

这里就把基础工作做好了,现在我们仔细看看这个openstreetmap-carto目录里都有些什么

 

这里值得注意的是*.mss文件和project.mml文件,这些文件就是传说中的TileMill生成的样式文件,其中mml是项目文件,主要保存地图的基本属性、数据库连接、图层属性等,mss则主要是各个图层的样式。

那我们该如何使用这些样式呢?这就要稍说一下mapnik是如何工作的了。

二、配图工具及准备样式文件

mapnik提供编程的方式向一个Map对象中添加Layer对象,在这个过程中指定每个Layer的数据源以及样式

C++示例

node-mapnik示例

 

我们思考一下,这样好吗?很显然,如果采用这种方式,那么配置人员就需要具备编程能力,这显然不合理,那好的方法是什么呢?最好是不编程,直接写写样式文件就能配出一张图来。当然,mapnik官方也是这么想的,所以就有了XML方式了。

XML示例

这样看起来像点话了。但是做为一个和颜值有密切关系的工作,使用纯文本开发貌似也挺不合理的,在这种情况下,当...当...当,图形化的IDE就闪亮登场了。

 TileMill

 MapBox Studio Classic

 

上面我们提到的*.mss文件就是TileMill设计的样式,project.mml是TileMill的项目文件。这样就对上号了,openstreetmap-carto是TileMill设计出来的。那么这个MapBox Studio Classic又是什么呢?它和TileMill功能基本一致,也是设计CartoCSS样式文件工具。不同的是MapBox Studio Classic生成的项目文件后缀名是yml,而且生成的要素也更齐全点。但是最大的问题是MapBox Studio Classic登录帐户需要Fq!(GFW威武!)。

从网上的资料来看,MapBox Studio Classic逐渐要取代TileMill

有了所见即所得的设计器,再加上表现力丰富、看着顺眼的类CSS语法的CartoCSS,那配图工作简直So easy了!更赞的是MapBox提供了这么多的预置地图样式,是不是看着要流口水了\(^o^)/

 

 好吧,那么现在唯一的问题是,找遍了openstreetmap-carto的文档,就是没有提如何使用!在这里就需要引入另一个工具了:Carto

安装Carto

sudo npm install -g carto --registry=https://registry.npm.taobao.org

Carto可以将mml转换为xml文件,方法如下:

carto project.mml > mapnik.xml

不过在转换之前还有一个小小的事情要做,openstreetmap-carto源码中默认的数据库连接还没有改过来,所以我们先指定PostGis的连接参数,然后再使用上面的命令生成xml样式文件,这里请注意,要先确保openstreetmap-carto目录有写入权限

修改前:

 

修改后:

 生成的文件如下:

 三、试验生成openstreetmap-carto样式的地图

先在用户目录下生成项目文件夹,然后照着官方示例先来一发

cd ~mkdir -p demoprojects/nodemapnik && cd demoprojects/nodemapnik

vim demo1.js

输入以下内容,注意,load方法中的路径要改相应的改下啊

var mapnik = require('mapnik');
var fs = require('fs');// register fonts and datasource plugins
mapnik.register_system_fonts();
mapnik.register_default_input_plugins();var map = new mapnik.Map(256, 256);
map.load('/home/postgresql_data/openstreetmap-carto/mapnik.xml', function(err,map) {if (err) throw err;map.zoomAll();var im = new mapnik.Image(256, 256);map.render(im, function(err,im) {if (err) throw err;im.encode('png', function(err,buffer) {if (err) throw err;fs.writeFile('map.png',buffer, function(err) {if (err) throw err;console.log('saved map image to map.png');});});});
});

然后运行一下 

node demo1.js

生成的效果图

Good,说明一切正常没问题,接下来我们使用Web的方式生成瓦片图。

四、创建Web瓦片服务,生成指定索引的地图瓦片

1. 安装必要的nodejs模块

sudo npm install -g connect --registry=https://registry.npm.taobao.org
sudo npm install -g sphericalmercator --registry=https://registry.npm.taobao.org

2. 创建node.js应用程序(才开始接触node.js,高手轻拍)

先进入项目目录

cd ~/demoprojects/nodemapnik

创建服务器程序:app.js

var mapnik = require('mapnik'), mercator = require('sphericalmercator'), http = require('http'), url = require('url'), fs = require('fs'), path = require('path'), connect = require('connect');mapnik.register_system_fonts(); 
mapnik.register_default_input_plugins();var server = http.createServer(function(req, res) {console.log('server start...');var query = url.parse(req.url.toLowerCase(), true).query;res.writeHead(500, {'Content-Type': 'text/plain'});console.log(query);if (!query || Object.keys(query).length == 0) {console.log('open html');  try {res.writeHead(200, {'Content-Type': 'text/html'});if (req.url == '/') {res.end(fs.readFileSync('./index.html'));} else {res.end(fs.readFileSync('./' + req.url));      }} catch (err) {res.end('Not found: ' + req.url);      }} else {console.log('validate query');     if (query &&query.x !== undefined &&query.y !== undefined &&query.z !== undefined ) {console.log('x: ' + query.x + ' y: ' + query.y + ' z: ' + query.z); var merc = new mercator({size:256});var map = new mapnik.Map(256,256); var bbox = merc.bbox(parseInt(query.x),parseInt(query.y),parseInt(query.z), false,'900913');console.log('begin load mapnik style');          map.loadSync('/home/postgresql_data/openstreetmap-carto/mapnik.xml');console.log('load mapnik style success');console.log('layers length is: ' + map.layers().length);map.zoomToBox(bbox);var img = new mapnik.Image(256,256);map.render(img,  function(err, img) {if (err) {res.end(err.message);} else {console.log('begin render map');     res.writeHead(200, {'Content-Type': 'image/png'});console.log('x: ' + query.x + ' y: ' + query.y + ' z: '+ query.z);res.end(img.encodeSync('png'));console.log('res end');}});}}
});console.log('start...');connect()
.use(server)
.listen(3000);

创建前端页面:index.html

<!DOCTYPE html>
<html><head><script src="https://ss0.bdstatic.com/5aV1bjqh_Q23odCf/static/superman/js/lib/jquery-1.10.2_d88366fd.js" type="text/javascript"></script><script type="text/javascript">$(function(){$('#btn').click(function(){var x = $('#x').val();var y = $('#y').val();var z = $('#z').val();$('#msg').text('x=' + x + ' y=' + y + ' z=' + z);$('#root').empty();$('#root').append('<img style="width:256px;height:256px" src="' + 'http://192.168.1.98:3000?x=' + x + '&y=' + y + '&z=' + z +'" alt="tile image" />');});});</script></head><body><div><span id="msg"></span></div><div id="root" style="height: 256px;"></div><div><input id="x" value="12162" style="width:50px"/><input id="y" value="6664" style="width:50px"/><input id="z" value="14" style="width:50px"/><input id="btn" type="button" value="get tile"/></div></body>
</html>

3. 然后在防火墙上打洞,让3000端口可以通过,或者懒点的办法,关了防火墙了事(我懒)。

systemctl stop firewalld

4. 启动服务

node app.js

5. 使用浏览器打开网页,http://服务器ip:端口号,然后点击“get tile”按钮。

初始界面

获得瓦片,完美支持万图语(图上中文左边的文字)

与openstreetmap官网对比

服务器端

 

至此,使用node-mapnik生成瓦片算是完工了。网上相关资料实在太少了,本文算是解决了有没有的问题,能力提升还要靠大家一起努力!如果大家在照着本文实验的时候出现问题,请留言一起讨论。

 

下一步的打算是:将openstreetmap-carto应用到生产环境中。架设openstreetmap生产环境的Tile Server。这涉及到node-mapnik切图、瓦片缓存、node.js单机集群等好多问题,不过github上貌似有不少现成的东西可以用,真希望我能有多点时间学习研究。

 

转载请注明原作者(think8848)和出处(http://think8848.cnblogs.com) 

 

转载于:https://www.cnblogs.com/think8848/p/6241836.html


http://www.ppmy.cn/news/190764.html

相关文章

css3 animation 实现帧动画

先上代码&#xff1a; <!DOCTYPE html> <html><head><title></title><style>.ani-container{width: 125px;height: 275px;background: url(data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAHAAcAAD/2wBDAAYEBQYFBAYGBQYHBwYIChAKCgkJChQODwwQ…

zookeeper的安装

1. 打开www.apache.org下载安装包 2. 执行解压命令tar xzf zookeeper-3.4.6.tar.gz 3. 执行cd zookeeper-3.4.6/conf 4. 将复制zoo_sample.cfg文件为zoo.cfg配置文件&#xff0c;指定dataDir目录和dataLogDir目录&#xff0c; dataDir/home/zookeeper/data dataLogDir/ho…

matlab生成28335的工程,(1)DSP_28335如何创建工程

1 )如何用CCS 3.3 新建 TMS320F28335 工程 使用 CCS3.3 新建一个空的工程,以工程名 PLAY( ,游戏之旅正式开始)为例。注意路径 Location 中不能含有中文。 2 )工程基本设置 右击工程名,选择 Build Options,进入设置页面: 1、 Complier 栏, 左列中选择 Advanced, 最下面的 …

java mail 1.4_JavaMail API 1.4.7邮件发送

下载oracle javaMail API: 下载&#xff1a;JavaMail API 1.4.7 解压缩将lib文件夹中的jar文件全部拷贝到 zhouspubuntu:~/Documents/eclipsedoc/workspace/javamail/javamailApi目录下。 在Pachage Explorer中&#xff0c;右击javamail&#xff0c;在Build Path中选择Configur…

HC32F460开发之看门狗功能

文章目录 前言一、看门狗是什么&#xff1f;二、看门狗的使用1.简介2.启动3.刷新看门狗计数器 总结 前言 在一些设备需要长时间稳定运行的场合中&#xff0c;看门狗功能可以说是必不可少的。但在一些低功耗设备中&#xff0c;硬件看门狗的启用又会增大设备的功耗。在实际的项目…

DDS

什么是&#xff24;&#xff24;&#xff33;&#xff1f;&#xff1f;&#xff1f; &#xff24;&#xff24;&#xff33;是针对网络编程的一个公开标准。 是一套支持发布&#xff0f;订阅思想的应用程序接口&#xff08;&#xff21;&#xff30;&#xff29;&#xff09; &…

STM32 PLC底层源码/FX2N源码/断电保持/Keil源码/三菱指令编码注释较多

STM32 PLC底层源码/FX2N源码/断电保持&#xff0f;Keil源码/三菱指令编码注释较多&#xff0c;适合初学者&#xff0c;发编译环境&#xff1a;Keil MDK 4.7以上的版本&#xff0c;CPU需要&#xff1a;STM32F103–RAM内存不小64K&#xff0c;Flash程序空间不小于256K&#xff0c…

STM32 PLC底层源码/FX2N源码/断电保持

STM32 PLC底层源码/FX2N源码/断电保持&#xff0f;Keil源码/三菱指令编码注释较多&#xff0c;适合初学者&#xff0c;发编译环境&#xff1a;Keil MDK 4.7以上的版本&#xff0c;CPU需要&#xff1a;STM32F103–RAM内存不小64K&#xff0c;Flash程序空间不小于256K&#xff0c…