一、基础使用:Cesium.js基础使用(vue)-CSDN博客
1、基础路径
为 Cesium 库设置一个全局变量 CESIUM_BASE_URL
,用于指定 Cesium 的资源文件(如 WebGL shaders、纹理、字体等)的
示例场景:假设你在开发一个基于 Cesium 的 3D 地球应用,但不想将 Cesium 的资源文件打包到项目中,而是希望通过 CDN 加载资源。
window.CESIUM_BASE_URL = 'https://cesium.com/downloads/cesiumjs/releases/1.97/Build/Cesium/';
2、Cesium Ion的默认访问令牌
Cesium.Ion.defaultAccessToken = ''; // 赋值你的访问令牌
二、其他配置
1、HTML自定义实体弹窗
// 以下代码都在onMounted钩子函数里
// 函数用于创建一个新的小点实体和对应的HTML弹窗
const createPoint = (id, position, info) => {
// 创建小点实体
var point = viewer.entities.add({
position: position, // 位置
point: {
// 点的样式
pixelSize: 10, // 像素大小
},
show: false, // 默认隐藏实体
});
// 创建HTML弹窗元素
let element = document.createElement('div');
element.className = 'locator';
element.innerHTML = `
<h3>${info.title}</h3>
<p>名称:${info.name}</p>
<p>类型:${info.type}</p>
<p>时间:${info.time}</p>
`;
// 设置初始可见性
element.style.display = state.eventVisible ? 'block' : 'none';
// 将HTML弹窗元素添加到Cesium Viewer容器中
viewer.container.appendChild(element);
//为弹窗添加点击事件
element.addEventListener('click', () => {
state.eventModalVisible = true;
state.eventId = id;
});
// 将小点实体和HTML弹窗元素存入相应的集合
state.points.push(point);
state.pointElements[point.id] = element;
return point;
};
//获取事件点数据
const getEventPoint = async () => {
state.pointsData = [];
let res = await getEventTaskList();
if (res.code === 200) {
res.data.list.forEach(item => {
if (item.f_lng !== null && item.f_lat !== null) {
state.pointsData.push({
id: item.id,
position: Cesium.Cartesian3.fromDegrees(parseFloat(item.f_lng), parseFloat(item.f_lat), 0),
info: { title: item.f_leve, name: item.f_name, type: item.f_from_type, time: item.f_create_time },
});
}
});
state.pointsData.forEach(function (data) {
createPoint(data.id, data.position, data.info);
});
} else {
console.log(res.msg);
}
};
getEventPoint();
//当鼠标拖动地图或放大缩小地图时,更新所有HTML弹窗的位置
function updateAllElementPositions() {
var scene = viewer.scene;
// 如果场景模式不是MORPHING,则更新所有HTML弹窗的位置
if (scene.mode !== Cesium.SceneMode.MORPHING) {
// 遍历所有小点实体,更新对应的HTML弹窗的位置
state.points.forEach(function (point) {
var canvas = scene.canvas;
// 获取小点实体的位置
var cartesian = Cesium.Property.getValueOrUndefined(point.position, scene.lastRenderTime);
// 将笛卡尔坐标转换为屏幕坐标
var pixelPosition = scene.cartesianToCanvasCoordinates(cartesian);
// 如果屏幕坐标存在,则更新HTML弹窗的位置
if (pixelPosition) {
// 获取HTML弹窗元素
var element = state.pointElements[point.id];
// 设置HTML弹窗元素的位置
element.style.left = pixelPosition.x + 'px';
element.style.top = pixelPosition.y + 'px';
// 检查可见性
element.style.display = state.eventVisible ? 'flex' : 'none';
}
});
}
}
// 监听Cesium场景更新事件,以便在每次渲染时更新所有HTML弹窗的位置
viewer.scene.postRender.addEventListener(updateAllElementPositions);
// 函数用于更新所有弹窗的可见性
function updatePopupVisibility() {
Object.values(state.pointElements).forEach(element => {
element.style.display = state.eventVisible ? 'block' : 'none';
});
}
//更新弹框显隐
watch(
() => state.eventVisible,
newVal => {
updatePopupVisibility();
},
);
onUnmounted(() => {
//页面卸载时清除事件监听器
window.removeEventListener('unload', function () {
viewer.scene.postRender.removeEventListener(updateAllElementPositions);
});
}
:deep(.locator) {
display: flex;
flex-direction: column;
align-items: center;
position: absolute;
width: 236px;
height: 207px;
margin-top: -190px;
margin-left: -118px;
background: url('/src/assets/images/screen/locator.png') no-repeat center center;
padding: 23px 0;
cursor: pointer;
}
2、让弹框和相关区域同时显隐
//该函数用于输入多边形顶点坐标,能够绘制多边形在视图上,多边形背景颜色为红色,边框为黄色
function drawPolygon(points, isShow, entities) {
let color;
if (entities === state.irrigationEntities) {
color = Cesium.Color.BLUE.withAlpha(0.5);
};
var polygon = viewer.entities.add({
polygon: {
hierarchy: Cesium.Cartesian3.fromDegreesArray(points),
material: color,
outline: true,
},
show: isShow,
});
//将多边形实体ID存入相应的集合
entities.push(polygon.id);
}
//监听showIrrigation,为true时绘制灌区,否则隐藏
watch(
() => state.showIrrigation,
newVal => {
if (newVal) {
//移除灌区多边形
state.irrigationEntities.forEach(id => {
viewer.entities.removeById(id);
});
state.irrigationEntities = [];
state.irrigationAreaData.forEach(area => {
drawPolygon(area, true, state.irrigationEntities);
});
} else {
//移除灌区多边形
state.irrigationEntities.forEach(id => {
viewer.entities.removeById(id);
});
state.irrigationEntities = [];
}
},
);
3、设置地形关闭,防止漂浮
- 启用地形:适用于需要展示真实地形的应用场景(如山脉、峡谷等)。
- 关闭地形:适用于需要简化渲染、提升性能或避免地形干扰的场景。
// 设置地形,关闭
viewer.terrainProvider = new Cesium.EllipsoidTerrainProvider();
注:不关闭地形的话,鼠标拖拽地图移动时,实体会出现类似漂浮的效果(鼠标拖拽一下,实体移动出去更远)
4、鹰眼
// 创建鹰眼地图的Viewer
const overviewViewer = new Cesium.Viewer(overviewContainer.value, {
animation: false, // 禁用动画控件
geocoder: false, // 开启地理编码控件
homeButton: false, // 禁用主视图控件
sceneModePicker: false, // 禁用场景模式切换控件
// baseLayerPicker: false, // 禁用底图切换控件
navigationHelpButton: false, // 禁用导航帮助按钮
timeline: false, // 禁用时间轴控件
});
// 隐藏底部版权信息
overviewViewer._cesiumWidget._creditContainer.style.display = 'none';
// 添加高德地图路网
overviewViewer.imageryLayers.addImageryProvider(gaodeLayer);
// 同步两个地图的视角
function syncView(longitude, latitude, height) {
// 确保参数是数值类型
longitude = parseFloat(longitude);
latitude = parseFloat(latitude);
height = parseFloat(height);
overviewViewer.camera.flyTo({
destination: Cesium.Cartesian3.fromDegrees(longitude, latitude, height),
orientation: {
heading: Cesium.Math.toRadians(0), // 方向角度,单位为弧度
pitch: Cesium.Math.toRadians(-90), // 俯仰角度,单位为弧度
roll: 0, // 翻滚角度,单位为弧度
},
duration: 1, // 动画持续时间,单位为秒
});
}
// 设置中心点同样的经纬度
syncView(state.longitude, state.latitude, state.height * 5);
5、添加高德地图路网
显示道路和中文的区域名字:
const gaodeLayer = new Cesium.UrlTemplateImageryProvider({
url: 'http://webst02.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=1&scale=1&style=8',
maximumLevel: 18,
});
viewer.imageryLayers.addImageryProvider(gaodeLayer);
6、让用户画圆
//开始画圆
const startDrawingCircle = () => {
//监听鼠标,后一次点击的位置与前一次点击的位置之间的直线为圆的直径。
let handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
let positions = [];
handler.setInputAction(movement => {
//获取鼠标点击的位置的笛卡尔坐标
let cartesian = viewer.scene.pickPosition(movement.position);
//如果cartesian存在且与positions数组中的第一个元素不相等,则将其添加到positions数组中
if (cartesian && (!positions.length || !Cesium.Cartesian3.equals(cartesian, positions[0]))) {
positions.push(cartesian);
if (positions.length === 2) {
let center = Cesium.Cartesian3.midpoint(positions[0], positions[1], new Cesium.Cartesian3());
let radius = Cesium.Cartesian3.distance(center, positions[0]);
var circle = viewer.entities.add({
position: center,
ellipse: {
semiMinorAxis: radius,
semiMajorAxis: radius,
material: Cesium.Color.RED.withAlpha(0.5),
outline: true,
outlineColor: Cesium.Color.BLACK,
},
});
positions = [];
state.circleEntities.push(circle.id);
}
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK); //监听state.drawingCircle,当其值为false时,移除handler
watch(
() => state.drawingCircle,
value => {
if (value) {
startDrawingCircle();
} else {
handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
}
},
);
};
7、让用户画多边形
//开始画多边形
const startDrawingPolygon = () => {
let handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
let positions = [];
let polygon = null;
handler.setInputAction(movement => {
let cartesian = viewer.scene.pickPosition(movement.position);
if (cartesian) {
positions.push(cartesian);
if (positions.length === 1) {
polygon = viewer.entities.add({
polygon: {
hierarchy: new Cesium.CallbackProperty(() => {
return new Cesium.PolygonHierarchy(positions);
}, false),
material: Cesium.Color.RED.withAlpha(0.5),
outline: true,
outlineColor: Cesium.Color.BLACK,
},
});
state.polygonEntities.push(polygon.id);
} else {
polygon.polygon.hierarchy = new Cesium.CallbackProperty(() => {
return new Cesium.PolygonHierarchy(positions);
}, false);
}
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
watch(
() => state.drawingPolygon,
value => {
if (value) {
startDrawingPolygon();
} else {
handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
}
},
);
};
8、隐藏底部版权信息
viewer._cesiumWidget._creditContainer.style.display = 'none';
注:创建Cesium Viewer要在onMounted钩子函数内
9、地图深度检测
确保 3D 场景中物体的遮挡关系正确,避免出现物体穿插或遮挡错误的问题。它是实现真实感渲染的关键技术之一,在地形、建筑、飞行器等场景中尤为重要。
viewer.scene.globe.depthTestAgainstTerrain = true;
10、地图颜色
官方本来提供了多种主题,但是仍然想自定义颜色可如下设置:
viewer.scene.globe.baseColor = Cesium.Color.fromCssColorString('#00115F');
let baseLayer = viewer.imageryLayers.get(0);
baseLayer.show = false;
11、禁用双击事件
双击地图上的某个位置,通常会放大视图并聚焦到该点。
viewer.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
12、添加动画效果,飞向指定位置
// 添加动画效果,飞向指定位置,写成函数,方便调用
function flyToLocation(longitude, latitude, height) {
viewer.camera.flyTo({
destination: Cesium.Cartesian3.fromDegrees(longitude, latitude, height),
orientation: {
heading: Cesium.Math.toRadians(0), // 方向角度,单位为弧度
pitch: Cesium.Math.toRadians(-90), // 俯仰角度,单位为弧度
roll: 0, // 翻滚角度,单位为弧度
},
duration: 1, // 动画持续时间,单位为秒
});
}
flyToLocation(104.69, 30.2183873102, 5000);
三、学习资料参考(感谢大佬分享):
1、cesium中文网
Animation - Cesium Documentation
2、cesium编程入门 | cesium中文网
3、3.Cesium中实体Entity创建(超详细)_new cesium.entity-CSDN博客