目录
- 1 前言
- 2 数据介绍
- 3 切片方案及技术难点
- 3.1 大数据量图层矢量切片无法正确返回结果
- 3.2 矢量切片标注过程中标注拥挤
- 3.3 矢量切片每一块切片都进行了标注,形成了冗余
- 3.4 矢量切片标注的随机性会造成时而在中央,时而在边界上
- 3.5 特殊样式的制作
- 3.6 图层组之间的冲突
- 3.6.1 数据量过大
- 3.6.2 显示前后矛盾
- 3.6.3 先加进去的后显示
- 3.6.4 图层组和图层组之间不能通过设置zIndex调整顺序
- 4 openlayers样式常用参数说明
- 5 openlayers点线面参数举例
- 6 效果图
- 7 总结
1 前言
本文于产生于一个特殊的需求,即能否在前端控制底图里各种图层的显隐?比如天地图中的道路、河流?答案显示是不行。为什么?因为天地图是后端渲染,前端拿到的只是一张图片而已,是没法控制图片里的图层的。那有没有办法来解决这一需求呢?答案是当然有。在前端渲染矢量切片,当需要隐藏的时候,将某一属性的图层直接设置样式为空就可以了倍。
另外作者注意到,百度地图和高德地图现在都已经将渲染方式改为了在前端渲染矢量切片的方式了。但是二者在标注时使用的技术上稍微有点不同,高德是把标注数据和切片数据放在一起了,而百度使用的是精灵图方式。感兴趣的朋友可以自行查看。
2 数据介绍
本文渲染的数据为全球的shp数据,共53个图层,1670万条数据,为了增加数据的读取效率,数据存储在 PostGIS 中,使用 GeoServer 发布矢量切片。
3 切片方案及技术难点
首先可以肯定的是不能像后端渲染那样,把所有图层都放在一个图层组里,然后做矢量切片,因为这样做,会导致切片非常大,一个切片几十兆。所以,我们现在就要考虑几个难点了。
3.1 大数据量图层矢量切片无法正确返回结果
解决办法:分组进行切片,如0-5级,5-10级,10-15,15-20级进行展示的数据分批进行切片。在第0级就显示居民点明显是不合适的,矢量切片的过程并不会考虑这种情况,只会把所有数据都拿来切,切完了能不能正常返回,也不关心。因此就需要人为进行干预。
3.2 矢量切片标注过程中标注拥挤
解决办法:设置layer的declutter属性,declutter意为整理,当范围太小,放不下标注时,会自动隐藏该标注。这种情况尤其适合当地图缩放到低层级时的出现的拥挤情况。
3.3 矢量切片每一块切片都进行了标注,形成了冗余
解决办法:记录当前层级下,当前图层,当前名称,是否标注了,如已标注,不在重复标注,当层级缩放时,清空记录,重新渲染。
3.4 矢量切片标注的随机性会造成时而在中央,时而在边界上
解决办法:单独形成需要标注的图层,以点的形式进行存储,这种情况适用于面图层和线图层,比如陕西省和黄河两个图层,都会被切为多个瓦片,每个瓦片都会进行标注,由于瓦片被请求到的顺序依赖于网络环境,因此有可能边界的瓦片先被请求到,中央的瓦片后被请求到。因为当前标注策略是,第一次请求才会进行标注,因此很有可能标注在边界上。所以应提取中央的点,作为独立的标注图层。
3.5 特殊样式的制作
关于特殊样式的制作,可以参考作者的另外两篇博文
如何在openlayers中使用iconfont或font Awesome字体图标
openlayers铁路公路桥梁隧道及导航样式参考
3.6 图层组之间的冲突
这个问题我们来详细解释一下,什么叫做图层组和图层组之间会存在冲突?要理解这个问题,我们首先要讲下分组方案。最初我们是把所有的面图层放在一个图层组,所有的线放在一个图层组,所有的点放在一个图层组,共3个图层组。然后在前端去渲染。
3.6.1 数据量过大
显然这样是有问题的,为什么?因为有些面是要在十几级才显示的,比如湖泊,县、乡、村;而有些面是要在前几级就进行显示,比如国家、省、市。那么按照我们目前的分组方案,会造成单个切片的数巨量大的问题。这一点我们在3.1节讲过了。
3.6.2 显示前后矛盾
按照目前的分组方案,世界的首都,这个点图层,是很早就要显示的,但是这个图层是在后面才加进来的。那么会造成什么问题?那就是要显示的时候,发现没数据。因为后面加进来的图层我们的设置是,从第10级开始切,但是现在要第3级就要显示,明显是冲突的。
3.6.3 先加进去的后显示
还有一些图层,比如医院、大学、火车站的面数据,这是数据是在十几级才去显示,按理说应该很晚加进去,但是很晚加进去以后,又会发现会覆盖前面加进去的线和点。所以必须把这些图层单独提出来形成一个图层组。最后,那就是要很早进去的,很晚才显示的,又形成一组。
3.6.4 图层组和图层组之间不能通过设置zIndex调整顺序
一个图层组中的图层,可以通过调整 zIndex 在这个组内调整层级,但是不能调整和另一个图层组里的图层的顺序。这句话读起来有点绕,我们来解释一下。
1.一个图层组,里面包含了很多图层,每个图层我们都可以通过 zIndex 调整层级。
这句话应该好理解,就是在组内调整顺序嘛
2.不能通过调整 zIndex 来调整A图层组里的A.2和B图层组里的B.3
这是因为 zIndex 参数只在所属的图层组里起作用,map 也是一个图层组。要想调整A图层组里的A.2和B图层组里的B.3,只能通过调整A图层组和B图层组的顺序来实现。
4 openlayers样式常用参数说明
5 openlayers点线面参数举例
6 效果图
7 总结
本文通过渲染1600万数据量的矢量切片,系统的剖析了矢量切片渲染过程中的技术难点,并将 openlayres 中常用的样式参数进行了举例说明,最后形成了一套全球矢量切片的渲染图。结合作者实际经历,在渲染过程中需逐个图层进行比对,实时的调整前端样式,和后端分组方案,更需耐心和细心,希望读者共勉。好了,本文就分享到这里,下期见~