zoukankan      html  css  js  c++  java
  • 官方示例之地球模块十三:建筑拔高

    /**
     * 该示例主要展示了根据底面坐标轮廓和高度进行拔楼的功能
     * 该示例中的插值功能主要用到了Tween.js
     * 该示例用到的数据地址为:https://www.thingjs.com/uearth/uGeo/chaoyang_building.geojson
     * 其中建筑的高度为随机值,无特殊意义
     */
    var app = new THING.App();
    app.background = [0, 0, 0];
    var map;
    THING.Utils.dynamicLoad('https://www.thingjs.com/uearth/uearth.min.js', function () {
    	map = app.create({
    		type: 'Map',
    		attribution: 'Google'
    	});
    
    	// 创建一个瓦片图层
    	var tileLayer1 = app.create({
    		type: 'TileLayer',
    		name: 'tileLayer1',
    		url: 'https://mt{0,1,2,3}.google.cn/vt/lyrs=s&hl=zh-CN&gl=cn&x={x}&y={y}&z={z}',
    		style: {
    			template: CMAP.TileLayerStyle.DARKGREEN // 设置瓦片图层的样式为DARKGREEN
    		}
    	});
    	// 将瓦片图添加到地图中
    	map.addLayer(tileLayer1);
    	// 创建一个建筑物图层
    	var buildingLayer = app.create({
    		type: 'ThingLayer',
    		name: 'buildingLayer'
    	});
    	// 将 buildingLayer 添加到 map 中
    	map.addLayer(buildingLayer);
    
    	// 飞到地理位置和高度
    	app.camera.earthFlyTo({
    		lonlat: [116.4488, 39.9187],
    		height: 4000,
    		time: 2000,
    		lerp: THING.LerpType.Linear.None,
    		complete: function () {
    			app.camera.curOrbit.setState();
    			setTimeout(createBuilding, 1000);
    		}
    	});
    	var createBuilding = function () {
    		$.ajax({
    			type: 'GET',
    			url: 'https://www.thingjs.com/uearth/uGeo/chaoyang_building.geojson',
    			dataType: 'json',
    			success: function (data) {
    				// 对数据进行排序
    				sortBuildData(data);
    				// 加载楼宇
    				addBuildAsync(data, 0, function () {
    				});
    			}
    		});
    	};
    	// 每次创建建筑数量
    	var step = 70;
    	function addBuildAsync(arr, start, cb) {
    		var building;
    		var i = start;
    		var j = THING.Math.min(start + step, arr.features.length);
    		// 循环创建建筑,先将其高度都设置成1米
    		for (; i < j; i += 1) {
    			building = app.create({
    				type: 'GeoBuilding',
    				name: 'build' + i,
    				coordinates: arr.features[i].geometry.coordinates,
    				userData: arr.features[i].properties,
    				height: 1,
    				renderer: {
    					type: 'image',
    					imageUrl: ['https://www.thingjs.com/uearth/uGeo/building_top.png', 'https://www.thingjs.com/uearth/uGeo/building.png'], // 楼宇顶部贴图和侧边贴图
    					blending: true, // 贴图叠加混合
    					textureWrap:CMAP.TextureWrapMode.Stretch
    				}
    			});
    			buildingLayer.add(building);
    		}
    		if (j < arr.features.length) {
    			// 异步递归下一次循环
    			setTimeout(function () {
    				addBuildAsync(arr, j, cb);
    			}, 0);
    		}
    		else if (typeof cb === 'function') {
    			cb();
    		}
    	}
    	// 对楼宇数据按照其中心点,从西到东排序
    	function sortBuildData(arr) {
    		arr.features.sort(function (a, b) {
    			return (a.properties.centerx - b.properties.centerx);
    		});
    	}
    	// 不同街道的相机视角
    	var camPos = {
    		'建外街道': {
    			position: [2179362.5621945052, 4091446.2018570947, 4382089.316474768],
    			target: [2178592.77284655, 4091931.0390559826, 4380492.883422022],
    			up: [0.34164472651390604, 0.6413960312283457, 0.6869425099451665]
    		},
    		'朝外街道': {
    			position: [2177287.5596858454, 4093097.7380608646, 4381963.4315843275],
    			target: [2177867.783281599, 4092609.529367086, 4380219.533160159],
    			up: [0.3413043969490713, 0.6416204643836936, 0.6869020951396816]
    		},
    		'呼家楼街道': {
    			position: [2180796.208593407, 4092585.7199409953, 4381166.2383312695],
    			target: [2178653.476017196, 4092893.444632129, 4379563.480796406],
    			up: [0.3415888171867664, 0.6417205149940622, 0.6866672124171224]
    		},
    		'三里屯街道': {
    			position: [2180049.8274386693, 4094127.8027542974, 4379868.140003332],
    			target: [2178462.4045711374, 4094071.222602554, 4378557.5679814685],
    			up: [0.34172853816543197, 0.6417652897142498, 0.6865558383127347]
    		},
    		'东外街道': {
    			position: [2176806.062780602, 4093945.081429624, 4381311.039653606],
    			target: [2177692.216493408, 4093814.228132429, 4379180.936632392],
    			up: [0.3412325931407259, 0.641760200965019, 0.6868072231971607]
    		},
    		'左家庄街道': {
    			position: [2178343.586772876, 4095041.600086432, 4379738.026890182],
    			target: [2178049.2702569016, 4095201.3772697616, 4377706.140884884],
    			up: [0.3414940843927409, 0.6420823733568143, 0.6863760020202075]
    		},
    		'团结湖街道': {
    			position: [2180423.2727790484, 4093298.1298934473, 4380347.1220772965],
    			target: [2179657.996113762, 4093548.054626523, 4378451.706304496],
    			up: [0.3417463148500724, 0.6418231506156354, 0.6864928984484943]
    		}, '麦子店街道': {
    			position: [2180809.303744469, 4097285.615845475, 4377199.009997367],
    			target: [2178441.4391688984, 4094647.778341093, 4378028.833554901],
    			up: [0.34155557214940396, 0.6419955751553925, 0.686426596669003]
    		}
    	};
    
    	var blocks = ['全景', '建外街道', '朝外街道', '呼家楼街道', '三里屯街道', '东外街道', '左家庄街道', '团结湖街道', '麦子店街道'];
    	// 创建一个tween对象
    	function grow(fromBlock, toBlock, cb) {
    		var indexForm = blocks.indexOf(fromBlock);
    		var indexTo = blocks.indexOf(toBlock);
    		var tw = buildTween(blocks[indexForm], blocks[indexTo], cb);
    		return tw;
    	}
    	// 创建生长动画对象
    	function buildTween(fromBlock, toBlock, cb) {
    		var growTween = new TWEEN.Tween({ num: 0 }).to({ num: 1 }, 3000).easing(TWEEN.Easing.Linear.None)
    			.onUpdate(function (obj) {
    				setBuildingHeight(fromBlock, toBlock, obj.num);
    			}).onStart(function () {
    				app.camera.flyTo({
    					position: camPos[toBlock].position,
    					target: camPos[toBlock].target,
    					time: 1000,
    					up: camPos[toBlock].up,
    					lerp: THING.LerpType.Linear.None,
    					upLerp: THING.LerpType.Linear.None
    				});
    			});
    		return growTween;
    	}
    	// 遍历buildingLayer中的楼宇对象,对其设置高度
    	function setBuildingHeight(fromBlock, toBlock, num) {
    		// 进度条onChange触发的情况
    		if (fromBlock == toBlock) {
    			var temp_blocks = blocks.slice(0, blocks.indexOf(toBlock) + 1);
    			buildingLayer.children.forEach(function (v) {
    				v.height = 1;
    				if (temp_blocks.indexOf(v.userData['district']) >= 0) {
    					v.visible = true;
    					v.height = v.userData['height'];
    				}
    			});
    		}
    		// tween触发的情况
    		else {
    			buildingLayer.children.forEach(function (v) {
    				if (v.userData['district'] == toBlock) {
    					var startHeight = 1;
    					var stopHeight = v.userData['height'];
    					var currentHeight = startHeight + (stopHeight - startHeight) * num;
    					v.visible = true;
    					v.height = currentHeight;
    				}
    			});
    		}
    	}
    	var progressObj = { progress: 0 };
    	// 创建一个进度条
    	function creatProgress() {
    		var bar = new THING.widget.Panel({  '800px' });
    		bar.position = [10, 10];
    		var progress = bar.addProgress(progressObj, 'progress', [
    			{ name: '全景', describe: '建外街道' },
    			{ name: '建外街道', describe: '朝外街道' },
    			{ name: '朝外街道', describe: '呼家楼街道' },
    			{ name: '呼家楼街道', describe: '三里屯街道' },
    			{ name: '三里屯街道', describe: '东外街道' },
    			{ name: '东外街道', describe: '东外街道' },
    			{ name: '左家庄街道', describe: '团结湖街道' },
    			{ name: '团结湖街道', describe: '团结湖街道' },
    			{ name: '麦子店街道', describe: '全景' },
    		]);
    
    		var tween = undefined;
    		// 设置每一步播放需要的时间,单位毫秒
    		progress.time(3000);
    		// 进度条变化
    		progress.on('change', function (id) {
    			setBuildingHeight(blocks[id], blocks[id], 1);
    			if (tween) {
    				tween.stop();
    				if (id < blocks.length - 1) {
    					tween = grow(blocks[id], blocks[id + 1]);
    					tween.start();
    				}
    				else {
    					app.camera.earthFlyTo({
    						lonlat: [116.4488, 39.9187],
    						height: 4000,
    						time: 2000
    					});
    				}
    			}
    		});
    		progress.startCallback(function (state, id) {
    			if (tween) {
    				tween.stop();
    				setBuildingHeight(blocks[id], blocks[id], 1);
    			}
    			if (state) {
    				tween = grow(blocks[id], blocks[id + 1]);
    				tween.start();
    			}
    		});
    	}
    	creatProgress();
    });
    
    
  • 相关阅读:
    TFS二次开发-基线文件管理器(5)-源码文件的读取
    TFS二次开发-基线文件管理器(4)-标签的创建
    TFS二次开发-基线文件管理器(3)-源码文件的读取
    TFS二次开发-基线文件管理器(2)-TFS登录
    TFS二次开发-基线文件管理器(1)-设计
    学习实践:使用模式,原则实现一个C++自动化测试程序
    学习实践:使用模式,原则实现一个C++数据库访问类
    C++字符转换等常用方法
    sqlserver 创建 aspstate的方法
    双网卡只有一个能ping通的解决办法
  • 原文地址:https://www.cnblogs.com/thingjs/p/13840362.html
Copyright © 2011-2022 走看看