PostgreSQL+Postgis MapboxVectorTile应用

该博客介绍基于Postgres+Postgis搭建实时矢量瓦片服务。阐述矢量瓦片优势,如支持高分辨率显示、解决传统栅格瓦片样式问题等。说明了实时矢量瓦片特点,还介绍使用的相关函数。给出软件环境,详述实现过程,包括模拟数据、部署扩展函数、编写后端接口和前端代码,最后展示结果。

背景

该实验基于Postgres+Postgis搭建实时矢量瓦片服务。
矢量瓦片的优势

  1. 可以支持高分辨率屏幕显示
  2. 地图渲染在前端,可以支持前端随意更改配图方案,解决传统栅格瓦片动态样式上的问题
  3. 要素查询可以在前端进行
  4. 保持了矢量数据的优势,同时采用切片方式在传输效率上有一定提升

实时矢量瓦片

不在线下用工具预先切片,采用即时浏览传输矢量瓦片;
采用实时矢量切片可以做到数据编辑功能,同时解决数据时效性问题

使用到的相关函数

ST_AsMvtGeo 将Geom转化为MVT的geom
ST_AsMVT 将geom转换为MVT数据
ST_TileEnvelope 根据行列号获取Envelop (该函数需要Postgis3.0才有,使用postgis-vt-util代替

软件环境

  • PostgreSQL11
  • Postgis2.5
  • java
  • (前端渲染) leaflet1.7、mapbox

实现过程

模拟数据

使用sql语句创建表,并在给定坐标范围内模拟点数据

CREATE TABLE data_1000000 AS SELECT
( ST_Dump ( ST_GeneratePoints ( kl.geom, 200000 ) ) ).geom AS geom,
md5( ( random ( ) * random ( ) ) :: text ) AS id,
random ( ) * 1000 AS val 
FROM ( 
  SELECT ST_SetSRID ( ST_MakeBox2D ( ST_Point ( 113.213316,22.954094 ), ST_Point ( 113.62805,23.368228 ) ), 4326 
) geom ) kl;

sql解读:
创建表名:data_1000000
坐标范围:左下角坐标(113.213316,22.954094)、右下角坐标(113.62805,23.368228),坐标系SRID为4326
模拟数据量:100万
表字段:geom(空间字段)、id(md5格式的唯一编码)、val(点的权重值0-1000)

部署扩展函数

由于需要用到ST_TileEnvelope函数,该函数需要postgis3.0才支持,所以使用扩展的函数库实现(postgis-vt-util下载)
执行postgis-vt-util.sql添加相关函数到数据库

这个库由mapbox提供,生成符合mapbox矢量切片格式的数据

后端接口

后端需要实现前端请求切片范围的矢量切片生成,传入的参数可能是行列号或者经纬度范围,最终返回byte的矢量切片数据

处理逻辑

graph LR
start("前端请求") --> isEnvelop("是否传入经纬度范围")
isEnvelop --no--> tileBBox("根据切片z,x,y转换经纬度范围")
isEnvelop --yes--> makeEnvelop("生成几何范围")
tileBBox --> makeEnvelop
makeEnvelop --> asMVTGeom("将几何图形转为mapbox矢量瓦片坐标")
asMVTGeom --> asMVT("返回mapbox矢量切片的byte数组")

点线面在转换byte数组时需要分开处理

代码编写

//根据切片xyz获取矢量切片
public byte[] getMVT(String tableName, int x, int y, int z, int srid) {
   
   
    byte[] res;
    try {
   
   
        String sqlStr = "SELECT " +
                "ST_AsMVT( vt, 'points', 256, 'geo' ) FROM ( " +
                "SELECT ST_SetSRID ( ST_Point ( ST_X ( A.geo ), ST_Y ( A.geo )), " + srid + " ) geo FROM (" +
                "SELECT ST_AsMVTGeom ( w.geom, Box2D ( TileBBox ( " + z + "," + x + "," + y + ", " + srid + " )), 256, 0, TRUE ) AS geo  " +
                "FROM " + tableName + " w  WHERE TileBBox ( " + z + "," + x + "," + y + ", " + srid + " ) && geom  ) A  " +
                "GROUP BY ST_X ( A.geo ), ST_Y ( A.geo ) ) AS vt"
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值