用PostGIS生成mvt格式的矢量瓦片
条评论PostGIS 从 2.4.0 版本开始支持通过 box 生成 mvt 数据,我们用尽可能简单的方法搭建一个生产 mvt 数据的测试数据库。
基础工作环境:
1. 数据源
从geofabrik上我们可以下载的分好地区的OpenStreetMap数据,这样可以得到一个比较小的测试数据集。可以通过下面的地址下载到最新的中国区域数据:
# 直接下载国区的数据 |
2. 准备 PostGIS 环境
我们直接用mdillon/postgis的 docker 镜像跑一个 PostGIS 数据库:
# 创建一个名称为gis网络 |
这个镜像可以通过POSTGRES_PASSWORD
指定数据库密码,如果没指定的话,密码会和POSTGRES_USER
即用户名保持一致。
建议通过-p 5432:5432
映射下端口,方便我们在宿主机上直接连接调试。
3. 导入 osm 数据到 PostGIS
我们用imposm3来导入 osm 数据到库中。
imposm3 主要需要配置 cache 目录(可选),connection 链接地址(必须)和 mapping 映射文件(必须)三个参数,官方仓库提供了一个mapping 样例供参考。这里我们方便测试,就用这个简单版本,定义了admim、amenities、buildings
三张表。
准备一个文件夹,把下载的 pbf 和 mapping 文件丢进去,再创建 cache 目录
依然用上强大的 docker,jawg/imposm3可以帮助我们方便的执行 imposm3 操作。
docker run --network gis --rm \ |
耐心等待导入完成,可以直接进入 docker 查看数据情况:
docker exec -it postgis psql gis gis |
或者通过第三方软件连接数据库,可以看到 import 导入的三张表:
4. 执行 SQL 脚本
在数据库中执行 mapbox 提供的TileBBox脚本,创建 TileBBox 函数
https://github.com/mapbox/postgis-vt-util/blob/master/src/TileBBox.sql |
这个函数的作用就是传入指定的x,y,z
瓦片序列,转换成 MVT 需要的tile coordinate space
,通常是 4096x4096 的网格
5. 测试数据结果
mvt 瓦片生成的关键就是ST_AsMVT和ST_AsMVTGeom两个函数,所以可以直接调用来做个测试,这里查询z=14,y=12917,6430
的瓦片对应的 mvt 数据
先查询出范围内的 geometry,并转化成 mvt 需要的格式
SELECT ST_AsMVTGeom( |
得到结果应该如下:
再使用 ST_AsMVT 进行转换就行,完成的合并后的 sql 如下:
SELECT ST_AsMVT(q, 'osm_mvt', 256, 'geom') AS mvt |
6. 数据展示
完整的地图区域数据前端展示可以使用 tilestrata 这个服务端工具,配合 tilestrata-postgismvt 插件就可以生成供地图调用的瓦片。
具体的 demo 项目可以参考tilestrata-sample-code
对应的文章可以看一下这篇tilestrata-postgismvt 使用
clone 项目tilestrata-sample-code,将项目里面src/mvt/
目录下index.js的pgConfig
改成你的设置
安装依赖,启动项目
npm install |
访问example/mvt.html
就可以看到结果了。
我们导入了三张表,分别是边界数据(蓝色)、设施(红点)和建筑(紫色),全部叠加之后如下图所示: