Cesium应用篇:2影像服务(下)


文章中相关范例下载路径:https://yunpan.cn/cByQqkANWN7Pu 访问密码 823d

      上篇主要介绍了Cesium自带的影像Provider ,在本篇中,我们主要涉及到如何扩展这些服务,能够支持天地图,Google Maps等自定义影像服务。

扩展影像服务

天地图影像服务

      以国内数据的范畴来看,个人认为最佳,一来是数据内容和完整性,二来是不用许可无偏移,三来浏览速度还是很不错,国内其他影像服务能够满足这三点的并不多。

      天地图影像服务都是全球范围,分为墨卡托投影和经纬度两种坐标系,后者标识的是CGCS2000坐标系,对我这样的非专业人士,我等同于WGS84。另外,天地图提供了中英文的注记,也是很不错的。

      首先我们看一下墨卡托投影的全球影像图,遵循WMTS规范,服务URL如下:

http://t0.tianditu.com/img_w/wmts

      首先,通过天地图的GetCapabilities信息,获取其相关的参数,重要信息如下:

      通过红框处,我们可以知道,该WMTS服务的url,Layer的Name,Style,Format以及TileMatrixSet等关键属性的值。有了这些属性,我们就可以通过

      创建天地图不麻烦,但如何更好的创建呢?比如轮询机制,我们知道天地图提供了't0','t1','t2','t3','t4','t5','t6','t7'8个域名,服务端TCP最大链接数是有限制的,轮询机制下瓦片下载的速度更有保证,很可惜,尽管Cesium提供了subdomains的属性,但需要把url按照format的方式来指定参数 ,所以我们需要稍微调整一下构建过程,把我们需要的参数都format到url中 ,代码如下:

      尽管这个url确实很长,自己手动拼这样一个url是要花一点时间,不过毕竟在性能上得到了优化,也算是劳有所得。

      看上去天地图大功告成了,别着急,还有最后一个地方要交代清楚。刚才我们都是用的墨卡托投影,而Cesium大多也是默认Provider是按照墨卡托投影的,但天地图也提供了经纬度的影像服务,虽然叠到地球上都一个样子,但空穴不回来风的,肯定有它存在的价值(经纬度的价值稍后再说),那我们看看经纬度的天地图如何加载?

      和前面的思路完全一样,但在创建Provider时需要同时构建tilingScheme,指定其为经纬度坐标系即可,代码如下:

      创建经纬度的天地图需要注意两个地方,一个是tilingScheme,指定为经纬度,另一个就是tileMatrixLabels,因为level是从1开始(而不是0),所以需要指定每一层级的索引号。

Google Map影像服务

      坦白说,GoogleMap的影像服务有些不实用,国内限制多,需要申请key,而且,关键是水印太多,每一个Tile都会有水印,但我们还是再次提供一下。创建GM和创建ArcGIS比较类似。

      首先,GM的url格式如下:

http://maps.googleapis.com/maps/api/staticmap?maptype=satellite¢er={y},{x}&zoom={level}&size=256x256&key={key}

      指定中心点和级别,以及key。Key需要个人申请,而中心点和级别则需要根据xyz的行列号自己来计算,在googlemap的范例里面已经实现,此处不介绍实现思路,有兴趣的可以看代码注释。基于这个类,可以很简单的加载Google Map影像服务,当然,你要申请自己的Key:

      通过Cesium自带的Provider以及扩展的Provider,基本上涵盖了所有的Provider,至于没有涵盖的,其实现思路也都如出一辙,但除了百度地图。因为其行列号是从经纬度(0,0)开始的,所以存在一个墨卡托xyz到百度xyz的映射过程,我在baidu.html中也实现了该Provider,不过你可以看到,没法用,所以一笔带过。

      除此之外,Cesium在新版本中还提供了TileCoordinatesImageryProvider和GridImageryProvider两个Provider,个人认为这两个主要为开发人员提供的,如果有兴趣可以参考Cesium自带范例,也提醒一下TileCoordinatesImageryProvider默认是按照墨卡托投影的,如果你需要经纬度的瓦片切分方式,则需要指定tilingScheme属性,和经纬度的天地图属于同一个问题。而其实现看上去很专业,其实是在Canvas中绘制成一个Image,然后作为Tile贴到球上去的,也算是二维和三维一个很好的结合效果展现,让我想起了风向图。

常见问题

多个Provider叠加

      这是一个非常基本的功能,毕竟很难用一个Provider满足用户的业务要求,比如有一个全球影像,但同时有一副全美人口密度专题图,是否能够叠加上去?

      看似简单,其实里面涉及到很多细节问题,叠加顺序涉及到渲染队列的优先级,两幅影像的投影不一致怎么办?如果全美人口密度专题图不是全球范围,只是美国范围,这样叠加是否能够准确?

      Cesium很好的解决了这些实际中的问题,简单说每一个Provider都对应一个tilingScheme,支持经纬度和墨卡托两种投影方式,默认是全球范围,用户也可以指定其范围,Cesium内部会根据这些参数来实现叠加效果。可以指定每一个ImagerLayer的Style。

       ImageryLayerCollection类是一个图层管理器,可以调整多个图层之间的顺序,添加和删除等。详细内容可以查看Cesium接口文档或本章的MultiProvider.html范例。

性能

      刚才说了,支持经纬度和墨卡托两种方式,而且效率都很不错,那我们该如何选择呢?当然是有什么就用什么了,但相比而言,经纬度的效率要快一些。可惜墨卡托的影像更丰富一些。为什么经纬度的效率高,这要牵扯到地形数据,以及动态投影的计算,后面在介绍Cesium地形原理时,会详细的阐述,这里我们只需要知道这个性能考虑因素就可以了。

水印

      有很多人希望去掉这个,很简单,在js中添加这句话即可(可参考MultiProvider.html范例):