我使用的版本是1.112,因为版本不同,有些方法跟写法会有区别,这个需要注意
主要功能是实现模型展示,模型测点显示以及改变模型构件颜色
Cesium.Ion.defaultAccessToken = '你的token'
var viewer = new Cesium.Viewer('cesiumContainer', {
skyAtmosphere: new Cesium.SkyAtmosphere(),
baseLayerPicker: false, // 影像切换
animation: false, //是否显示动画控件
timeline: false, //是否显示时间线控件
infoBox: false, //是否显示点击要素之后显示的信息
geocoder: false, //是否显示地名查找控件
navigationHelpButton: false, //是否显示帮助信息控件
fullscreenButton:false,//全屏
vrButton:false,
homeButton:false,//首页
infoBox:false,//信息框
sceneModePicker:false,//场景模式
selectionIndicator:false,//选择指示器
navigationHelpButton:false//时间线
});
设置相机,相机视角:v_longitude:定位经度,v_latitude:定位纬度,v_height:相机高度,v_heading:水平旋转角度,v_pitch:俯仰角度,v_roll:翻滚角度
viewer.scene.camera.setView({
destination: Cesium.Cartesian3.fromDegrees(//参数:(经度,纬度,椭球上方的高度)
view.v_longitude,
view.v_latitude,//调纬度可以拉近视角
view.v_height
),
orientation: {
heading: Cesium.Math.toRadians(view.v_heading),
pitch: Cesium.Math.toRadians(view.v_pitch),
roll: Cesium.Math.toRadians(view.v_roll) //heading、pitch和roll就是镜头相对于xyz轴的角度,比如pitch为-90°而另外两个为0时,就是90°向下俯视地球
}
});
对地图进行操作需得等地图加载出来后再执行
// 最小缩放高度(米)
viewer.scene.screenSpaceCameraController.minimumZoomDistance = 100;
// 最大缩放高度(米)
viewer.scene.screenSpaceCameraController.maximumZoomDistance = 8000;
//显示部分区域113.38, 22.11, 113.51, 22.22
let coffeeBeltRectangle = new Cesium.Rectangle.fromDegrees(113.226394, 21.930137, 113.500404, 22.095537);//最西的经度,最南端的纬度,最东的经度,最北端的纬度
viewer.scene.globe.cartographicLimitRectangle = coffeeBeltRectangle;
//添加地形
// viewer.terrainProvider = await Cesium.createWorldTerrainAsync({//添加全球范围高质量地形数据的便捷方法
//添加自定义地形数据源
viewer.terrainProvider = await Cesium.CesiumTerrainProvider.fromUrl('../../HTML_model/scripts/Assets/dem',{
requestWaterMask: true, // 请求水体遮罩
requestVertexNormals: true // 请求顶点法线以改善光照效果
});
//添加建筑
// viewer.scene.primitives.add(await Cesium.createOsmBuildingsAsync());
//关闭时间对于模型亮度的影响
// viewer.scene.light = new Cesium.DirectionalLight({
// direction: new Cesium.Cartesian3(0.354925, -0.890918, -0.283358)
// });
对模型进行标点需要先点击模型获取经纬度高度坐标,再将其转换成笛卡尔坐标
获取坐标的方法
const search = (viewer) => {
const handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
handler.setInputAction(function (event) {
var earthPosition = viewer.scene.pickPosition(event.position);
var cartographic = Cesium.Cartographic.fromCartesian(earthPosition);
var longitudeString = Cesium.Math.toDegrees(cartographic.longitude);
var latitudeString = Cesium.Math.toDegrees(cartographic.latitude);
console.log("坐标",longitudeString, latitudeString, cartographic.height);
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
};
转换成笛卡尔坐标
const position = Cesium.Cartesian3.fromDegrees(
113.37539144506866, 22.01542218818829, 28.297001267728
);
将测点遍历显示出来
const a=a_data;//测点笛卡尔坐标数据
// const a=[{
// x: -2352750.078,y: 5421498.473 ,z:2390420.521
// }];
const modelPunctuation=(viewer) => {
a.forEach((el,index)=>{
$(`
<div class="coordinate" id="speed${index}">
<!-- <div class="coordinate_label">{{ item.CameraName }}</div> -->
<img class="coordinate_icon" src="/HTML_model/images/coordinate.png">
</div>
`).appendTo('#speed_points');
let speedEvent = viewer.scene.preRender.addEventListener(() => {//在场景更新之后以及场景渲染之前执行
let ele = document.getElementById("speed" + index);
if (ele != null) {
let scratch = new Cesium.Cartesian2();
let position = {//3D笛卡尔点位置
x:el.x,
y:el.y,
z:el.z
};
// console.log(position);
let canvasPosition =viewer.scene.cartesianToCanvasCoordinates(position, scratch);//将笛卡尔坐标中的位置转换为画布坐标
if (canvasPosition && canvasPosition.x && canvasPosition.y) {//未缩放时整体坐标偏移位置
ele.style.left = `${canvasPosition.x - ele.offsetWidth / 2}px`;
ele.style.top = `${canvasPosition.y- ele.offsetHeight / 2}px`;
}
};
});
});
};
如果需要对地图不满意的部分进行遮挡,可以使用以下方法,不过不能调旋转角度,不好用
const hqeq_Texture=(viewer)=>{
// 图片的经纬度范围
var west = 113.456355;
var south = 22.154288;
var east = 113.460418;
var north = 22.157447;
// 图片的URL
var imageUrl = '../public/HTML_model/images/hqeq_texture.png';
// 创建 imagery provider
var rectangle = Cesium.Rectangle.fromDegrees(west, south, east, north);
var imageProvider = new Cesium.UrlTemplateImageryProvider({
url: imageUrl,
rectangle: rectangle,
minimumLevel:1,
maximumLevel:1
});
// 添加图像层到视图
viewer.imageryLayers.addImageryProvider(imageProvider);
};
导入模型
//导入模型
async function loadModel(modelURL){
const position = Cesium.Cartesian3.fromDegrees(//位置
view.longitude,
view.latitude,
view.height
);
const heading = Cesium.Math.toRadians(view.heading);//转换成弧度,左右旋转
const pitch = view.pitch;//上下旋转
const roll = view.roll;//翻转
const hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll);
const orientation = Cesium.Transforms.headingPitchRollQuaternion(
position,
hpr
);//转换成四元数
const scale=new Cesium.Cartesian3(
view.scale,
view.scale,
view.scale
);
const entity_id=view.codec;
let modelMatrix=Cesium.Matrix4.fromTranslationQuaternionRotationScale(position, orientation, scale);
let primitive =viewer.scene.primitives.add(await Cesium.Model.fromGltfAsync({
id:entity_id,
url: view.url,
modelMatrix: modelMatrix,
minimumPixelSize: 128,
maximumScale: 2000,
// color : Cesium.Color.RED// 改颜色,白色半透明材质可以使模型显得更亮#8f97aa
color : Cesium.Color.fromCssColorString('#e0e4e7')// 改颜色,白色半透明材质可以使模型显得更亮
}));
getSensorsList(stage);
};
找到模型的构件
let entity = viewer.scene.primitives._primitives.find(item=>item._id===monitor_project);
构件都在entity._nodesByName里面,设置构件颜色并存取原来颜色,用于恢复颜色
entity.getNode(node)._runtimeNode.node.primitives.map((p,index)=>{
node_color.push({id:index,o_color:p.material.metallicRoughness.baseColorFactor});
p.material.metallicRoughness.baseColorFactor=new Cesium.Cartesian4(1,0,0,1);
});
模型需要进行压缩,不然太大,具体参考GLTF(2):使用gltf-pipeline对gltf进行压缩_gltf文件在线压缩-CSDN博客
快捷添加地形以前是Cesium.createWorldTerrain,现在改为Cesium.createWorldTerrainAsync
添加自定义数据以前是这种写法
viewer.terrainProvider = await Cesium.CesiumTerrainProvider({
url:'../../HTML_model/scripts/Assets/dem',
requestWaterMask: true, // 请求水体遮罩
requestVertexNormals: true // 请求顶点法线以改善光照效果
});
现在是这种写法,使用formUrl
viewer.terrainProvider = await Cesium.CesiumTerrainProvider.fromUrl('../../HTML_model/scripts/Assets/dem',{
requestWaterMask: true, // 请求水体遮罩
requestVertexNormals: true // 请求顶点法线以改善光照效果
});
但是这样添加地形山形会导致平面也会凹凸不平,最好是添加自定义地形数据
首先在地理空间数据云下载地形数据,在cesiumlab进行地形切片
参考cesium示例集--4.加载地形服务_cesium 添加地形-CSDN博客
【CesiumJS-2】自定义地图图层与加载地形服务_cesium 添加天地图三维地名-CSDN博客
其他参考资料: