自建OpenStreetmap地图瓦片服务
自建OpenStreetsmap地图瓦片服务
迫于openstreetsmap官方的瓦片服务器(tile server)速度太慢,而提供矢量瓦片(vector tile)服务的mapbox和maptiler的免费额度太少,更新慢。笔者最近尝试基于tileserver-gl,openmaptiles和tilemaker等工具自建了一个openstreetsmap的地图瓦片服务器。
数据准备
我们所需的地图数据有两种格式,分别为pbf和mbtiles。其中,mbtiles格式是可以直接被tileserver-gl使用的,而pbf格式需要转换为mbtiles之后才能被tileserver-gl读取。
mbtiles
如果希望快速搭建地图服务器,我们可以直接在https://extract.bbbike.org/这个网站上选择自己想要的区域并下载。下载时格式选择MB Vector Tiles Openmaptiles
即可。但这样下载下来的mbtiles只有地标的name
字段,其他的翻译全部丢失了。如果不介意这一点,可以在下载完后直接跳到「服务搭建」一节。
PBF
如果希望下载带有完整数据的PBF文件进行修改,我们可以在网站上选择下载PBF格式的地图,或者去 https://download.geofabrik.de/ 上按照国家下载PBF格式的地图。
转换格式
转换格式可以用两个软件,分别是tilemaker和openmaptiles。tilemaker的转换速度很快,不过转换出的mbtiles地图还是有上一节提到的「丢失属性」的问题,而openmaptiler在属性保留这一方面做的很好,而且还能从wikidata里自动下载对应地点的翻译(可选),不过转换的速度很慢。
根据笔者自己测试的转换速度比较,转换的是https://download.geofabrik.de/上下载的中国大陆地区地图,文件大小大约900M,用一台96C372G的机器进行转换。tilemaker转换用了大约半小时,而openmaptiler花了12个小时左右。转换完之后的mbtiles大小约3.5G。
使用tilemaker转换
首先下载tilemaker的二进制文件,之后准备好输入的文件,进行转换即可,机器可能需要安装luajit
,sqlite3
,shapelib
等依赖。:
1 | /root/build/tilemaker --input /data/asia.osm.pbf --output /data/asia.mbtiles --config /root/resources/config-openmaptiles.json --process /root/resources/process-openmaptiles.lua |
其中,json配置文件和lua文件直接使用发行版自带的配置文件即可,**ZOOM
的值最大使用14即可,更大的值不会带来更多的细节**。
使用openmaptiles转换
参考openmaptiles的README进行转换即可,机器需要预装docker
和docker-compose
,具体依赖可以参考这里。首先clone repo,之后在目录中执行(以下的几步需要拉取若干个docker镜像,加起来大约有10G,加上处理的数据,需要在磁盘中至少预留30G的空间比较保险):
(可选)如果要拉取维基百科的数据,则需要给docker添加代理。在.env
中添加:
1 | http_proxy: http://192.168.59.100:8118 |
(可选)如果PBF数据是从bbbike上切出来的,需要预处理一下数据的边界(mydata即下载下来的数据文件名):
1 | mkdir -p data |
如果需要增大执行数据库操作和地图切割操作的线程,可以更改.env
里的MAX_PARALLEL_PSQL
和COPY_CONCURRENCY
。
初始化数据文件夹:
1 | make |
准备数据库:
1 | make start-db |
导入PBF的数据:
1 | make import-data |
导入边界数据:
1 | make import-osm |
(可选)
导入维基百科的附加数据:
1 | make import-wikidata |
清理数据库:
1 | make clean |
生成地图边界:
1 | make generate-bbox-file # compute data bbox -- not needed for the whole planet |
生成mbtiles
文件:
1 | make generate-tiles # generate tiles |
执行完成之后,在data
文件夹下就能看到一个名为tiles.mbtiles
的地图数据文件,复制出来即可。
服务搭建
笔者自己的配置文件repo:https://github.com/sparkcyf/tileserver-gl-config
将中文字体的repo(用于瓦片地图渲染中文):https://github.com/klokantech/klokantech-gl-fonts.git ,将repo中的
KlokanTech Noto Sans CJK Regular
重命名成Noto Sans Regular
,并放入下面提到的fonts文件夹。将前面的到的
tiles.mbtiles
地图数据文件放入相应的data
文件夹。
随后使用repo中的docker-compose文件拉起容器,注意修改配置路径为自己的路径:
1 | version: '3.3' |
docker compose中提到的styles,config等文件都已经放在了上面的repo中了。另外记得修改--public_url
后面的值,以及docker暴露出来的端口。
如果修改了样式文件或配置文件,重启容器即可重载配置。有关tileserver-gl的更多用法,可以参考这里:https://tileserver.readthedocs.io/en/latest/
(可选)修改sprite
在部分的样式文件中,一些图标(比如麦当劳,肯德基,高速公路标志等)需要从外联的样式文件加载,可能会造成瓦片地图渲染缓慢。如果需要替换成本地文件或网络上的其他文件,可以修改样式json文件中的"sprite"
一节。sprite文件的具体类型可以参考这个repo。
全部配置完成之后,运行docker-compose up
,等待镜像被拉起即可查看地图了。
如果打开地图时发现地图是空的,有可能是因为你并没有下载地图对应位置的数据,这时修改url末尾的经纬度即可(下面的url中#
后面的那一串,分别是缩放级别/纬度/经度):
1 | example.com/osm-tile/styles/osm-street/#11.16/22.5429/114.0402 |
在其他地图中引用瓦片服务器
可以参考mapbox写的这个例子,更改style
变量即可:
1 |
|
https://github.com/systemed/tilemaker/issues/187
参考文档
- https://blog.csdn.net/fbvukn/article/details/109072579
- https://stackoverflow.com/questions/65849406/is-there-a-way-to-generate-a-mbtiles-file-from-osm-pbf-file
- https://blog.kleunen.nl/blog/tilemaker-generate-map (如何转换PBF到mbtiles)
- https://yasoob.me/posts/custom-map-with-tileserver-gl/ (如何配置tileserver-gl的config.json)