Cesium 展示——新增需求和分析
文章目录
- 二三维视图的打点飞线,二三维实现联动
- 需求
- 分析
- 模型点击事件
- 需求
- 分析
- 二三维标绘图标,依比例和不依比例缩放
- 需求
- 分析
- 二维标绘图标
- 依比例缩放
- 不依比例缩放
- 三维标绘图标
- 依比例缩放
- 不依比例缩放
- 经纬度和地名互查
- 需求
- 分析
- 经纬度转地名
- 地名转经纬度
- 提供一部分三维模型示例,加载在图片
- 需求
- 分析
- 鹰眼联动,内容同步
- 需求
- 分析
二三维视图的打点飞线,二三维实现联动
需求
二三维视图的打点飞线,二三维实现联动
分析
该需求需要实现打点飞线,即实现对点线的制作,实现打点飞线
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Cesium Example</title>
<script src="https://cesium.com/downloads/cesiumjs/releases/1.83/Build/Cesium/Cesium.js"></script>
<style>
@import url("https://cesium.com/downloads/cesiumjs/releases/1.83/Build/Cesium/Widgets/widgets.css");
html,
body,
#cesiumContainer {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
overflow: hidden;
}
</style>
</head>
<body>
<div id="cesiumContainer"></div>
<script>
// 初始化 Cesium 场景
const viewer = new Cesium.Viewer("cesiumContainer");
// 创建飞线路径
const positions = [
Cesium.Cartesian3.fromDegrees(-75, 35, 250000),
Cesium.Cartesian3.fromDegrees(-125, 35, 250000),
Cesium.Cartesian3.fromDegrees(-125, 45, 250000),
];
const redLine = viewer.entities.add({
polyline: {
positions: positions,
width: 5,
material: Cesium.Color.RED,
},
});
// 创建点
for (let i = 0; i < positions.length; i++) {
viewer.entities.add({
position: positions[i],
point: {
pixelSize: 10,
color: Cesium.Color.YELLOW,
},
});
}
// 设置相机视角
viewer.camera.flyTo({
destination: Cesium.Cartesian3.fromDegrees(-100, 40, 5000000),
});
</script>
</body>
</html>
模型点击事件
需求
实现对模型的点击事件
分析
当在 Cesium 场景中加载了一个或多个模型时,可以通过添加点击事件来捕获用户点击模型的操作。以下是一个示例,演示如何为 Cesium 模型添加点击事件:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Cesium Example</title>
<script src="https://cesium.com/downloads/cesiumjs/releases/1.83/Build/Cesium/Cesium.js"></script>
<style>
@import url("https://cesium.com/downloads/cesiumjs/releases/1.83/Build/Cesium/Widgets/widgets.css");
html,
body,
#cesiumContainer {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
overflow: hidden;
}
</style>
</head>
<body>
<div id="cesiumContainer"></div>
<script>
// 初始化 Cesium 场景
const viewer = new Cesium.Viewer("cesiumContainer");
// 加载模型
const modelEntity = viewer.entities.add({
name: "model",
position: Cesium.Cartesian3.fromDegrees(-75, 40),
model: {
uri: "path/to/your/model.gltf",
},
});
// 添加点击事件
viewer.screenSpaceEventHandler.setInputAction(function onLeftClick(
movement
) {
const pickedObject = viewer.scene.pick(movement.position);
if (
Cesium.defined(pickedObject) &&
pickedObject.id === modelEntity
) {
console.log("模型被点击了!");
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
</script>
</body>
</html>
-
在这个示例中,我们首先初始化了 Cesium 场景,并加载了一个模型。然后,我们为场景的左击事件添加了一个处理函数。在处理函数中,通过使用 viewer.scene.pick() 方法来获取用户点击的对象。如果被点击的对象的 ID 与模型实体的 ID 匹配,就会在控制台输出一条消息。
-
请注意,path/to/your/model.gltf 部分应该替换为你自己模型文件的路径。此外,还可以根据需要修改模型的位置、添加更多的模型,以及在点击事件处理函数中执行其他操作。
-
这个示例演示了如何在 Cesium 中为模型添加点击事件,并在用户点击模型时触发相应的操作
二三维标绘图标,依比例和不依比例缩放
需求
二三维标绘图标,依比例和不依比例缩放
分析
在Cesium中,实现依比例和不依比例缩放的方法略有不同。下面我将分别介绍在Cesium中如何实现依比例和不依比例缩放。
二维标绘图标
依比例缩放
在Cesium中,二维标绘通常使用Billboard来表示图标。要实现依比例缩放,可以设置Billboard的scale属性来指定缩放比例。
var viewer = new Cesium.Viewer('cesiumContainer');
var billboard = viewer.entities.add({
position: Cesium.Cartesian3.fromDegrees(longitude, latitude),
billboard: {
image: 'path/to/image.png',
scale: 1.0, // 初始缩放比例
// 其他属性...
}
});
viewer.zoomTo(viewer.entities);
上面的代码创建了一个位于指定经纬度位置的Billboard,并设置了初始的缩放比例为1.0。当调整地图的缩放级别时,Billboard会自动按照相应比例进行缩放,从而保持图标的原始比例。
不依比例缩放
如果想实现不依比例缩放,可以直接改变Billboard的width和height属性,而不是使用scale属性。
var viewer = new Cesium.Viewer('cesiumContainer');
var billboard = viewer.entities.add({
position: Cesium.Cartesian3.fromDegrees(longitude, latitude),
billboard: {
image: 'path/to/image.png',
width: 32, // 初始宽度
height: 16, // 初始高度
// 其他属性...
}
});
viewer.zoomTo(viewer.entities);
上述代码中,width和height分别设置了初始的宽度和高度。在地图缩放时,Billboard的宽度和高度将以不同的比例进行调整,从而导致图标的形状发生变化。
三维标绘图标
依比例缩放
在Cesium中,三维标绘通常使用Model来加载和显示模型。要实现依比例缩放,可以设置Model的scale属性来指定缩放比例。
var viewer = new Cesium.Viewer('cesiumContainer');
var modelEntity = viewer.entities.add({
position: Cesium.Cartesian3.fromDegrees(longitude, latitude, height),
model: {
uri: 'path/to/model.gltf',
scale: 1.0, // 初始缩放比例
// 其他属性...
}
});
viewer.zoomTo(viewer.entities);
上面的代码加载了一个指定位置的模型,并设置了初始的缩放比例为1.0。当调整地图的缩放级别时,模型会按照相应比例进行缩放,保持原始比例。
不依比例缩放
如果想实现不依比例缩放,可以直接改变Model的scale属性中的各个轴的缩放比例。
var viewer = new Cesium.Viewer('cesiumContainer');
var modelEntity = viewer.entities.add({
position: Cesium.Cartesian3.fromDegrees(longitude, latitude, height),
model: {
uri: 'path/to/model.gltf',
scale: new Cesium.Cartesian3(2, 1, 0.5), // 初始缩放比例
// 其他属性...
}
});
viewer.zoomTo(viewer.entities);
上述代码中,scale属性使用了一个Cartesian3对象来设置初始的缩放比例。可以根据需要调整各个轴的缩放比例,从而实现不依比例缩放效果。
综上所述,在Cesium中实现依比例和不依比例缩放主要通过设置Billboard和Model的scale属性来实现。
经纬度和地名互查
需求
经纬度和地名互查
分析
- 要在Cesium中实现经纬度和地名的互查,可以使用Cesium的Geocoder组件来实现。
经纬度转地名
- 要将经纬度转换为地名,可以使用Geocoder的geocode方法。该方法接受一个Cartographic对象作为参数,其中包含了经度和纬度信息。下面是一个示例代码:
var viewer = new Cesium.Viewer('cesiumContainer');
var geocoder = new Cesium.Geocoder({
container: 'geocoderContainer'
});
viewer.extend(Cesium.viewerCesiumInspectorMixin); // 添加Inspector插件
viewer.extend(Cesium.viewerCesium3DTilesInspectorMixin); // 添加3DTiles Inspector插件
geocoder.viewModel.searchText = "40.7128, -74.0060"; // 设置经纬度
viewer.geocoder.viewModel.search(); // 调用search方法进行查询
-
上述代码中,我们创建了一个Geocoder实例,并将其绑定到指定的HTML容器中(这里使用了id为geocoderContainer的容器)。然后,通过设置searchText属性,我们传入了一个经纬度坐标"40.7128, -74.0060"。最后,调用search方法进行查询。
-
当查询成功后,可以通过监听geocodeComplete事件,获取查询结果并获取地名信息。示例如下:
geocoder.viewModel.geocodeComplete.addEventListener(function(geocodeResult) {
var result = geocodeResult.results[0];
if (result) {
var displayName = result.displayName;
console.log(displayName); // 输出地名信息
}
});
- 上述代码中,监听了geocodeComplete事件,并通过geocodeResult.results[0]获取到查询结果的第一个地名信息。然后,可以使用displayName属性来获取地名信息,并进行后续操作。
地名转经纬度
- 要将地名转换为经纬度,同样可以使用Geocoder的geocode方法,但这次传入的参数是地名字符串。以下是示例代码:
var viewer = new Cesium.Viewer('cesiumContainer');
var geocoder = new Cesium.Geocoder({
container: 'geocoderContainer'
});
viewer.extend(Cesium.viewerCesiumInspectorMixin); // 添加Inspector插件
viewer.extend(Cesium.viewerCesium3DTilesInspectorMixin); // 添加3DTiles Inspector插件
geocoder.viewModel.searchText = "New York City"; // 设置地名
viewer.geocoder.viewModel.search(); // 调用search方法进行查询
-
上述代码中,我们设置了searchText属性为"New York City",即要查询的地名。然后,调用search方法进行查询。
-
同样,可以在geocodeComplete事件中获取查询结果并获取经纬度信息。示例如下:
geocoder.viewModel.geocodeComplete.addEventListener(function(geocodeResult) {
var result = geocodeResult.results[0];
if (result) {
var position = result.position;
console.log(position); // 输出经纬度信息
}
});
-
上述代码中,我们通过geocodeResult.results[0]获取到查询结果的第一个地名信息,然后使用position属性获取经纬度信息,并进行后续操作。
-
综上所述,在Cesium中实现经纬度和地名的互查可以通过使用Geocoder组件的geocode方法实现。可以根据需要传入经纬度或地名字符串作为参数,并监听geocodeComplete事件获取查询结果。
提供一部分三维模型示例,加载在图片
需求
提供一部分三维模型示例,加载在图片
分析
- 在Cesium中,可以通过Cesium.Model来加载三维模型,并通过Cesium.Billboard来加载图片。下面是一个简单的示例代码,演示了如何在Cesium中实现加载三维模型并将其与图片一起展示:
// 初始化Cesium Viewer
var viewer = new Cesium.Viewer('cesiumContainer');
// 加载三维模型
var modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(
Cesium.Cartesian3.fromDegrees(-75.62898254394531, 40.02804946899414, 0.0)
);
var model = viewer.scene.primitives.add(Cesium.Model.fromGltf({
url : 'path_to_your_3d_model.gltf',
modelMatrix : modelMatrix,
scale : 200.0
}));
// 加载图片
var imageUrl = 'path_to_your_image.jpg';
var billboard = viewer.entities.add({
position: Cesium.Cartesian3.fromDegrees(-75.62898254394531, 40.02804946899414, 0.0),
billboard: {
image: imageUrl,
scale: 1.0
}
});
-
在上述代码中,我们首先初始化了Cesium Viewer,并加载了一个三维模型和一张图片。对于三维模型,我们使用Cesium.Model.fromGltf方法加载了一个GLTF格式的模型,并通过modelMatrix设置了其位置、旋转和缩放。对于图片,我们创建了一个Cesium.Billboard实体,并通过image属性设置了图片的URL,然后将该实体添加到了Viewer中。
-
通过上述示例代码,可以在Cesium中实现加载三维模型并将其与图片一起展示。
鹰眼联动,内容同步
需求
鹰眼联动,内容同步
分析
在Cesium中实现鹰眼联动可以通过两个视图之间的相机位置和操控进行同步。下面是一个示例代码,演示了如何在Cesium中实现鹰眼联动:
// 初始化主视图
var mainViewer = new Cesium.Viewer('mainContainer');
// 初始化鹰眼视图
var overviewViewer = new Cesium.Viewer('overviewContainer', {
animation: false,
baseLayerPicker: false,
fullscreenButton: false,
geocoder: false,
homeButton: false,
infoBox: false,
sceneModePicker: false,
selectionIndicator: false,
timeline: false,
navigationHelpButton: false,
navigationInstructionsInitiallyVisible: false,
shouldAnimate: false
});
// 主视图相机变化时更新鹰眼视图
mainViewer.camera.changed.addEventListener(function() {
updateOverviewView();
});
// 鹰眼视图点击时更新主视图
overviewViewer.canvas.addEventListener('click', function(event) {
var clickedPosition = overviewViewer.scene.pickPosition(event.position);
if (Cesium.defined(clickedPosition)) {
mainViewer.camera.flyTo({
destination : clickedPosition
});
}
});
// 更新鹰眼视图
function updateOverviewView() {
var mainCamera = mainViewer.camera;
var overviewCamera = overviewViewer.camera;
// 更新鹰眼视图相机位置和方向
overviewCamera.setView({
destination: mainCamera.position,
orientation: {
heading: mainCamera.heading,
pitch: Cesium.Math.toRadians(-90),
roll: 0.0
}
});
// 更新鹰眼视图操控器
var scene = overviewViewer.scene;
scene.screenSpaceCameraController.minimumZoomDistance = mainCamera.minimumZoomDistance;
scene.screenSpaceCameraController.maximumZoomDistance = mainCamera.maximumZoomDistance;
scene.screenSpaceCameraController.enableRotate = mainCamera.enableRotate;
scene.screenSpaceCameraController.enableTranslate = mainCamera.enableTranslate;
scene.screenSpaceCameraController.enableZoom = mainCamera.enableZoom;
scene.screenSpaceCameraController.enableTilt = mainCamera.enableTilt;
}
// 加载示例模型,仅为演示效果
mainViewer.entities.add({
position: Cesium.Cartesian3.fromDegrees(-75.62898254394531, 40.02804946899414, 0.0),
model: {
uri: 'path_to_your_3d_model.gltf'
}
});
-
在上述代码中,我们初始化了主视图和鹰眼视图。主视图和鹰眼视图分别对应两个不同的
<div>容器
(分别是mainContainer和overviewContainer)。然后,我们通过监听主视图相机的changed事件,实现主视图相机变化时更新鹰眼视图。 -
在更新鹰眼视图的函数updateOverviewView中,我们首先获取主视图相机的位置和方向,然后将其设置到鹰眼视图的相机中。接着,我们更新鹰眼视图的操控器,使其与主视图保持一致。
-
最后,我们通过给鹰眼视图的canvas添加点击事件监听器,实现在鹰眼视图中点击某个位置时更新主视图相机。
-
请注意,在示例代码中我们加载了一个示例模型,仅用于演示效果。你需要将路径’path_to_your_3d_model.gltf’替换为你实际使用的模型路径。
-
通过以上示例代码,可以在Cesium中实现鹰眼联动,实现两个视图之间的相机位置和操控的同步。