刚开始用的是cesium加载geojson来达到加载三维建筑的目的,加载建筑物倒是没什么太大问题,只是建筑物还要进行贴图,如果再用geojson来加载贴图会特别卡,浏览器会崩溃,电脑会死机,于是发现官网有这种方法,加载完成之后速度特别快。而且是分片加载的,只加载视野区域内的建筑物,并且用这种方法来加载贴图也很快。但是加载之前本地必须引入xx.b3dm一个文件。否则加载不成功。
文档架构如下
代码如下
Cesium.Ion.defaultAccessToken = "官网申请的token"
var viewer = new Cesium.Viewer('cesiumContainer', {
imageryProvider: new Cesium.ArcGisMapServerImageryProvider({
url: 'https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer'
}),
animation: false,
timeline: false, //时间线
fullscreenButton: true, //全屏模式
infoBox: false, //要素信息框
homeButton: false, //显示主页
geocoder: false, //搜索位置
sceneModePicker: true,//模式切换
selectionIndicator: true, //展示三维的指示器
navigationHelpButton: false, //帮助按钮
navigationInstructionsInitiallyVisible: false
});
viewer.extend(Cesium.viewerCesiumNavigationMixin, {}); //添加指南针控件
//经度、纬度、建筑物视角高度
var initialPosition = new Cesium.Cartesian3.fromDegrees(117.11744684384189,39.128615983991416,500);
// var initialPosition = new Cesium.Cartesian3.fromDegrees(117.148,39.08135,500);
var initialOrientation = new Cesium.HeadingPitchRoll.fromDegrees(7.1077496389876024807, -31.987223091598949050, 0.025883251314950971306);
var homeCameraView = {
destination: initialPosition,
orientation: {
heading: initialOrientation.heading,//围绕负z轴的旋转
pitch: initialOrientation.pitch,//围绕负y轴的旋转
roll: initialOrientation.roll//围绕正x轴的旋转
}
};
viewer.scene.camera.setView(homeCameraView); //将相机设定在特定的位置和方向
//防止地面穿透
viewer.clock.onTick.addEventListener(function () {
if (viewer.camera.pitch > -0.5) {
viewer.scene.screenSpaceCameraController.enableTilt = false;
}
});
var mousePosition, startMousePosition;
var handler = new Cesium.ScreenSpaceEventHandler(viewer.canvas);
handler.setInputAction(function (movement) {
mousePosition = startMousePosition = Cesium.Cartesian3.clone(movement.position);
handler.setInputAction(function (movement) {
mousePosition = movement.endPosition;
var y = mousePosition.y - startMousePosition.y;
// console.log(y)
if (y > 0) {
viewer.scene.screenSpaceCameraController.enableTilt = true;
}
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
}, Cesium.ScreenSpaceEventType.MIDDLE_DOWN);
var layer = new Cesium.WebMapTileServiceImageryProvider({
url: 'http://t0.tianditu.gov.cn/img_w/wmts?tk=42dca576db031641be0524ee977ddd04',
layer: 'img',
style: 'default',
tileMatrixSetID: 'w',
format: 'tiles',
maximumLevel: 18
});
viewer.imageryLayers.addImageryProvider(layer);
var layer1 = new Cesium.WebMapTileServiceImageryProvider({
url: 'http://t0.tianditu.gov.cn/cia_w/wmts?tk=42dca576db031641be0524ee977ddd04',
layer: 'cia',
style: 'default',
tileMatrixSetID: 'w',
format: 'tiles',
maximumLevel: 18
});
viewer.imageryLayers.addImageryProvider(layer1);
以上是加载cesium默认一些鼠标事件,以及地图用的是天地图遥感影像图层。下面是加载建筑物的方法:
var tileset = new Cesium.Cesium3DTileset({
url:"http://192.168.9.123:9002/api/folder/c942a82fcb8647d7b47c607e24ee36b4/tileset.json"
});
viewer.scene.primitives.add(tileset);
tileset.readyPromise.then(function(tileset) {
viewer.scene.primitives.add(tileset);
var heightOffset = 0; //设置建筑物与地面的高度
var boundingSphere = tileset.boundingSphere;
var cartographic = Cesium.Cartographic.fromCartesian(boundingSphere.center);
var surface = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, 0.0);
var offset = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, heightOffset);
var translation = Cesium.Cartesian3.subtract(offset, surface, new Cesium.Cartesian3());
tileset.modelMatrix = Cesium.Matrix4.fromTranslation(translation);
viewer.zoomTo(tileset, new Cesium.HeadingPitchRange(0.5, -0.2, tileset.boundingSphere.radius * 1.0));
});
tileset.readyPromise.then(function(argument) {
var position = Cesium.Cartesian3.fromDegrees(longitude, latitude, height);
var mat = Cesium.Transforms.eastNorthUpToFixedFrame(position);
var rotationX = Cesium.Matrix4.fromRotationTranslation(Cesium.Matrix3.fromRotationZ(Cesium.Math.toRadians(heading)));
Cesium.Matrix4.multiply(mat, rotationX, mat);
tileset._root.transform = mat;
viewer.camera.flyTo({destination: Cesium.Cartesian3.fromDegrees(longitude, latitude, height + 1000)});
});
tileset.style = new Cesium.Cesium3DTileStyle({
defines: {
latitudeRadians: 'radians(${day})'
},
color: {
conditions: [
['${day} < 200', "color('#C6C4C4')"]
]
}
});
好了,这主要就是加载三维建筑物的代码,建筑物的配色是根据生成建筑物的文件里面的建筑物属性来配色的。那个tileset.json就是建筑物的数据接口。
加载贴图跟加载三维建筑物一样,这里是把贴图接口放入一个接口里了
$.ajax({
url: "http://192.168.9.123:8090/SelectUrl",
type: "post",
async: true,
dataType: "json",
contentType: "application/x-www-form-urlencoded; charset=utf-8",
success: function (data) {
console.log(data)
console.log(typeof data)
for (var i = 0; i < data.length; i++) {
var url = "http://192.168.9.123:9002/api/folder/"+data[i]+"/tileset.json"
console.log(url)
var imagetile = new Cesium.Cesium3DTileset({
url:url //贴图
});
viewer.scene.primitives.add(imagetile);
imagetile.style = new Cesium.Cesium3DTileStyle({
defines: {
latitudeRadians: 'radians(${day})'
},
color: {
conditions: [
['${day} < 30', "color('#267300')"],
['${day} >= 30 && ${day} < 35', "color('#5E8C00')"],
['${day} >= 35 && ${day} < 40', "color('#A8A800')"],
['${day} >= 40 && ${day} < 45', "color('#C48300')"],
['${day} >= 45 && ${day} < 50', "color('#E04B00')"],
['${day} >= 50 && ${day} < 55', "color('#FF0000')"],
['${day} >= 55 && ${day} < 60', "color('#D41923')"],
['${day} >= 60 && ${day} < 65', "color('#A82236')"],
['${day} >= 65 && ${day} < 70', "color('#7D250A')"],
['${day} >= 70 && ${day} < 75', "color('#4F275E')"],
['${day} >= 75', "color('#002673')"]
]
}
});
}
},
error: function (data) {
console.log(data)
}
})
最后上效果图
建筑物效果:
贴图效果:
总之用这种方式加载比加载geojson快的不是一点。