ST_TileEnvelope这个函数,是配合st_mvt等函数将geom数据返回成矢量瓦片显示在页面上的,但是网上搜到的大部分使用方式是这样的:
SELECT
ST_AsMVT (a, 'points',4096,'geom') As tile
FROM
(
SELECT t.id,
st_asmvtgeom (t.geom,
ST_TileEnvelope(${z},${x},${y},st_makeenvelope (-180,-180.66,180,179.34, 4490)),
4096,
0,
false
) AS geom
FROM
test t
) AS a
简单来说,就是这个函数不用自己去主动处理xyz参数,去进行经纬度的转换,而是直接根据后面st_makeenvelope函数或者直接给定的范围,去进行瓦片的分割计算,并将数据库种包含在瓦片中的要素查询返回矢量二进制到页面上。
但是这种自己设定范围的方式,实际上比较麻烦,因为手动设定后,返回的要素位置会根据设定的范围进行拉伸或者位移,所以当手动设定的范围不是正方形,即横纵坐标的差值不相同时,原来的要素会等比例被拉伸。而且目前没有发现这个中心点是以什么为标准的。
-180,-180.66,180,179.34
比如这个范围参数,是我使用mapbox进行渲染的时候调试的,可以保证原本要素不会被缩放或者伸缩在对应标准地图的位置上,目前没有找到这个的计算方式。
后来在官网对这个函数的介绍中,发现另一种加载方式,可以根据坐标系自动设置范围,不需要手动加入:
可以看到,这里案例可以直接传入xyz参数,函数会自动计算,但是返回的是墨卡托投影坐标系参数下的数据,因此需要将数据库的geom数据转换成对应墨卡托投影的坐标系,才能将范围内的要素找到:
SELECT
ST_AsMVT (a, 'points',4096,'geom') As tile
FROM
(
SELECT t.id,
st_asmvtgeom (
ST_Transform(t.geom, 3857)
ST_TileEnvelope(${z},${x},${y} ,4490),
4096,
0,
false
) AS geom
FROM
test t
) AS a
这样输出的就是函数自己转换的xyz参数下的瓦片数据了,而且这种方式返回的矢量瓦片,也可以避免页面显示时放大缩小图像会偏移的问题。个人感觉一般情况下比手动输入范围要好用点。
注意:
如果使用自己手动添加范围的方式,那数据库geom字段可以不需要ST_Transform进行转换,但是只要是自动判断范围的方式,数据库geom字段必须要使用ST_Transform进行转换成对应坐标系参数下的数据,否则页面无法显示。