123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239 |
- // 物体状态
- var EntityState = {
- FAILED: 0,
- UNLOADED: 1,
- RECEIVING: 2,
- RECEIVED: 3,
- TRANSFORMING: 4,
- TRANSFORMED: 5,
- READY: 6
- };
- /**
- * 物体瓦片,负责管理瓦片内物体的加载过程。
- * @param provider
- * @constructor
- */
- function TileEntity(provider) {
- if (!Cesium.defined(provider)) {
- throw new DeveloperError('provider is required.');
- }
- this.provider = provider;
- this.state = EntityState.UNLOADED;
- this.buffers = [];
- this.dataList = [];
- }
- /**
- * Processes the load state machine for this instance.
- *
- */
- TileEntity.prototype.processStateMachine = function (frameState, entityProvider, x, y, level, priorityFunction) {
- if (this.state === EntityState.UNLOADED) {
- requestEntityData(this, entityProvider, x, y, level, priorityFunction);
- }
- if (this.state === EntityState.RECEIVED) {
- transform(this, frameState, entityProvider, x, y, level);
- }
- if (this.state === EntityState.TRANSFORMED) {
- createResources(this, frameState.context, entityProvider, x, y, level);
- }
- if (this.state === EntityState.READY) {
- return true; // done loading
- }
- // 没有加载完成也应该使用父节点的,不能四个子节点都使用父节点显示那样就重复了;可以给节点增加计数,确保每个节点只显示一次。
- // 目前所有父节点都是可见,后期再完善。
- // Find some ancestor imagery we can use while this imagery is still loading.
- // var ancestor = this.parent;
- // var closestAncestorThatNeedsLoading;
- // while (defined(ancestor) && (ancestor.state !== ImageryState.READY || (!this.useWebMercatorT && !defined(ancestor.texture)))) {
- // if (ancestor.state !== ImageryState.FAILED && ancestor.state !== ImageryState.INVALID) {
- // // ancestor is still loading
- // closestAncestorThatNeedsLoading = closestAncestorThatNeedsLoading || ancestor;
- // }
- // ancestor = ancestor.parent;
- // }
- //
- // if (this.readyImagery !== ancestor) {
- // if (defined(this.readyImagery)) {
- // this.readyImagery.releaseReference();
- // }
- //
- // this.readyImagery = ancestor;
- //
- // if (defined(ancestor)) {
- // ancestor.addReference();
- // this.textureTranslationAndScale = imageryLayer._calculateTextureTranslationAndScale(tile, this);
- // }
- // }
- if (this.state === EntityState.FAILED) {
- // The imagery tile is failed or invalid, so we'd like to use an ancestor instead.
- // if (defined(closestAncestorThatNeedsLoading)) {
- // // Push the ancestor's load process along a bit. This is necessary because some ancestor imagery
- // // tiles may not be attached directly to a terrain tile. Such tiles will never load if
- // // we don't do it here.
- // closestAncestorThatNeedsLoading.processStateMachine(frameState, !this.useWebMercatorT, tile._priorityFunction);
- // return false; // not done loading
- // }
- // This imagery tile is failed or invalid, and we have the "best available" substitute.
- return true; // done loading
- }
- return false; // not done loading
- }
- function requestEntityData(tileEntity, entityProvider, x, y, level, priorityFunction) {
- function success(buffers) {
- if (!Cesium.defined(buffers)) {
- tileEntity.state = EntityState.UNLOADED;
- tileEntity.request = undefined;
- return;
- }
- tileEntity.buffers = buffers;
- tileEntity.state = EntityState.RECEIVED;
- tileEntity.request = undefined;
- }
- function failure() {
- if (tileEntity.request.state === RequestState.CANCELLED) {
- // Cancelled due to low priority - try again later.
- tileEntity.state = EntityState.UNLOADED;
- tileEntity.request = undefined;
- return;
- }
- // Initially assume failure. handleError may retry, in which case the state will
- // change to RECEIVING or UNLOADED.
- tileEntity.state = EntityState.FAILED;
- tileEntity.request = undefined;
- var message = 'Failed to obtain entity tile X: ' + x + ' Y: ' + y + ' Level: ' + level + '.';
- entityProvider._requestError = Cesium.TileProviderError.handleError(
- entityProvider._requestError,
- entityProvider,
- entityProvider.errorEvent,
- message,
- x, y, level,
- doRequest);
- }
- function doRequest() {
- // Request the entity data from the entity provider.
- var request = new Cesium.Request({
- throttle: true,
- throttleByServer: true,
- type: Cesium.RequestType.TILES3D,
- priorityFunction: priorityFunction
- });
- tileEntity.request = request;
- var data = entityProvider.requestEntityData(x, y, level, request);
- // If the request method returns undefined (instead of a promise), the request
- // has been deferred.
- if (Cesium.defined(data)) {
- tileEntity.state = tileEntity.RECEIVING;
- Cesium.when(data, success, failure);
- } else {
- // Deferred - try again later.
- //tileEntity.state = EntityState.UNLOADED;
- tileEntity.request = undefined;
- tileEntity.state = EntityState.FAILED;
- }
- }
- doRequest();
- }
- function transform(tileEntity, frameState, provider, x, y, level) {
- if (!Cesium.defined(tileEntity.buffers)) {
- return null;
- }
- // 解析数据(也可以放在分支线程)
- for (var i = 0, len = tileEntity.buffers.length; i < len; ++i) {
- var stream = new MemStream(tileEntity.buffers[i]);
- var version = stream.readInt32();
- var count = stream.readInt32();
- for (var j = 0; j < count; ++j) {
- var lon = stream.readFloat();
- var lat = stream.readFloat();
- var h = stream.readFloat();
- var text = '';
- var textLen = stream.readUChar8();
- if (textLen > 0) {
- var strData = stream.readUChar8Array2(textLen);
- text = new TextDecoder("utf-8").decode(strData);
- text = text.replace(/\|/g, ''); // 替换掉所有的|字符
- }
- var useFont = provider.fontSize * 2 + "px " + provider.fontFamily;
- var entity = provider.viewer.entities.add({
- parent: provider.fatherGroup,
- position: Cesium.Cartesian3.fromDegrees(lon, lat, h),
- label: {
- text: text,
- font: useFont,
- fillColor: Cesium.Color.WHITE,
- outlineColor: Cesium.Color.BLACK,
- outlineWidth: 6,
- style: Cesium.LabelStyle.FILL_AND_OUTLINE,
- scale: 0.5
- }
- });
- tileEntity.dataList.push(entity.id); // 保留id供移除时使用
- }
- }
- tileEntity.buffers.length = 0;
- tileEntity.state = EntityState.TRANSFORMING;
- // 如果是在其他线程做,完成后再改变状态
- // when(meshPromise, function(mesh) {
- // tileTerrain.mesh = mesh;
- // tileTerrain.state = TerrainState.TRANSFORMED;
- // }, function() {
- // tileTerrain.state = TerrainState.FAILED;
- // });
- tileEntity.state = EntityState.TRANSFORMED;
- }
- function createResources(tileEntity, context) {
- // 使用现有的结构就不手动构建渲染单元了
- // tileTerrain.vertexArray = new VertexArray({
- // context : context,
- // attributes : attributes,
- // indexBuffer : indexBuffer
- // });
- tileEntity.state = EntityState.READY;
- }
- TileEntity.prototype.freeResources = function () {
- for (var i = 0, len = this.dataList.length; i < len; ++i) {
- this.provider.viewer.entities.removeById(this.dataList[i]);
- }
- this.dataList.length = 0;
- this.buffers.length = 0;
- };
|