|  | @@ -26,31 +26,58 @@ Date.prototype.Format = function(fmt) { // author: meizz
 | 
	
		
			
				|  |  |  /* 引入Cesium */
 | 
	
		
			
				|  |  |  import * as Cesium from 'cesium';
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -import CrImageMaterialProperty from './CrImageMaterialProperty.js'
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |  /* 创建类 */
 | 
	
		
			
				|  |  |  class CrImageServerLayer {
 | 
	
		
			
				|  |  |  	/**
 | 
	
		
			
				|  |  |  	 * 构造函数
 | 
	
		
			
				|  |  |  	 * @param {Cesium.Viewer} options.viewer 地图视图容器
 | 
	
		
			
				|  |  | -	 * @param {String} options.url 服务地址
 | 
	
		
			
				|  |  | -	 * @param {Number} options.opacity 图层透明度 [默认0.3]    
 | 
	
		
			
				|  |  | +	 * @param {CrImageServerLayer.ProviderType} options.providerType 数据提供器类型
 | 
	
		
			
				|  |  | +	 * @param {JSON} options.config 对应该提供器的配置参数
 | 
	
		
			
				|  |  | +	 * @param {Number} options.opacity 图层透明度[0.0~1.0] [默认0.3]    
 | 
	
		
			
				|  |  |  	 */
 | 
	
		
			
				|  |  |  	constructor({
 | 
	
		
			
				|  |  |  		viewer,
 | 
	
		
			
				|  |  | -		url,
 | 
	
		
			
				|  |  | -		opacity = 0.3
 | 
	
		
			
				|  |  | +		providerType = CrImageServerLayer.ArcGisMapServerImageryProvider,
 | 
	
		
			
				|  |  | +		config = {},
 | 
	
		
			
				|  |  | +		opacity = 0.75,
 | 
	
		
			
				|  |  | +		show = true,
 | 
	
		
			
				|  |  |  	} = {}) {
 | 
	
		
			
				|  |  | +		/* 地图视图 外部传入 必须参数 */
 | 
	
		
			
				|  |  |  		this._viewer = viewer;
 | 
	
		
			
				|  |  | -		//http://218.59.194.74:6080/arcgis/rest/services/LYLSQ_YX_102100_202112/MapServer/WMTS
 | 
	
		
			
				|  |  | -		//http://218.59.194.74:6080/arcgis/rest/services/LYLSQ_GHT_102100_202112/MapServer/wmts
 | 
	
		
			
				|  |  | -		this._url = 'http://218.59.194.74:6080/arcgis/rest/services/LYLSQ_GHT_102100_202112/MapServer';
 | 
	
		
			
				|  |  | +		/* 服务提供者配置参数 */
 | 
	
		
			
				|  |  | +		this._providerType = providerType;
 | 
	
		
			
				|  |  | +		/* 服务提供者 */
 | 
	
		
			
				|  |  | +		this._provider = undefined;
 | 
	
		
			
				|  |  | +		/* 服务提供者切片方案 */
 | 
	
		
			
				|  |  | +		this._tilingScheme = undefined;
 | 
	
		
			
				|  |  | +		/* 服务的切片的最大/最小层级 */
 | 
	
		
			
				|  |  | +		this._maximumLevel = 0;
 | 
	
		
			
				|  |  | +		this._minimumLevel = 20;
 | 
	
		
			
				|  |  | +		/* 切片大小 */
 | 
	
		
			
				|  |  | +		this._tileWidth = 0;
 | 
	
		
			
				|  |  | +		this._tileHeight = 0;
 | 
	
		
			
				|  |  | +		/* 服务数据范围 */
 | 
	
		
			
				|  |  | +		this._rectangle = undefined;
 | 
	
		
			
				|  |  | +		/* 服务提供者的配置参数 */
 | 
	
		
			
				|  |  | +		this._config = config;
 | 
	
		
			
				|  |  | +		/* 透明度 外部传入 */
 | 
	
		
			
				|  |  |  		this._opacity = opacity;
 | 
	
		
			
				|  |  | -		this._renderName = 'suiji'; //后期要改成随机字符串
 | 
	
		
			
				|  |  | -		this._entities = this._viewer.entities;
 | 
	
		
			
				|  |  | +		/* 图层随机标识 */
 | 
	
		
			
				|  |  | +		this._renderName = this._guid();
 | 
	
		
			
				|  |  | +		/* 实体集合 */
 | 
	
		
			
				|  |  | +		/* 用DataSource 方式 以便进行多图层管理 */
 | 
	
		
			
				|  |  | +		let dataSource = new Cesium.CustomDataSource(this._renderName);
 | 
	
		
			
				|  |  | +		this._viewer.dataSources.add(dataSource);
 | 
	
		
			
				|  |  | +		this._entities = dataSource.entities;
 | 
	
		
			
				|  |  | +		/* 渲染集合 */
 | 
	
		
			
				|  |  | +		this._renderEntities = new Map();
 | 
	
		
			
				|  |  | +		this._renderImagebitmaps = new Map();
 | 
	
		
			
				|  |  | +		/* 是否渲染标志 */
 | 
	
		
			
				|  |  | +		this._isUpdateTile = show;
 | 
	
		
			
				|  |  | +		/* 是否输出测试信息 */
 | 
	
		
			
				|  |  | +		this._isDebug = true;
 | 
	
		
			
				|  |  | +		/* 初始化 */
 | 
	
		
			
				|  |  |  		this._init();
 | 
	
		
			
				|  |  | -		this._updateTiles = [];
 | 
	
		
			
				|  |  | -		this._isUpdateTile = true;
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	/**
 | 
	
	
		
			
				|  | @@ -58,290 +85,462 @@ class CrImageServerLayer {
 | 
	
		
			
				|  |  |  	 */
 | 
	
		
			
				|  |  |  	_init() {
 | 
	
		
			
				|  |  |  		let _self = this;
 | 
	
		
			
				|  |  | -		this._provider = new Cesium.ArcGisMapServerImageryProvider({
 | 
	
		
			
				|  |  | -			url: _self._url,
 | 
	
		
			
				|  |  | -		})
 | 
	
		
			
				|  |  | -		/* 激活provider 继而获取必要信息 */
 | 
	
		
			
				|  |  | +		/* 创建服务提供者 */
 | 
	
		
			
				|  |  | +		switch (this._providerType) {
 | 
	
		
			
				|  |  | +			case CrImageServerLayer.ProviderType.ArcGisMapServerImageryProvider:
 | 
	
		
			
				|  |  | +				this._provider = new Cesium.ArcGisMapServerImageryProvider(this._config);
 | 
	
		
			
				|  |  | +				break;
 | 
	
		
			
				|  |  | +			case CrImageServerLayer.ProviderType.UrlTemplateImageryProvider:
 | 
	
		
			
				|  |  | +				this._provider = new Cesium.UrlTemplateImageryProvider(this._config);
 | 
	
		
			
				|  |  | +				break;
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +		/* 服务提供者判断 */
 | 
	
		
			
				|  |  | +		if (this._provider === undefined) {
 | 
	
		
			
				|  |  | +			this._console('没有服务提供者,无法初始化!');
 | 
	
		
			
				|  |  | +			return;
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +		/* 激活服务提供者 注册刷帧事件 */
 | 
	
		
			
				|  |  |  		this._provider.readyPromise.then(function(result) {
 | 
	
		
			
				|  |  | +			/* 初始化参数 */
 | 
	
		
			
				|  |  | +			_self._rectangle = _self._provider.rectangle;
 | 
	
		
			
				|  |  | +			_self._tilingScheme = _self._provider.tilingScheme;
 | 
	
		
			
				|  |  | +			_self._maximumLevel = _self._provider.maximumLevel === undefined ? 22 : _self._provider
 | 
	
		
			
				|  |  | +				.maximumLevel;
 | 
	
		
			
				|  |  | +			_self._minimumLevel = _self._provider.minimumLevel === undefined ? 0 : _self._provider
 | 
	
		
			
				|  |  | +				.minimumLevel;
 | 
	
		
			
				|  |  | +			_self._tileWidth = _self._provider.tileWidth;
 | 
	
		
			
				|  |  | +			_self._tileHeight = _self._provider.tileHeight;
 | 
	
		
			
				|  |  | +			/* 输出调试信息 */
 | 
	
		
			
				|  |  | +			if (_self._isDebug) _self._printDebug();
 | 
	
		
			
				|  |  |  			/* 注册事件 */
 | 
	
		
			
				|  |  |  			_self._viewer.scene.postRender.addEventListener(() => {
 | 
	
		
			
				|  |  | -				if (_self._isUpdateTile === true) {
 | 
	
		
			
				|  |  | -					_self._console(_self._isUpdateTile);
 | 
	
		
			
				|  |  | -					_self._updateRenderTile();
 | 
	
		
			
				|  |  | +				if (_self._isUpdateTile) {
 | 
	
		
			
				|  |  | +					/* 设置运行标志为false 等待计算完成 */
 | 
	
		
			
				|  |  | +					_self._isUpdateTile = false;
 | 
	
		
			
				|  |  | +					/* 投影瓦片集合 */
 | 
	
		
			
				|  |  | +					_self._renderTiles();
 | 
	
		
			
				|  |  |  				}
 | 
	
		
			
				|  |  |  			});
 | 
	
		
			
				|  |  | -			/* 注册相机场景移动停止事件 */
 | 
	
		
			
				|  |  | -			// _self._viewer.camera.moveEnd.addEventListener(() => {
 | 
	
		
			
				|  |  | -			// 	_self._console('相机移动结束');
 | 
	
		
			
				|  |  | -			// 	_self._updateRenderTile();
 | 
	
		
			
				|  |  | -			// })
 | 
	
		
			
				|  |  |  		})
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	/**
 | 
	
		
			
				|  |  | +	 * 生成GUID随机数
 | 
	
		
			
				|  |  | +	 */
 | 
	
		
			
				|  |  | +	_guid() {
 | 
	
		
			
				|  |  | +		function S4() {
 | 
	
		
			
				|  |  | +			return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +		return (S4() + S4() + "-" + S4() + "-" + S4() + "-" + S4() + "-" + S4() + S4() + S4());
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	/**
 | 
	
		
			
				|  |  | +	 * 输出调试信息
 | 
	
		
			
				|  |  | +	 */
 | 
	
		
			
				|  |  | +	_printDebug() {
 | 
	
		
			
				|  |  | +		/* 数据提供者的切片方案 */
 | 
	
		
			
				|  |  | +		let tiling = this._provider.tilingScheme;
 | 
	
		
			
				|  |  | +		/* WGS84坐标系的切片方案 */
 | 
	
		
			
				|  |  | +		let tiling84 = new Cesium.GeographicTilingScheme();
 | 
	
		
			
				|  |  | +		/* 绘制数据提供者的数据范围 */
 | 
	
		
			
				|  |  | +		this._drawDebugRectangle(this._rectangle, Cesium.Color.GREEN);
 | 
	
		
			
				|  |  | +		/* 根据行列号和等级创建调试矩形 */
 | 
	
		
			
				|  |  | +		let rect = tiling84.tileXYToRectangle(1696, 312, 10);
 | 
	
		
			
				|  |  | +		/* 绘制调试矩形 */
 | 
	
		
			
				|  |  | +		// this._drawDebugRectangle(rect, Cesium.Color.YELLOW);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +		// let rect11 = Cesium.Rectangle.subsection(rect, 0, 0, 0.5, 0.5);
 | 
	
		
			
				|  |  | +		// let rect12 = Cesium.Rectangle.subsection(rect, 0.5, 0, 1.0, 0.5);
 | 
	
		
			
				|  |  | +		// let rect21 = Cesium.Rectangle.subsection(rect, 0, 0.5, 0.5, 1.0);
 | 
	
		
			
				|  |  | +		// let rect22 = Cesium.Rectangle.subsection(rect, 0.5, 0.5, 1.0, 1.0);
 | 
	
		
			
				|  |  | +		// this._drawDebugRectangle(rect11, Cesium.Color.RED);
 | 
	
		
			
				|  |  | +		// this._drawDebugRectangle(rect12, Cesium.Color.GREEN);
 | 
	
		
			
				|  |  | +		// this._drawDebugRectangle(rect21, Cesium.Color.BLUE);
 | 
	
		
			
				|  |  | +		// this._drawDebugRectangle(rect22, Cesium.Color.WHITE);
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	/**
 | 
	
		
			
				|  |  | +	 * 绘制调试矩形
 | 
	
		
			
				|  |  | +	 * @param {Cesium.Rectangle} rectangle 绘制的矩形
 | 
	
		
			
				|  |  | +	 * @param {Cesium.Color} color 矩形边框颜色
 | 
	
		
			
				|  |  | +	 */
 | 
	
		
			
				|  |  | +	_drawDebugRectangle(rectangle, color) {
 | 
	
		
			
				|  |  | +		/* 计算矩形的外包范围 */
 | 
	
		
			
				|  |  | +		let positions = this._calculateRectangleOutlineCoordinates(rectangle);
 | 
	
		
			
				|  |  | +		/* 创建矩形实体 */
 | 
	
		
			
				|  |  | +		let rectEntity = new Cesium.Entity({
 | 
	
		
			
				|  |  | +			name: this._renderName,
 | 
	
		
			
				|  |  | +			polyline: {
 | 
	
		
			
				|  |  | +				positions: positions,
 | 
	
		
			
				|  |  | +				material: color,
 | 
	
		
			
				|  |  | +				width: 10,
 | 
	
		
			
				|  |  | +				clampToGround: true, //开启贴地 如果有模型则贴模型
 | 
	
		
			
				|  |  | +			}
 | 
	
		
			
				|  |  | +		});
 | 
	
		
			
				|  |  | +		/* 加入数据集 */
 | 
	
		
			
				|  |  | +		this._entities.add(rectEntity);
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	/**
 | 
	
		
			
				|  |  |  	 * 输出消息
 | 
	
		
			
				|  |  |  	 * @param {Object} res
 | 
	
		
			
				|  |  |  	 */
 | 
	
		
			
				|  |  |  	_console(...rest) {
 | 
	
		
			
				|  |  | -		console.log('===' + new Date().Format('yyyy-MM-dd HH:mm:ss') + '>>>', rest);
 | 
	
		
			
				|  |  | +		if (this._isDebug)
 | 
	
		
			
				|  |  | +			console.log('===' + new Date().Format('yyyy-MM-dd HH:mm:ss') + '>>>', rest);
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	/**
 | 
	
		
			
				|  |  | -	 * 更新渲染的Tile集合
 | 
	
		
			
				|  |  | +	 * 渲染瓦片集合
 | 
	
		
			
				|  |  |  	 */
 | 
	
		
			
				|  |  | -	_updateRenderTile() {
 | 
	
		
			
				|  |  | -		/* 设置更新标志为否 */
 | 
	
		
			
				|  |  | -		this._isUpdateTile = false;
 | 
	
		
			
				|  |  | +	_renderTiles() {
 | 
	
		
			
				|  |  |  		let _self = this;
 | 
	
		
			
				|  |  | -		/* 同步 */
 | 
	
		
			
				|  |  | -		let promise = new Promise((resolve, reject) => {
 | 
	
		
			
				|  |  | -			/* 获取当前Cesium自动调度渲染的瓦片集合 */
 | 
	
		
			
				|  |  | -			let tilesToRender = _self._viewer.scene.globe._surface._tilesToRender;
 | 
	
		
			
				|  |  | -			/* 存在渲染瓦片则进行处理转换 */
 | 
	
		
			
				|  |  | -			if (tilesToRender.length !== undefined && tilesToRender.length > 0) {
 | 
	
		
			
				|  |  | -				let renderTiles = [];
 | 
	
		
			
				|  |  | -				for (let i = 0; i < tilesToRender.length; i++) {
 | 
	
		
			
				|  |  | -					let renderTile = tilesToRender[i];
 | 
	
		
			
				|  |  | -					let tile = {
 | 
	
		
			
				|  |  | -						x: renderTile.x,
 | 
	
		
			
				|  |  | -						y: renderTile.y,
 | 
	
		
			
				|  |  | -						level: renderTile.level,
 | 
	
		
			
				|  |  | -						rectangle: renderTile._rectangle,
 | 
	
		
			
				|  |  | -					}
 | 
	
		
			
				|  |  | -					renderTiles.push(tile);
 | 
	
		
			
				|  |  | -				}
 | 
	
		
			
				|  |  | -				resolve(renderTiles);
 | 
	
		
			
				|  |  | -			}
 | 
	
		
			
				|  |  | -		});
 | 
	
		
			
				|  |  | -		/* 异步 */
 | 
	
		
			
				|  |  | -		promise.then(renderTiles => {
 | 
	
		
			
				|  |  | -			_self._calculateRenderTiles(renderTiles);
 | 
	
		
			
				|  |  | -		}).catch(err => {
 | 
	
		
			
				|  |  | -			_self._console(err);
 | 
	
		
			
				|  |  | -		}).finally(() => {
 | 
	
		
			
				|  |  | -			// _self._console('执行结束');
 | 
	
		
			
				|  |  | -		});
 | 
	
		
			
				|  |  | +		/* 获取当前视图渲染的瓦片集合 */
 | 
	
		
			
				|  |  | +		let tilesToRender = this._viewer.scene.globe._surface._tilesToRender;
 | 
	
		
			
				|  |  | +		if (tilesToRender === undefined || tilesToRender.length === 0) {
 | 
	
		
			
				|  |  | +			this._isUpdateTile = true;
 | 
	
		
			
				|  |  | +			return;
 | 
	
		
			
				|  |  | +		} else {
 | 
	
		
			
				|  |  | +			new Promise((resolve, reject) => {
 | 
	
		
			
				|  |  | +				/* 对瓦片数组按照level进行排序 以保证后续瓦片重投影时的重叠移除无误 */
 | 
	
		
			
				|  |  | +				tilesToRender.sort(function(obj1, obj2) {
 | 
	
		
			
				|  |  | +					let level1 = parseInt(obj1.level);
 | 
	
		
			
				|  |  | +					let level2 = parseInt(obj2.level);
 | 
	
		
			
				|  |  | +					return level1 - level2;
 | 
	
		
			
				|  |  | +				})
 | 
	
		
			
				|  |  | +				/* 返回排序后的渲染瓦片数据集 开始异步计算 */
 | 
	
		
			
				|  |  | +				resolve(tilesToRender);
 | 
	
		
			
				|  |  | +			}).then(tiles => {
 | 
	
		
			
				|  |  | +				/* Cesium渲染瓦片为84投影,如果不一致需要异步重投影瓦片数据集 */
 | 
	
		
			
				|  |  | +				_self._asyncProjectionTiles(tiles);
 | 
	
		
			
				|  |  | +			})
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	/**
 | 
	
		
			
				|  |  | -	 * 投影当前瓦片
 | 
	
		
			
				|  |  | -	 * @param {Object} tile
 | 
	
		
			
				|  |  | +	 * 根据行列和等级生成key
 | 
	
		
			
				|  |  | +	 * @param {Number} x 行
 | 
	
		
			
				|  |  | +	 * @param {Number} y 列
 | 
	
		
			
				|  |  | +	 * @param {Number} level 等级
 | 
	
		
			
				|  |  |  	 */
 | 
	
		
			
				|  |  | -	_projectionTile(tile) {
 | 
	
		
			
				|  |  | -		/* 获取矩形 */
 | 
	
		
			
				|  |  | -		let rectangle = tile.rectangle;
 | 
	
		
			
				|  |  | -		let imageryLevel = tile.level;
 | 
	
		
			
				|  |  | -		let mercatorTilingScheme = this._provider.tilingScheme;
 | 
	
		
			
				|  |  | -		let res = [];
 | 
	
		
			
				|  |  | -		let resLeftTop = undefined;
 | 
	
		
			
				|  |  | -		let resRightBottom = undefined;
 | 
	
		
			
				|  |  | -		/* 判断北西角点的墨卡托投影瓦片信息 */
 | 
	
		
			
				|  |  | -		let northwestTileCoordinates = mercatorTilingScheme.positionToTileXY(
 | 
	
		
			
				|  |  | -			Cesium.Rectangle.northwest(rectangle),
 | 
	
		
			
				|  |  | -			imageryLevel
 | 
	
		
			
				|  |  | -		);
 | 
	
		
			
				|  |  | -		if (northwestTileCoordinates !== undefined) {
 | 
	
		
			
				|  |  | -			let _webRectangle = mercatorTilingScheme.tileXYToRectangle(northwestTileCoordinates.x,
 | 
	
		
			
				|  |  | -				northwestTileCoordinates.y,
 | 
	
		
			
				|  |  | -				imageryLevel);
 | 
	
		
			
				|  |  | -			resLeftTop = {
 | 
	
		
			
				|  |  | -				x: northwestTileCoordinates.x,
 | 
	
		
			
				|  |  | -				y: northwestTileCoordinates.y,
 | 
	
		
			
				|  |  | -				level: imageryLevel,
 | 
	
		
			
				|  |  | -				rectangle: _webRectangle,
 | 
	
		
			
				|  |  | -			}
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | -		/* 判断南东角点的墨卡托投影瓦片信息 */
 | 
	
		
			
				|  |  | -		let southeastTileCoordinates = mercatorTilingScheme.positionToTileXY(
 | 
	
		
			
				|  |  | -			Cesium.Rectangle.southeast(rectangle),
 | 
	
		
			
				|  |  | -			imageryLevel
 | 
	
		
			
				|  |  | -		);
 | 
	
		
			
				|  |  | -		if (southeastTileCoordinates !== undefined) {
 | 
	
		
			
				|  |  | -			let _webRectangle = mercatorTilingScheme.tileXYToRectangle(southeastTileCoordinates.x,
 | 
	
		
			
				|  |  | -				southeastTileCoordinates.y,
 | 
	
		
			
				|  |  | -				imageryLevel);
 | 
	
		
			
				|  |  | -			resRightBottom = {
 | 
	
		
			
				|  |  | -				x: southeastTileCoordinates.x,
 | 
	
		
			
				|  |  | -				y: southeastTileCoordinates.y,
 | 
	
		
			
				|  |  | -				level: imageryLevel,
 | 
	
		
			
				|  |  | -				rectangle: _webRectangle,
 | 
	
		
			
				|  |  | -			}
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | -		if (resLeftTop !== undefined && resRightBottom !== undefined) {
 | 
	
		
			
				|  |  | -			if (resLeftTop.x === resRightBottom.x && resLeftTop.y === resRightBottom.y) {
 | 
	
		
			
				|  |  | -				res.push(resLeftTop);
 | 
	
		
			
				|  |  | -			} else {
 | 
	
		
			
				|  |  | -				res.push(resLeftTop);
 | 
	
		
			
				|  |  | -				res.push(resRightBottom);
 | 
	
		
			
				|  |  | -			}
 | 
	
		
			
				|  |  | -		} else if (resLeftTop !== undefined && resRightBottom === undefined) {
 | 
	
		
			
				|  |  | -			res.push(resLeftTop);
 | 
	
		
			
				|  |  | -		} else if (resLeftTop === undefined && resRightBottom !== undefined) {
 | 
	
		
			
				|  |  | -			res.push(resRightBottom);
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | -		return res;
 | 
	
		
			
				|  |  | +	_createKey(x, y, level) {
 | 
	
		
			
				|  |  | +		let key = `${this._renderName}_${x}_${y}_${level}`;
 | 
	
		
			
				|  |  | +		return key;
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	/**
 | 
	
		
			
				|  |  | -	 * 计算渲染的瓦片集合
 | 
	
		
			
				|  |  | -	 * @param {JSON} renderTiles 渲染的瓦片集合
 | 
	
		
			
				|  |  | +	 * 投影瓦片集合
 | 
	
		
			
				|  |  | +	 * @param {Object} tiles 原始渲染瓦片集合
 | 
	
		
			
				|  |  |  	 */
 | 
	
		
			
				|  |  | -	_calculateRenderTiles(renderTiles) {
 | 
	
		
			
				|  |  | -		this._updateTiles = [];
 | 
	
		
			
				|  |  | -		let _self = this;
 | 
	
		
			
				|  |  | -		for (let i = 0; i < renderTiles.length; i++) {
 | 
	
		
			
				|  |  | -			let renderTile = renderTiles[i];
 | 
	
		
			
				|  |  | -			/* 计算重投影后的Tiles */
 | 
	
		
			
				|  |  | -			let tiles = this._projectionTile(renderTile);
 | 
	
		
			
				|  |  | -			for (let tile of tiles) {
 | 
	
		
			
				|  |  | -				let key = tile.x + '_' + tile.y + '_' + tile.level;
 | 
	
		
			
				|  |  | -				let subTile = this._updateTiles.find(obj => {
 | 
	
		
			
				|  |  | -					return obj.x === tile.x && obj.y === tile.y;
 | 
	
		
			
				|  |  | +	_asyncProjectionTiles(tiles) {
 | 
	
		
			
				|  |  | +		let renderTiles = [];
 | 
	
		
			
				|  |  | +		/* 循环投影 */
 | 
	
		
			
				|  |  | +		for (let tile of tiles) {
 | 
	
		
			
				|  |  | +			/* 对单个瓦片进行重投影 */
 | 
	
		
			
				|  |  | +			let proTiles = this._projectionTile(tile);
 | 
	
		
			
				|  |  | +			for (let proTile of proTiles) {
 | 
	
		
			
				|  |  | +				/* 瓦片实体唯一标识 */
 | 
	
		
			
				|  |  | +				let key = this._createKey(proTile.x, proTile.y, proTile.level);
 | 
	
		
			
				|  |  | +				/* 查找瓦片是否已经存在 存在则过滤 以免重复存在 */
 | 
	
		
			
				|  |  | +				let subTile = renderTiles.find(obj => {
 | 
	
		
			
				|  |  | +					return obj.x === proTile.x && obj.y === proTile.y;
 | 
	
		
			
				|  |  |  				})
 | 
	
		
			
				|  |  |  				if (subTile === undefined) {
 | 
	
		
			
				|  |  | -					this._updateTiles.push({
 | 
	
		
			
				|  |  | -						key: key,
 | 
	
		
			
				|  |  | -						x: tile.x,
 | 
	
		
			
				|  |  | -						y: tile.y,
 | 
	
		
			
				|  |  | -						level: tile.level,
 | 
	
		
			
				|  |  | -						rectangle: tile.rectangle,
 | 
	
		
			
				|  |  | -					});
 | 
	
		
			
				|  |  | +					/* 重投影瓦片范围与数据范围的叠合计算 */
 | 
	
		
			
				|  |  | +					let isExists = false;
 | 
	
		
			
				|  |  | +					for (let eTile of renderTiles) {
 | 
	
		
			
				|  |  | +						if (Cesium.Rectangle.intersection(eTile.rectangle, proTile.rectangle)) {
 | 
	
		
			
				|  |  | +							/* 追加子集 方便后期进行层级处理 */
 | 
	
		
			
				|  |  | +							eTile.childTiles.push(key);
 | 
	
		
			
				|  |  | +							isExists = true;
 | 
	
		
			
				|  |  | +							break;
 | 
	
		
			
				|  |  | +						}
 | 
	
		
			
				|  |  | +					}
 | 
	
		
			
				|  |  | +					/* 加入渲染集合 */
 | 
	
		
			
				|  |  | +					if (!isExists) {
 | 
	
		
			
				|  |  | +						renderTiles.push({
 | 
	
		
			
				|  |  | +							key: key,
 | 
	
		
			
				|  |  | +							x: proTile.x,
 | 
	
		
			
				|  |  | +							y: proTile.y,
 | 
	
		
			
				|  |  | +							level: proTile.level,
 | 
	
		
			
				|  |  | +							rectangle: proTile.rectangle,
 | 
	
		
			
				|  |  | +							childTiles: [],
 | 
	
		
			
				|  |  | +						});
 | 
	
		
			
				|  |  | +					}
 | 
	
		
			
				|  |  |  				}
 | 
	
		
			
				|  |  |  			}
 | 
	
		
			
				|  |  |  		}
 | 
	
		
			
				|  |  | -		/* 判断是否有需要渲染的瓦片 有则渲染 */
 | 
	
		
			
				|  |  | -		if (this._updateTiles.length > 0) {
 | 
	
		
			
				|  |  | -			this._renderTiles();
 | 
	
		
			
				|  |  | -		} else {
 | 
	
		
			
				|  |  | -			this._isUpdateTile = true;
 | 
	
		
			
				|  |  | +		/* 清理低层级元素 */
 | 
	
		
			
				|  |  | +		let i = renderTiles.length;
 | 
	
		
			
				|  |  | +		let appendTiles = [];
 | 
	
		
			
				|  |  | +		while (i--) {
 | 
	
		
			
				|  |  | +			let findTile = renderTiles[i];
 | 
	
		
			
				|  |  | +			if (findTile.childTiles.length >= 1) {
 | 
	
		
			
				|  |  | +				/* 创建高层级的瓦片 */
 | 
	
		
			
				|  |  | +				let tiles = this._createFourTiles(findTile);
 | 
	
		
			
				|  |  | +				for (let tile of tiles) {
 | 
	
		
			
				|  |  | +					appendTiles.push(tile);
 | 
	
		
			
				|  |  | +				}
 | 
	
		
			
				|  |  | +				/* 如果存在高层级 则删除低层级 */
 | 
	
		
			
				|  |  | +				renderTiles.splice(i, 1);
 | 
	
		
			
				|  |  | +			}
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +		/* 将四叉树追加的层级数据加入到渲染集合中 */
 | 
	
		
			
				|  |  | +		for (let appendTile of appendTiles) {
 | 
	
		
			
				|  |  | +			renderTiles.push(appendTile);
 | 
	
		
			
				|  |  |  		}
 | 
	
		
			
				|  |  | +		/* 对数组进行排序 */
 | 
	
		
			
				|  |  | +		renderTiles.sort(function(obj1, obj2) {
 | 
	
		
			
				|  |  | +			let level1 = parseInt(obj1.level);
 | 
	
		
			
				|  |  | +			let level2 = parseInt(obj2.level);
 | 
	
		
			
				|  |  | +			return level1 - level2;
 | 
	
		
			
				|  |  | +		})
 | 
	
		
			
				|  |  | +		/* 渲染数据到视图中 */
 | 
	
		
			
				|  |  | +		this._renderTilesToViewer(renderTiles);
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	/**
 | 
	
		
			
				|  |  | -	 * 渲染瓦片集
 | 
	
		
			
				|  |  | +	 * 根据矩形和登记查询高一等级的行列号
 | 
	
		
			
				|  |  | +	 * @param {Cesium.Rectangle} rectangle 
 | 
	
		
			
				|  |  |  	 */
 | 
	
		
			
				|  |  | -	_renderTiles() {
 | 
	
		
			
				|  |  | -		this._console(this._updateTiles);
 | 
	
		
			
				|  |  | -		// this._removeEntityByName('AAA');
 | 
	
		
			
				|  |  | -		// this._renderTileToVierer(0);
 | 
	
		
			
				|  |  | -		this._isUpdateTile = true;
 | 
	
		
			
				|  |  | +	_createTileByRectangleAndLevel(rectangle, level) {
 | 
	
		
			
				|  |  | +		/* 获取矩形中心点 */
 | 
	
		
			
				|  |  | +		let center = Cesium.Rectangle.center(rectangle);
 | 
	
		
			
				|  |  | +		/* 新层级 */
 | 
	
		
			
				|  |  | +		let nLevel = parseInt(level) + 1;
 | 
	
		
			
				|  |  | +		/* 查询高一层级的行列号 */
 | 
	
		
			
				|  |  | +		let query = this._provider.tilingScheme.positionToTileXY(center, nLevel);
 | 
	
		
			
				|  |  | +		if (query === undefined) return undefined;
 | 
	
		
			
				|  |  | +		/* 返回结果 */
 | 
	
		
			
				|  |  | +		return {
 | 
	
		
			
				|  |  | +			key: this._createKey(query.x, query.y, nLevel),
 | 
	
		
			
				|  |  | +			x: query.x,
 | 
	
		
			
				|  |  | +			y: query.y,
 | 
	
		
			
				|  |  | +			level: nLevel,
 | 
	
		
			
				|  |  | +			rectangle: rectangle,
 | 
	
		
			
				|  |  | +			childTiles: [],
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	/**
 | 
	
		
			
				|  |  | -	 * 渲染瓦片到地图上
 | 
	
		
			
				|  |  | -	 * @param {Number} index
 | 
	
		
			
				|  |  | +	 * 创建四个高层级的瓦片
 | 
	
		
			
				|  |  | +	 * @param {Object} tile 当前瓦片
 | 
	
		
			
				|  |  |  	 */
 | 
	
		
			
				|  |  | -	_renderTileToVierer(index) {
 | 
	
		
			
				|  |  | -		let _self = this;
 | 
	
		
			
				|  |  | -		if (index === this._updateTiles.length - 1) {
 | 
	
		
			
				|  |  | -			this._isUpdateTile = true;
 | 
	
		
			
				|  |  | -			return;
 | 
	
		
			
				|  |  | +	_createFourTiles(tile) {
 | 
	
		
			
				|  |  | +		let rects = [];
 | 
	
		
			
				|  |  | +		let results = [];
 | 
	
		
			
				|  |  | +		let rectangle = tile.rectangle;
 | 
	
		
			
				|  |  | +		/* 将该矩形按照四叉树规则分割为4个高层级的矩形 */
 | 
	
		
			
				|  |  | +		rects.push(Cesium.Rectangle.subsection(rectangle, 0, 0, 0.5, 0.5));
 | 
	
		
			
				|  |  | +		rects.push(Cesium.Rectangle.subsection(rectangle, 0.5, 0, 1.0, 0.5));
 | 
	
		
			
				|  |  | +		rects.push(Cesium.Rectangle.subsection(rectangle, 0, 0.5, 0.5, 1.0));
 | 
	
		
			
				|  |  | +		rects.push(Cesium.Rectangle.subsection(rectangle, 0.5, 0.5, 1.0, 1.0));
 | 
	
		
			
				|  |  | +		for (let rect of rects) {
 | 
	
		
			
				|  |  | +			/* 判断高层级的矩形是否与谁范围存在交集 */
 | 
	
		
			
				|  |  | +			if (Cesium.Rectangle.intersection(rect, this._rectangle)) {
 | 
	
		
			
				|  |  | +				/* 查询高一层级的Tile */
 | 
	
		
			
				|  |  | +				let newTile = this._createTileByRectangleAndLevel(rect, tile.level);
 | 
	
		
			
				|  |  | +				/* 如果存在加入到返回集合中 */
 | 
	
		
			
				|  |  | +				if (newTile !== undefined) results.push(newTile);
 | 
	
		
			
				|  |  | +			}
 | 
	
		
			
				|  |  |  		}
 | 
	
		
			
				|  |  | -		try {
 | 
	
		
			
				|  |  | -			let tile = this._updateTiles[index];
 | 
	
		
			
				|  |  | -			let x = tile.x;
 | 
	
		
			
				|  |  | -			let y = tile.y;
 | 
	
		
			
				|  |  | -			let level = tile.level;
 | 
	
		
			
				|  |  | -			const canvas = document.createElement("canvas");
 | 
	
		
			
				|  |  | -			canvas.width = 256;
 | 
	
		
			
				|  |  | -			canvas.height = 256;
 | 
	
		
			
				|  |  | -			const context = canvas.getContext("2d");
 | 
	
		
			
				|  |  | -			context.strokeStyle = 'rgba(255,255,0)';
 | 
	
		
			
				|  |  | -			context.lineWidth = 2;
 | 
	
		
			
				|  |  | -			context.strokeRect(1, 1, 255, 255);
 | 
	
		
			
				|  |  | +		return results;
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -			context.font = "bold 25px Arial";
 | 
	
		
			
				|  |  | -			context.textAlign = "center";
 | 
	
		
			
				|  |  | -			context.fillStyle = 'rgba(255,0,0)';
 | 
	
		
			
				|  |  | -			context.fillText(`L: ${level}`, 124, 86);
 | 
	
		
			
				|  |  | -			context.fillText(`X: ${x}`, 124, 136);
 | 
	
		
			
				|  |  | -			context.fillText(`Y: ${y}`, 124, 186);
 | 
	
		
			
				|  |  | -			let bjPositions = this._calculateRectangleOutlineCoordinates(tile
 | 
	
		
			
				|  |  | -				.rectangle);
 | 
	
		
			
				|  |  | -			let tileEntity = new Cesium.Entity({
 | 
	
		
			
				|  |  | -				name: 'AAA',
 | 
	
		
			
				|  |  | -				id: tile.key,
 | 
	
		
			
				|  |  | -				rectangle: {
 | 
	
		
			
				|  |  | -					coordinates: tile.rectangle,
 | 
	
		
			
				|  |  | -					material: canvas, //Cesium.Color.RED.withAlpha(0.9),
 | 
	
		
			
				|  |  | -				},
 | 
	
		
			
				|  |  | -				polyline: {
 | 
	
		
			
				|  |  | -					positions: bjPositions,
 | 
	
		
			
				|  |  | -					material: Cesium.Color.YELLOW,
 | 
	
		
			
				|  |  | -					width: 2,
 | 
	
		
			
				|  |  | -					clampToGround: true, //开启贴地 如果有模型则贴模型
 | 
	
		
			
				|  |  | -				}
 | 
	
		
			
				|  |  | -			});
 | 
	
		
			
				|  |  | -			this._entities.add(tileEntity);
 | 
	
		
			
				|  |  | -			let worker = new Worker('public/js/worker_download.js');
 | 
	
		
			
				|  |  | -			worker.onmessage = function(event) {
 | 
	
		
			
				|  |  | -				/* 重置渲染 */
 | 
	
		
			
				|  |  | -				let entity = _self._entities.getById(event.data.key);
 | 
	
		
			
				|  |  | -				const canvas = document.createElement("canvas");
 | 
	
		
			
				|  |  | -				canvas.width = 256;
 | 
	
		
			
				|  |  | -				canvas.height = 256;
 | 
	
		
			
				|  |  | -				let context = canvas.getContext('2d');
 | 
	
		
			
				|  |  | -				context.drawImage(event.data.image, 0, 0, 256, 256);
 | 
	
		
			
				|  |  | -				entity.rectangle.material = canvas;
 | 
	
		
			
				|  |  | +	/**
 | 
	
		
			
				|  |  | +	 * 渲染瓦片到视图中
 | 
	
		
			
				|  |  | +	 * @param {Object} tiles
 | 
	
		
			
				|  |  | +	 */
 | 
	
		
			
				|  |  | +	_renderTilesToViewer(tiles) {
 | 
	
		
			
				|  |  | +		let _self = this;
 | 
	
		
			
				|  |  | +		/* 确定哪些渲染实体已失效 对失效的实体进行清理 */
 | 
	
		
			
				|  |  | +		let deleteKeys = [];
 | 
	
		
			
				|  |  | +		for (let [key, tile] of this._renderEntities) {
 | 
	
		
			
				|  |  | +			let findTile = tiles.find(obj => {
 | 
	
		
			
				|  |  | +				return obj.key === key;
 | 
	
		
			
				|  |  | +			})
 | 
	
		
			
				|  |  | +			if (findTile === undefined) {
 | 
	
		
			
				|  |  | +				deleteKeys.push(key);
 | 
	
		
			
				|  |  |  			}
 | 
	
		
			
				|  |  | -			worker.postMessage({
 | 
	
		
			
				|  |  | -				key: tile.key,
 | 
	
		
			
				|  |  | -				x: tile.x,
 | 
	
		
			
				|  |  | -				y: tile.y,
 | 
	
		
			
				|  |  | -				level: tile.level,
 | 
	
		
			
				|  |  | -				url: _self._url,
 | 
	
		
			
				|  |  | -			});
 | 
	
		
			
				|  |  | -			this._renderTileToVierer(index + 1);
 | 
	
		
			
				|  |  | -		} catch (e) {
 | 
	
		
			
				|  |  | -			this._console(e.message);
 | 
	
		
			
				|  |  | -			this._renderTileToVierer(index + 1);
 | 
	
		
			
				|  |  |  		}
 | 
	
		
			
				|  |  | +		for (let key of deleteKeys) {
 | 
	
		
			
				|  |  | +			// /* 移除元素 */
 | 
	
		
			
				|  |  | +			this._renderEntities.delete(key);
 | 
	
		
			
				|  |  | +			// /* 移除渲染元素 */
 | 
	
		
			
				|  |  | +			this._entities.removeById(key);
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +		/* 对过滤后的数据集进行渲染 */
 | 
	
		
			
				|  |  | +		for (let tile of tiles) {
 | 
	
		
			
				|  |  | +			/* 判断当前渲染的数据是否已经渲染且有效 */
 | 
	
		
			
				|  |  | +			if (!this._renderEntities.has(tile.key)) {
 | 
	
		
			
				|  |  | +				/* 将数据渲染到视图中 */
 | 
	
		
			
				|  |  | +				let entity = this._renderSimpleTileToViewer(tile);
 | 
	
		
			
				|  |  | +				this._renderEntities.set(tile.key, entity);
 | 
	
		
			
				|  |  | +				/* 初始化y */
 | 
	
		
			
				|  |  | +				let tile_y = tile.y;
 | 
	
		
			
				|  |  | +				/* 利用数据提供器获取图片 */
 | 
	
		
			
				|  |  | +				this._provider.requestImage(tile.x, tile_y, tile.level).then(function(image) {
 | 
	
		
			
				|  |  | +					/* 判断是否返回图片资源 */
 | 
	
		
			
				|  |  | +					if (image !== undefined) {
 | 
	
		
			
				|  |  | +						_self._console('渲染图片', image);
 | 
	
		
			
				|  |  | +						/* 对图片资源进行Y轴翻转 */
 | 
	
		
			
				|  |  | +						let primise = createImageBitmap(image, {
 | 
	
		
			
				|  |  | +							imageOrientation: 'flipY',
 | 
	
		
			
				|  |  | +						});
 | 
	
		
			
				|  |  | +						primise.then(function(resImage) {
 | 
	
		
			
				|  |  | +							let renderEntity = _self._entities.getById(tile.key);
 | 
	
		
			
				|  |  | +							if (renderEntity !== undefined) {
 | 
	
		
			
				|  |  | +								const canvas = _self._createCanvas(tile, resImage, _self._isDebug);
 | 
	
		
			
				|  |  | +								renderEntity.rectangle.material = canvas;
 | 
	
		
			
				|  |  | +							}
 | 
	
		
			
				|  |  | +							// _self._renderImagebitmaps.set(tile.key, resImage);
 | 
	
		
			
				|  |  | +							/* 释放图片资源 */
 | 
	
		
			
				|  |  | +							image.close();
 | 
	
		
			
				|  |  | +						})
 | 
	
		
			
				|  |  | +					}
 | 
	
		
			
				|  |  | +				});
 | 
	
		
			
				|  |  | +			}
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +		/* 重启计算标志 */
 | 
	
		
			
				|  |  | +		this._isUpdateTile = true;
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	/**
 | 
	
		
			
				|  |  | -	 * 竖向翻转
 | 
	
		
			
				|  |  | -	 * @param {Array[]} sourceData 
 | 
	
		
			
				|  |  | +	 * 渲染单个瓦片到视图中
 | 
	
		
			
				|  |  | +	 * @param {Object} tile
 | 
	
		
			
				|  |  |  	 */
 | 
	
		
			
				|  |  | -	_imageDataVRevert(sourceData) {
 | 
	
		
			
				|  |  | -		let newData = {
 | 
	
		
			
				|  |  | -			width: sourceData.width,
 | 
	
		
			
				|  |  | -			height: sourceData.height,
 | 
	
		
			
				|  |  | -			data: new Uint8ClampedArray(sourceData.data.length)
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | -		for (var i = 0, h = sourceData.height; i < h; i++) {
 | 
	
		
			
				|  |  | -			for (var j = 0, w = sourceData.width; j < w; j++) {
 | 
	
		
			
				|  |  | -				newData.data[i * w * 4 + j * 4 + 0] =
 | 
	
		
			
				|  |  | -					sourceData.data[(h - i) * w * 4 + j * 4 + 0];
 | 
	
		
			
				|  |  | -				newData.data[i * w * 4 + j * 4 + 1] =
 | 
	
		
			
				|  |  | -					sourceData.data[(h - i) * w * 4 + j * 4 + 1];
 | 
	
		
			
				|  |  | -				newData.data[i * w * 4 + j * 4 + 2] =
 | 
	
		
			
				|  |  | -					sourceData.data[(h - i) * w * 4 + j * 4 + 2];
 | 
	
		
			
				|  |  | -				newData.data[i * w * 4 + j * 4 + 3] =
 | 
	
		
			
				|  |  | -					sourceData.data[(h - i) * w * 4 + j * 4 + 3] - 100;
 | 
	
		
			
				|  |  | +	_renderSimpleTileToViewer(tile) {
 | 
	
		
			
				|  |  | +		/* 创建画布 */
 | 
	
		
			
				|  |  | +		const canvas = this._createCanvas(tile, undefined, this._isDebug);
 | 
	
		
			
				|  |  | +		let bjPositions = this._calculateRectangleOutlineCoordinates(tile
 | 
	
		
			
				|  |  | +			.rectangle);
 | 
	
		
			
				|  |  | +		let tileEntity = new Cesium.Entity({
 | 
	
		
			
				|  |  | +			name: this._renderName,
 | 
	
		
			
				|  |  | +			id: tile.key,
 | 
	
		
			
				|  |  | +			rectangle: {
 | 
	
		
			
				|  |  | +				coordinates: tile.rectangle,
 | 
	
		
			
				|  |  | +				material: canvas,
 | 
	
		
			
				|  |  | +			},
 | 
	
		
			
				|  |  | +			polyline: {
 | 
	
		
			
				|  |  | +				positions: bjPositions,
 | 
	
		
			
				|  |  | +				material: Cesium.Color.YELLOW.withAlpha(this._isDebug ? 1 : 0),
 | 
	
		
			
				|  |  | +				width: 1,
 | 
	
		
			
				|  |  | +				clampToGround: true, //开启贴地 如果有模型则贴模型
 | 
	
		
			
				|  |  |  			}
 | 
	
		
			
				|  |  | +		});
 | 
	
		
			
				|  |  | +		return this._entities.add(tileEntity);
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	/**
 | 
	
		
			
				|  |  | +	 * 根据瓦片创建画布
 | 
	
		
			
				|  |  | +	 * @param {Object} tile 瓦片
 | 
	
		
			
				|  |  | +	 * @param {Object} image 绘制的图片
 | 
	
		
			
				|  |  | +	 * @param {boolean} islabel 是否绘制标签 
 | 
	
		
			
				|  |  | +	 */
 | 
	
		
			
				|  |  | +	_createCanvas(tile, image, islabel) {
 | 
	
		
			
				|  |  | +		/* 获取服务提供者的切片方案 */
 | 
	
		
			
				|  |  | +		let provider = this._provider;
 | 
	
		
			
				|  |  | +		const canvas = document.createElement("canvas");
 | 
	
		
			
				|  |  | +		canvas.width = provider.tileWidth;
 | 
	
		
			
				|  |  | +		canvas.height = provider.tileHeight;
 | 
	
		
			
				|  |  | +		const context = canvas.getContext("2d");
 | 
	
		
			
				|  |  | +		if (image !== undefined) {
 | 
	
		
			
				|  |  | +			context.globalAlpha = this._opacity;
 | 
	
		
			
				|  |  | +			context.drawImage(image, 0, 0, canvas.width, canvas.height);
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +		if (islabel !== undefined && islabel === true) {
 | 
	
		
			
				|  |  | +			context.globalAlpha = 1.0;
 | 
	
		
			
				|  |  | +			/* 创建标签 */
 | 
	
		
			
				|  |  | +			context.font = "20px Arial";
 | 
	
		
			
				|  |  | +			context.textAlign = "center";
 | 
	
		
			
				|  |  | +			context.fillStyle = 'rgba(255,255,0)';
 | 
	
		
			
				|  |  | +			context.strokeStyle = 'rgba(255,255,255,1)';
 | 
	
		
			
				|  |  | +			context.lineWidth = 2;
 | 
	
		
			
				|  |  | +			context.strokeText(`L: ${tile.level}`, 126, 86);
 | 
	
		
			
				|  |  | +			context.fillText(`L: ${tile.level}`, 126, 86);
 | 
	
		
			
				|  |  | +			context.strokeText(`X: ${tile.x}`, 126, 136);
 | 
	
		
			
				|  |  | +			context.fillText(`X: ${tile.x}`, 126, 136);
 | 
	
		
			
				|  |  | +			context.strokeText(`Y: ${tile.y}`, 126, 186);
 | 
	
		
			
				|  |  | +			context.fillText(`Y: ${tile.y}`, 126, 186);
 | 
	
		
			
				|  |  |  		}
 | 
	
		
			
				|  |  | -		return newData;
 | 
	
		
			
				|  |  | +		/* 返回画布 */
 | 
	
		
			
				|  |  | +		return canvas;
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	/**
 | 
	
		
			
				|  |  | -	 * 横向翻转
 | 
	
		
			
				|  |  | -	 * @param {Array[]} sourceData 
 | 
	
		
			
				|  |  | -	 * @param {Array[]} newData
 | 
	
		
			
				|  |  | +	 * 投影当前瓦片
 | 
	
		
			
				|  |  | +	 * @param {Object} tile
 | 
	
		
			
				|  |  |  	 */
 | 
	
		
			
				|  |  | -	_imageDataHRevert(sourceData, newData) {
 | 
	
		
			
				|  |  | -		for (var i = 0, h = sourceData.height; i < h; i++) {
 | 
	
		
			
				|  |  | -			for (j = 0, w = sourceData.width; j < w; j++) {
 | 
	
		
			
				|  |  | -				newData.data[i * w * 4 + j * 4 + 0] =
 | 
	
		
			
				|  |  | -					sourceData.data[i * w * 4 + (w - j) * 4 + 0];
 | 
	
		
			
				|  |  | -				newData.data[i * w * 4 + j * 4 + 1] =
 | 
	
		
			
				|  |  | -					sourceData.data[i * w * 4 + (w - j) * 4 + 1];
 | 
	
		
			
				|  |  | -				newData.data[i * w * 4 + j * 4 + 2] =
 | 
	
		
			
				|  |  | -					sourceData.data[i * w * 4 + (w - j) * 4 + 2];
 | 
	
		
			
				|  |  | -				newData.data[i * w * 4 + j * 4 + 3] =
 | 
	
		
			
				|  |  | -					sourceData.data[i * w * 4 + (w - j) * 4 + 3];
 | 
	
		
			
				|  |  | +	_projectionTile(tile) {
 | 
	
		
			
				|  |  | +		if (this._tilingScheme instanceof Cesium.GeographicTilingScheme) {
 | 
	
		
			
				|  |  | +			return [{
 | 
	
		
			
				|  |  | +				x: tile.x,
 | 
	
		
			
				|  |  | +				y: tile.y,
 | 
	
		
			
				|  |  | +				level: tile.level,
 | 
	
		
			
				|  |  | +				rectangle: tile._rectangle,
 | 
	
		
			
				|  |  | +			}];
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +		/* 获取矩形 */
 | 
	
		
			
				|  |  | +		let rectangle = tile._rectangle;
 | 
	
		
			
				|  |  | +		// let imageryLevel = parseInt(tile.level) + 1;
 | 
	
		
			
				|  |  | +		let imageryLevel = parseInt(tile.level);
 | 
	
		
			
				|  |  | +		let mercatorTilingScheme = this._provider.tilingScheme;
 | 
	
		
			
				|  |  | +		let res = [];
 | 
	
		
			
				|  |  | +		/* 先判断当前的切片范围是否与提供者的数据范围有交集 */
 | 
	
		
			
				|  |  | +		let interRectangle = Cesium.Rectangle.intersection(rectangle, this._rectangle);
 | 
	
		
			
				|  |  | +		/* 如果当前计算的瓦片与数据范围无交集 则舍弃 */
 | 
	
		
			
				|  |  | +		if (interRectangle === undefined) return res;
 | 
	
		
			
				|  |  | +		/* 判断北西角点的墨卡托投影瓦片信息 */
 | 
	
		
			
				|  |  | +		let northwestTileCoordinates = mercatorTilingScheme.positionToTileXY(
 | 
	
		
			
				|  |  | +			Cesium.Rectangle.northwest(rectangle),
 | 
	
		
			
				|  |  | +			imageryLevel
 | 
	
		
			
				|  |  | +		);
 | 
	
		
			
				|  |  | +		/* 判断南东角点的墨卡托投影瓦片信息 */
 | 
	
		
			
				|  |  | +		let southeastTileCoordinates = mercatorTilingScheme.positionToTileXY(
 | 
	
		
			
				|  |  | +			Cesium.Rectangle.southeast(rectangle),
 | 
	
		
			
				|  |  | +			imageryLevel
 | 
	
		
			
				|  |  | +		);
 | 
	
		
			
				|  |  | +		/* 根据不同类型分别进行计算 */
 | 
	
		
			
				|  |  | +		if (northwestTileCoordinates !== undefined && southeastTileCoordinates !== undefined) {
 | 
	
		
			
				|  |  | +			for (let i = northwestTileCoordinates.x; i <= southeastTileCoordinates.x; i++) {
 | 
	
		
			
				|  |  | +				for (let j = northwestTileCoordinates.y; j <= southeastTileCoordinates.y; j++) {
 | 
	
		
			
				|  |  | +					let _webRectangle = mercatorTilingScheme.tileXYToRectangle(i, j, imageryLevel);
 | 
	
		
			
				|  |  | +					if (Cesium.Rectangle.intersection(_webRectangle, this._rectangle)) {
 | 
	
		
			
				|  |  | +						res.push({
 | 
	
		
			
				|  |  | +							x: i,
 | 
	
		
			
				|  |  | +							y: j,
 | 
	
		
			
				|  |  | +							level: imageryLevel,
 | 
	
		
			
				|  |  | +							rectangle: _webRectangle,
 | 
	
		
			
				|  |  | +						});
 | 
	
		
			
				|  |  | +					}
 | 
	
		
			
				|  |  | +				}
 | 
	
		
			
				|  |  | +			}
 | 
	
		
			
				|  |  | +		} else if (northwestTileCoordinates !== undefined) {
 | 
	
		
			
				|  |  | +			let _webRectangle = mercatorTilingScheme.tileXYToRectangle(northwestTileCoordinates.x,
 | 
	
		
			
				|  |  | +				northwestTileCoordinates.y,
 | 
	
		
			
				|  |  | +				imageryLevel);
 | 
	
		
			
				|  |  | +			if (Cesium.Rectangle.intersection(_webRectangle, this._rectangle)) {
 | 
	
		
			
				|  |  | +				res.push({
 | 
	
		
			
				|  |  | +					x: northwestTileCoordinates.x,
 | 
	
		
			
				|  |  | +					y: northwestTileCoordinates.y,
 | 
	
		
			
				|  |  | +					level: imageryLevel,
 | 
	
		
			
				|  |  | +					rectangle: _webRectangle,
 | 
	
		
			
				|  |  | +				});
 | 
	
		
			
				|  |  | +			}
 | 
	
		
			
				|  |  | +		} else if (southeastTileCoordinates !== undefined) {
 | 
	
		
			
				|  |  | +			let _webRectangle = mercatorTilingScheme.tileXYToRectangle(southeastTileCoordinates.x,
 | 
	
		
			
				|  |  | +				southeastTileCoordinates.y,
 | 
	
		
			
				|  |  | +				imageryLevel);
 | 
	
		
			
				|  |  | +			if (Cesium.Rectangle.intersection(_webRectangle, this._rectangle)) {
 | 
	
		
			
				|  |  | +				res.push({
 | 
	
		
			
				|  |  | +					x: southeastTileCoordinates.x,
 | 
	
		
			
				|  |  | +					y: southeastTileCoordinates.y,
 | 
	
		
			
				|  |  | +					level: imageryLevel,
 | 
	
		
			
				|  |  | +					rectangle: _webRectangle,
 | 
	
		
			
				|  |  | +				});
 | 
	
		
			
				|  |  |  			}
 | 
	
		
			
				|  |  |  		}
 | 
	
		
			
				|  |  | -		return newData;
 | 
	
		
			
				|  |  | +		return res;
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	/**
 | 
	
	
		
			
				|  | @@ -371,7 +570,7 @@ class CrImageServerLayer {
 | 
	
		
			
				|  |  |  	 */
 | 
	
		
			
				|  |  |  	_removeEntityByName(entityName) {
 | 
	
		
			
				|  |  |  		/* 获取实体集合 */
 | 
	
		
			
				|  |  | -		var entities = this._viewer.entities;
 | 
	
		
			
				|  |  | +		var entities = this._entities;
 | 
	
		
			
				|  |  |  		/* 如果不存在实体集合或集合中没有数据 则返回 */
 | 
	
		
			
				|  |  |  		if (!entities || !entities.values) return;
 | 
	
		
			
				|  |  |  		var delEntitys = [];
 | 
	
	
		
			
				|  | @@ -388,5 +587,61 @@ class CrImageServerLayer {
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +/* 对外方法 */
 | 
	
		
			
				|  |  | +Object.assign(CrImageServerLayer.prototype, {
 | 
	
		
			
				|  |  | +	/**
 | 
	
		
			
				|  |  | +	 * 隐藏
 | 
	
		
			
				|  |  | +	 */
 | 
	
		
			
				|  |  | +	hide: function() {
 | 
	
		
			
				|  |  | +		this._console('隐藏');
 | 
	
		
			
				|  |  | +		this._isUpdateTile = false;
 | 
	
		
			
				|  |  | +		/* 清理资源 */
 | 
	
		
			
				|  |  | +		this._removeEntityByName(this._renderName);
 | 
	
		
			
				|  |  | +		/* 清理渲染 */
 | 
	
		
			
				|  |  | +		this._renderEntities.clear();
 | 
	
		
			
				|  |  | +	},
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	/**
 | 
	
		
			
				|  |  | +	 * 显示
 | 
	
		
			
				|  |  | +	 */
 | 
	
		
			
				|  |  | +	show: function() {
 | 
	
		
			
				|  |  | +		this._console('显示');
 | 
	
		
			
				|  |  | +		this._isUpdateTile = true;
 | 
	
		
			
				|  |  | +	},
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	/**
 | 
	
		
			
				|  |  | +	 * 设置透明度
 | 
	
		
			
				|  |  | +	 * @param {Number} opacity [0-1]
 | 
	
		
			
				|  |  | +	 */
 | 
	
		
			
				|  |  | +	setOpacity: function(opacity) {
 | 
	
		
			
				|  |  | +		if (opacity === undefined || typeof opacity !== 'number') return;
 | 
	
		
			
				|  |  | +		if (opacity >= 1) this._opacity = 1.0;
 | 
	
		
			
				|  |  | +		if (opacity <= 0) this._opacity = 0.0;
 | 
	
		
			
				|  |  | +		this._opacity = parseFloat(opacity);
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +})
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/**
 | 
	
		
			
				|  |  | + * 数据提供器类型
 | 
	
		
			
				|  |  | + */
 | 
	
		
			
				|  |  | +CrImageServerLayer.ProviderType = Object.freeze({
 | 
	
		
			
				|  |  | +	ArcGisMapServerImageryProvider: 'ArcGisMapServerImageryProvider',
 | 
	
		
			
				|  |  | +	BingMapsImageryProvider: 'BingMapsImageryProvider',
 | 
	
		
			
				|  |  | +	OpenStreetMapImageryProvider: 'OpenStreetMapImageryProvider',
 | 
	
		
			
				|  |  | +	TileMapServiceImageryProvider: 'TileMapServiceImageryProvider',
 | 
	
		
			
				|  |  | +	GoogleEarthEnterpriseImageryProvider: 'GoogleEarthEnterpriseImageryProvider',
 | 
	
		
			
				|  |  | +	GoogleEarthEnterpriseMapsProvider: 'GoogleEarthEnterpriseMapsProvider',
 | 
	
		
			
				|  |  | +	GridImageryProvider: 'GridImageryProvider',
 | 
	
		
			
				|  |  | +	IonImageryProvider: 'IonImageryProvider',
 | 
	
		
			
				|  |  | +	MapboxImageryProvider: 'MapboxImageryProvider',
 | 
	
		
			
				|  |  | +	MapboxStyleImageryProvider: 'MapboxStyleImageryProvider',
 | 
	
		
			
				|  |  | +	SingleTileImageryProvider: 'SingleTileImageryProvider',
 | 
	
		
			
				|  |  | +	TileCoordinatesImageryProvider: 'TileCoordinatesImageryProvider',
 | 
	
		
			
				|  |  | +	UrlTemplateImageryProvider: 'UrlTemplateImageryProvider',
 | 
	
		
			
				|  |  | +	WebMapServiceImageryProvider: 'WebMapServiceImageryProvider',
 | 
	
		
			
				|  |  | +	WebMapTileServiceImageryProvider: 'WebMapTileServiceImageryProvider',
 | 
	
		
			
				|  |  | +})
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  /* 输出类 */
 | 
	
		
			
				|  |  |  export default CrImageServerLayer
 |