/**
* 该示例主要展示了根据底面坐标轮廓和高度进行拔楼的功能
* 该示例中的插值功能主要用到了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({ width: '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();
});