方案背景
2018年三月份写了一篇postgis计算矢量切片,参考了网上资料给出了一份很粗糙的相关方案(文章写的更粗糙)。当时的方案中只能针对gis形状进行渲染,而不能用属性渲染.针对这个情况,本文进行相对应的修改。
前期准备
软件是用的是Qgis和Postgis(Postgis版本为2.42 ,Postgresql版本为10.0)。qgis使用Ramdom points in extent 用来生成测试数据,数据范围参数使用
120.6327590942379970,120.8625335693359943,31.2309341430663991,31.4467678070068004(xmin,xmax,ymin,ymax),数据量设置为十万。生成好数据,再建好索引,添加字段v,根据奇偶性给字段赋值。
后台梳理
先看了STAsMVT和STAsMVTGeom帮助文档,一头雾水.使用谷歌大法,发现了这个资料参考资料
![c24fa9ffaa65bf886ad73b4504989817.png](https://i-blog.csdnimg.cn/blog_migrate/cd381b9c2d1507bfe02fea1feadd4e9f.jpeg)
只要通过上图的方式就能查询到我想要的带属性值的矢量切片,代码如下。只要先输入需要查找的范围,用STAsMVTGeom查询出范围内矢量并转换成屏幕坐标,最后用STAsMVT压缩数据成mvt格式,和之前文章有所不同的是,查询过程中加入了属性的查询,压缩之后矢量切片就会带上我们想要的属性值(w.v就是我们想要的属性值)
SELECT ST_AsMVT(tile,'points',4096,'geom') tile FROM (SELECT w.v,ST_AsMVTGeom(w.the_geom,Box2D(ST_MakeEnvelope(119.531250,30.751278,120.937500,31.952162, 4326)),4096, 0, true) AS geom FROM pnt w) AS tile where tile.geom is not null
做完这些我们只要用后台语言写一个服务,将前台请求的切片坐标z/x/y这些转换成经纬度得到最大最小经纬度,放到前面提到的sql中去查询就可以。
前台展示
前台展示还是选用mapbox,添加自定义矢量切片数据源,修改下按值渲染颜色
map.addLayer({"id": "custom-go-vector-tile-layer","type": "circle","source": "custom-go-vector-tile-source","source-layer": "points",paint: {'circle-radius': {stops: [[8, 0.1], [11, 0.5],[15, 3],[20, 60]]},'circle-color': {property: 'v',stops: [[0, '#990055'],[1, '#2a55b9']]},'circle-opacity': 1}});
显示效果如下
![bc1facbb456ae17766f74c0eb2c05eb1.png](https://i-blog.csdnimg.cn/blog_migrate/c4d3cc9e4a860bae24367ace67a0f40c.jpeg)
性能对比
一百万数据,页面加载结束5s;十万数据,页面加载结束1.86s.同样数据,百万数据,geoserver的(openlayer)页面加载结束20.20s;十万数据时,geoserver的的(openlayer)页面加载结束4.32s
附代码地址:
https://github.com/tpolong/postgisvectortile