SuperMap iClient3D for WebGL/Cesium端性能优化

       在GIS项目中,SuperMap iClient for WebGL / Cesium 加载的服务图层很多、种类也很多,经常会出现少部分数据可以,但是大批量数据加载进来会出现掉帧严重,性能急速下跌,甚至导致浏览器崩溃的情况。本文争对这种情况来罗列出了下列四大类性能优化的方案,供GIS用户参考使用。

一、请求优化

1.1 多子域

       由于浏览器对同一个域名服务的并发请求数量有限制,是6个,所以运行大场景三维需要用到多子域。通过Nginx 服务搭建多个子域名,加大向SuperMap iServer 发送数据请求的并发量,从而达到提升加载速度的目的。

描述:利用Nginx客户端,映射不同的端口地址来对SuperMap iServer进行访问,搭建子域环境,提升性能。

应用场景:充分利用SuperMap iServer机器的硬件性能,加大并发量,提升加载速度。

Nginx 服务如何搭建多个子域名请详见博客:Nginx服务搭建多个子域名

SuperMap iClient3D for Cesium支持多子域加载地形、影像、S3M以及MVT,关键接口是subdomains(获取或者设置子域名称。通过该接口可以向指定的子域请求数据具体代码如下:

1.1.1 scene.open()打开场景

var promise = scene.open("http://{s}/iserver/services/3D-CBD/rest/realspace",undefined,{
                subdomains:['localhost:8090','localhost:8092']
            });
            viewer.flyTo(promise);

1.1.2 加载地形

var viewer = new Cesium.Viewer('cesiumContainer',{
            terrainProvider:new Cesium.CesiumTerrainProvider({
                url:'http://{s}/iserver/services/3D-SiChuanDiXingYingXiang/rest/realspace/datas/DatasetDEM',
                isSct : true,//是否为iServer发布的TIN地形服务,stk地形设置为false。
                subdomains:['localhost:8081','localhost:8082','localhost:8083'],//获取或者设置子域名称。通过该接口可以向指定的子域请求数据。
                invisibility:true//是否开启设置地形显隐的功能,默认为false。
            })
        });

1.1.3 加载影像

var imageLayer = viewer.imageryLayers.addImageryProvider(new Cesium.SuperMapImageryProvider({
                url:"http://{s}/iserver/services/3D-SiChuanDiXingYingXiang/rest/realspace/datas/MosaicResult",
                subdomains:['localhost:8081','localhost:8082','localhost:8083']
            }));
            viewer.flyTo(imageLayer);

1.1.4 加载S3M

 var config = {
            subdomainConfig: {
                urlScheme: " http://{s}/iserver/services/3D-CBD/rest/realspace",
                subdomains: ['localhost:8081', 'localhost:8082', 'localhost:8083']//设置子域
            },
            name: "building"
        };

        var promise = viewer.scene.addS3MTilesLayerByScp('http://localhost:8090/iserver/services/3D-CBD/rest/realspace/datas/building/config', config);
        Cesium.when(promise, function (layer) {
            viewer.flyTo(promise);
        })

1.1.5 加载MVT

var mvtMap = scene.addVectorTilesMap({
               url:"http://{s}/iserver/services/map-mvt-GLDZJSYDSPDKBZD/restjsr/v1/vectortile/maps/GL_DZ_JSYDSP_DKB_ZD",
               subdomains:['localhost:8081','localhost:8082','localhost:8083'],
               canvasWidth:512,
               name:'testMVT',
               viewer:viewer
            });

加载效果:从网络请求里看是否有不同端口的请求,比如'localhost:8081', 'localhost:8082', 'localhost:8083'。

1.2 批量请求

批量请求可以加快图层的下载请求速度,地形和影像图层支持批量请求。

1.2.1 地形

如果是 10.1 之前的SuperMap iDesktop版本,TIN 地形要生成紧凑存储类型,在前端开启批量请求,也能体验 10.1 版本块存储的加载效果,块存储的数据不需要再加 packingRequest:1 这行代码。

var provider_terrain=new Cesium.CesiumTerrainProvider({
url :'url',
isSct : true,//地形服务源自SuperMap iServer发布时需设置isSct为true
packingRequest:1//批量请求
})

1.2.2 影像

为了加快影像的下载速度,使周边切片一次请求下来,需要用到批量请求packingRequest:1 这行代码。

var provider= new Cesium.SuperMapImageryProvider({
					url: 'url', 
					packingRequest: 1//批量请求
				});"

二、内存优化

2.1 根节点驻留内存

根节点驻留内存residentRootTile是为了屏幕区域外不清除根节点内存。而这个前提还需要设置保存根节点indexedDBSetting.isGeoTilesRootNodeSave,这个是为了将缓存根节点下载保存到本地,根节点不需要重复下载当清除浏览器缓存后,本地缓存也将被清除掉。所以当请适当选择清楚浏览器缓存

var layer = scene.layers.find('Config');//打开倾斜数据的Config图层
layer.indexedDBSetting.isGeoTilesRootNodeSave = true;//设置是否保存根节点
layer.residentRootTile=true;//设置根节点是否驻留内存不删除

2.2 自动释放缓存

S3MTilesLayer.clearMemoryImmediately是否及时释放内存,默认值为true。其表现在加载倾斜或者其他S3M图层完全加载到了客户端,但是一转动视角,不在视野范围内的模型消失(这是默认的渲染机制,为了保证性能),再把视角转回来,它会继续加载(按说数据已经加载过了)。

S3MTilesLayer.clearMemoryImmediately=true;//及时释放内存(默认)

当然,上述这种不在视野范围内模型就消失的情况,也有项目不满足这种需要,他们希望模型一直都在,这时就需要将clearMemoryImmediately设置为false,则还需要设置缓存空间的大小setCacheSize,不然浏览器内存不够会造成页面崩溃。

S3MTilesLayer.clearMemoryImmediately=false;//不及时释放内存
Cesium.MemoryManager.setCacheSize(4096);//设置缓存空间的大小,单位为MB

2.3 内存管理

实际项目中经常会遇到下图这种渲染错误,出现这种报错需要从很多方面考虑,比如硬件显卡、浏览器内存、数据等。其中浏览器内存至关重要,可以设置场景总的显存资源占用阈值,根据机器内存显存大小,适当调整这个值,可以避免因为资源占满导致的崩溃,由于用户机器差异较大,这个值在Web端也没法获取到,因此产品包中设置的默认大小4GB,建议您们根据实际情况在前端设置(如果阈值太小会导致数据加载不全的问题)。

scene.context.memoryThreshold = 6;//显存资源占用阈值,单位是GB。

超过内存,修改设置最大内存,防止内存超限导致崩溃。设置以下这两个参数,出现不加载的情况就会少了一些。

 Cesium.MemoryManager.showMemoryInfo(true);//显示内存调用
 Cesium.MemoryManager.setMaxMemory(4096);//设置最大内存

三、图层优化

3.1 LOD

LOD机制使数据拥有不同的精细层级,在特定的情境下使用合适精细层级可提高数据的浏览效率,降低场景帧率。在SuperMap iDesktop中,对模型数据集生成缓存时默认构建3层LOD。在SuperMap iClient3D for Cesium中,场景通过数据与相机的直线距离来调度显示不同LOD,每一个LOD层级之间的切换距离大约是1000米。

举个例子:当相机距离模型3000米以上时,显示第一层LOD,当相机距离模型2000米-3000米时,显示第二层LOD,当相机距离模型小于1000米时,显示第三层LOD。

根据业务需求,SuperMap iClient3D for Cesium中可调整LOD层级的切换距离:

S3MTilesLayer.lodRangeScale = 1   //图层层级缩放比例系数

该值默认为1,如果想要在远距离时加载精细层LOD,将该值调小,同时会导致加载数据量变大;如果对场景性能要求高,将该值调大,同时会导致数据相对模糊。

3.2 空间索引

SuperMap iClient3D for Cesium中有4种数据加载模式,分为深度优先、层优先、空间索引、深度优先非线性切换。默认为深度优先。

采用空间索引加载方式,可减少LOD层级切换,从而提高加载到数据精细层LOD的速度

(ps:需要结合数据使用,SuperMap iDesktop 11i及以后缓存的数据可直接使用空间索引,SuperMap iDesktop 11i之前缓存的数据,需要用新版本桌面对缓存图层右键【创建空间索引】)

S3MTilesLayer.LoadingPriority = Cesium.LoadingPriorityMode.UsePagedLodInfo //空间索引加载模式

3.3 控制图层显示范围

控制图层显示范围是指影像加载只显示指定区域内,其他隐藏。SuperMap iClient3D for Cesium 11i及以后版本支持自定义多边形范围裁剪影像图层。可以前往官网SuperMap技术资源中心|为您提供全面的在线技术服务下载SuperMap iClient3D 11i (2022) SP1 for Cesium包,代码如下:

viewer.scene.globe.addImageryClipRegions({
    position: positions,
    layers: [imageryLayer],
    name: "test"
})//控制影像图层显示范围

3.4 控制图层显隐

在满足业务需求的前提下,减少场景中的模型渲染量,比如,浏览地上数据时隐藏地下数据,浏览地下数据时隐藏地上数据,浏览室外数据时隐藏室内数据......

S3MTilesLayer.visible = false  //隐藏图层

3.5 最大最小高程/距离

在满足业务需求的前提下,减少场景中的模型渲染量,适用于大场景下可以不显示,相机拉近再显示的图层

S3MTilesLayer.visibleDistanceMax = 1000;  //最大可见距离值,单位为米
S3MTilesLayer.visibleDistanceMin = 100;   //最小可见距离值,单位为米
S3MTilesLayer.maxVisibleAltitude  = 1000;  //最大可见高度值,单位为米
S3MTilesLayer.minVisibleAltitude  = 100;   //最小可见高度值,单位为米

3.6 最大最小层级

对于影像数据而言,可设置最大最小请求层级

var layer = viewer.imageryLayers.addImageryProvider(new Cesium.SuperMapImageryProvider({
      url: URL_CONFIG.SiChuan_IMG,
      minimumLevel:2,    //最小请求层级
      maximumLevel:8     //最大请求层级
    }));

四、属性优化

4.1 开启indexDB

在SuperMap iClient3D for WebGL 10i以及之后版本中,提供了indexedDB缓存功能,通过设置S3MTileslayer中的indexDBSetting属性开启缓存机制,开启之后首次访问下载的s3m文件将被写入indexedDB数据库中,再访问时将从indexedDB中直接读取,极大提高二次浏览性能。同时indexedDB也支持大量数据的存储,以及索引查询。

indexDBSetting获取或者设置indexedDB属性信息(IE浏览器不支持)。其中,在设置indexeDB属性时, 有三个布尔类型的分支属性:isGeoTilesSave——是否保存切片; isAttributesSave--是否保存属性;isGeoTilesRootNodeSave--是否保存根节点。

开启indexedDB之后的客户端缓存,这些缓存的文件都在浏览器的安装目录下,一般是在C:\Users\CYKJ\AppData\Local\Google\Chrome\User Data\Default\IndexedDB目录下。

开启代码:

 var layer = scene.layers.find('Config');
 layer.indexedDBSetting.isGeoTilesRootNodeSave=true;

4.2 专题图

4.2.1 字段专题图

       前端项目中用户往往有对s3m图层(这里指线、面和白模数据)根据属性信息赋予不同颜色的需求。虽然咱们前端可以支持SQL查询获取属性对象信息,实现上面需求思路是根据不同字段属性查出对应图元ID数组,再根据图元ID数组用接口setObjsColor(ids, color)来设置对应的颜色。这种流程可以走下来,但是往往查询渲染起来特别慢,这时我们就可以用前端做字段专题图的方法来提升它的性能。

下面是前端制作字段专题图的关键代码:

 //生成缓存时需要在桌面软件中把“属性存储类型”改为“ATTRIBUTE”在web端会根据指定属性字段设置专题图。
        var infos = [
            {
                url: 'http://www.supermapol.com/realspace/services/3D-bjBaiMo/rest/realspace/datas/bjBaiMo3/config',
                cullEnabled: true,
                queryFieldNames: ['name']
            }
        ];
        
//默认是layer.indexedDBSetting.isAttributesSave=true,会开启图层的全部属性字段下载,数据量大会影响性能
S3MTilesLayer.queryFieldNames = ['name'];//指定仅下载需要的属性字段,提升性能;桌面缓存生成时,‘属性存属类型’需要选择ATTRIBUTE才支持
S3MTilesLayer.themeStyle = new Cesium.Cesium3DTileStyle({
							color: {
								conditions: [//根据字段的不同属性值赋予不同颜色
									['${name} === "北京"', 'color("purple")'],
									['${name} === "上海"', 'color("yellow")'],
									['${name} === "成都"', 'color("green")'],
									['false', 'color("blue")']//当属性值不符合上述条件时,设置该颜色
								]
							},
							//show: '${name} === "成都"',//只显示字段符合该属性值的对象,其它不满足的会被过滤掉
						});

4.2.2 标签专题图

       在GIS项目中将标签、图标在SuperMap iDesktop中做好后生成场景缓存,在SuperMap iServer发布三维服务,在前端代码加载会出现下图这种图标和标签密密麻麻的现象,这种可视效果差而且还影响性能。

那我们可以同时开启图标和标签避让,来达到视觉美观和提升性能的效果。具体代码见下图:

var iconlayer = scene.layers.find('BusPoint@RealspaceSample');//图标图层
var textlayer = scene.layers.find('BusPoint@RealspaceSample#1');//文字图层
iconlayer.isOverlapDisplayed = false;//开启图标避让
textlayer.isOverlapDisplayed = false;//开启标签避让
iconlayer.iconRelatedTextLayerID = textlayer.id;//图标随着文字避让而避让

效果如下:

4.3 属性查询

SuperMap官网WebGL范例里对模型进行属性查询,用到三种方法:

(1)模型数据集发布数据服务进行查询;

(2)模型数据集转成二维面数据集或者属性表,对二维面或者属性表发布数据服务进行查询;

(3)通过模型缓存进行属性查询。

上述查询方法各有优缺点,小编整理了根据不同数据类型发布服务在前端进行查询的功能对比,如下图所示:

可以根据自己的项目需求选择适合自己的属性查询方式。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值