Cesium单体化效果及监听
**
这章我们讲解Cesium中如何单体化以及监听点击事件,上代码:
1.先加载三维模型
var viewer = new Cesium.Viewer('cesiumContainer', {
//需要进行可视化的数据源的集合
selectionIndicator: false,//关闭绿色点击框
animation: false, //是否显示动画控件
shouldAnimate: true,
homeButton: false, //是否显示Home按钮
fullscreenButton: false, //是否显示全屏按钮
baseLayerPicker: false, //是否显示图层选择控件
geocoder: false, //是否显示地名查找控件
timeline: false, //是否显示时间线控件
sceneModePicker: false, //是否显示投影方式控件
navigationHelpButton: false, //是否显示帮助信息控件
infoBox: false, //是否显示点击要素之后显示的信息
requestRenderMode: true, //启用请求渲染模式
scene3DOnly: false, //每个几何实例将只能以3D渲染以节省GPU内存
sceneMode: 3, //初始场景模式 1 2D模式 2 2D循环模式 3 3D模式 Cesium.SceneMode
fullscreenElement: document.body, //全屏时渲染的HTML元素 暂时没发现用处
//加载arcgis大屏地图,ArcGisMapServerImageryProvider 火星坐标和谷歌一样
imageryProvider: new Cesium.ArcGisMapServerImageryProvider({
url: 'https://services.arcgisonline.com/arcgis/rest/services/World_Imagery/MapServer',
})
});
//开启地形深度检测
viewer.scene.globe.depthTestAgainstTerrain = true; //默认为false
//定位到目的地
viewer.scene.camera.setView({
destination: new Cesium.Cartesian3(-2245028.6351935025, 4645894.817835149, 3736807.1223881883),
orientation: {
heading: 0.6603500068839194,
pitch: -0.5595114015440812,
roll: 6.283183331396049
}
});
//加载模型数据
let tileset = new Cesium.Cesium3DTileset({
url: "XXXXX/3dtilesmodel/factory/tileset.json", //瓦片路径,指向json
skipLevelOfDetail: true,//这个参数在金字塔数据加载中,可以跳过一些级别,这样整体的效率会高一些,数据占用也会小一些。
skipScreenSpaceErrorFactor: 16,
baseScreenSpaceError: 1024,
maximumScreenSpaceError: 10, // 数值加大,能让最终成像变模糊 //也可以解决内存不足的问题
immediatelyLoadDesiredLevelOfDetail: false,
loadSiblings: true, // 如果为true则不会在已加载完概况房屋后,自动从中心开始超清化房屋
cullWithChildrenBounds: true,
cullRequestsWhileMoving: true,
cullRequestsWhileMovingMultiplier: 10, // 值越小能够更快的剔除
preloadWhenHidden: true,
preferLeaves: true,//这样我们就能最快的看见符合当前视觉精度的块
maximumMemoryUsage: 2048, // 内存分配变小有利于倾斜摄影数据回收,提升性能体验 比如我的显存是6G,这个可以设置到3000左右。
progressiveResolutionHeightFraction: 0.5, // 数值偏于0能够让初始加载变得模糊
dynamicScreenSpaceErrorDensity: 0.5, // 数值加大,能让周边加载变快
dynamicScreenSpaceErrorFactor: 1, // 不知道起了什么作用没,反正放着吧先
dynamicScreenSpaceError: false, // 根据测试,有了这个后,会在真正的全屏加载完之后才清晰化房屋
});
tileset.readyPromise.then(function (palaceTileset) {
viewer.scene.primitives.add(palaceTileset)
var heightOffset = -39.5; //设置模型高度
var boundingSphere = palaceTileset.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()
);
palaceTileset.modelMatrix = Cesium.Matrix4.fromTranslation(translation);
});
2.再加载单体化数据,单体化数据就是绘制的一个个建筑面,然后用面去贴模型。
//jquery或者其他方式获取建筑面的json数据
$.get('./data/Basicdata/build.json', (data)=> {
let features = data.features
features.forEach((item) => {
//获取cesium的三维坐标
let degreesArray = getDegreesArray(item);
viewer.entities.add({
//唯一标识,用于点击事件
beof:'建筑',
polygon: {
hierarchy: Cesium.Cartesian3.fromDegreesArray(degreesArray),
//设置颜色为无色 点击才变色
material: Cesium.Color.WHITE.withAlpha(0),
//设置只贴模型 不贴地
classificationType: Cesium.ClassificationType.CESIUM_3D_TILE,
},
});
});
})
//获取坐标串 不带高度 工具类
function getDegreesArray(feature) {
let degreesArray = [];
let coordinates;
if (feature.geometry.type == "MultiPolygon") {
coordinates = feature.geometry.coordinates[0][0];
} else if (feature.geometry.type == "Polygon") {
coordinates = feature.geometry.coordinates[0];
} else if (feature.geometry.type == "LineString") {
coordinates = feature.geometry.coordinates;
}
for (let i = 0; i < coordinates.length; i++) {
const element = coordinates[i];
degreesArray.push(element[0]);
degreesArray.push(element[1]);
}
return degreesArray;
}
吧颜色改为不透明的话,成功的效果应该如下:
3.取消初始化高亮,监听点击高亮事件
//注册点击事件
var handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
//初始化上一次高亮的建筑
var entityBuild
handler.setInputAction(function (e) {
var pick = viewer.scene.pick(e.position);
var cartesian = viewer.scene.pickPosition(e.position);
if (pick && pick.id) {
//如果选中的是建筑
if (pick.id.beof == "建筑") {
//则将上一次的建筑颜色变为无色
if (entityBuild) {
entityBuild.material.color = Cesium.Color.WHITE.withAlpha(0)
}
//再高亮这次的建筑
entityBuild = pick.id.polygon
entityBuild.material.color = Cesium.Color.RED.withAlpha(1)
}
} else {
//如果没选中则同样改为无色
if (entityBuild) {
entityBuild.material.color = Cesium.Color.WHITE.withAlpha(0)
}
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
以上就是完整的单体化代码,大家照抄即可,后续小编会持续更新cesium各种源码,特效以及其他效果或者模型加载的实现方式,还希望大家多多关注,小编也会持续更新的!
tips:如果还有小伙伴需要其他的源码的请加我 QQ657155100或者留言联系~
声明:转载请声明出处。