一、基本方式:
图标使用.png比.svg性能要好
<template>
<div id="cesiumContainer"></div>
<div class="toolbar">
<button id="resetButton">重新生成点</button>
<span id="countDisplay">当前车辆数量: 1500</span>
</div>
</template>
<script setup>
Cesium.Ion.defaultAccessToken = '你的defaultAccessToken';
import { onMounted } from "vue";
import * as Cesium from "cesium";
import "./Widgets/widgets.css";
window.CESIUM_BASE_URL = "/"; // 设置Cesium静态资源路径(public目录)
onMounted(() => {
// 中国边界经纬度范围
const chinaBounds = {
west: 73.66,
south: 18.10,
east: 135.08,
north: 53.52
};
// 中国主要省份排除区域(简化版)
const exclusionAreas = [
// 示例:排除南海区域
{ west: 105, south: 0, east: 125, north: 22 }
];
// 检查坐标是否在中国境内且不在排除区域内
function isInChina(lng, lat) {
// 检查是否在中国边界内
if (lng < chinaBounds.west || lng > chinaBounds.east ||
lat < chinaBounds.south || lat > chinaBounds.north) {
return false;
}
// 检查是否在排除区域内
for (const area of exclusionAreas) {
if (lng >= area.west && lng <= area.east &&
lat >= area.south && lat <= area.north) {
return false;
}
}
return true;
}
// 生成随机经纬度(在中国范围内)
function generateRandomCoordinatesInChina() {
let lng, lat;
do {
lng = chinaBounds.west + Math.random() * (chinaBounds.east - chinaBounds.west);
lat = chinaBounds.south + Math.random() * (chinaBounds.north - chinaBounds.south);
} while (!isInChina(lng, lat));
return { lng, lat };
}
// 初始化Cesium
const viewer = new Cesium.Viewer('cesiumContainer', {
terrainProvider: Cesium.createWorldTerrain(),
baseLayerPicker: false, // 禁用底图选择器
geocoder: false, // 禁用地理编码器
homeButton: false, // 禁用主页按钮
infoBox: false, // 禁用信息框
sceneModePicker: false, // 禁用场景模式选择器
selectionIndicator: false, // 禁用选择指示器
navigationHelpButton: false, // 禁用导航帮助按钮
animation: false, // 禁用动画控件
timeline: false, // 禁用时间轴
fullscreenButton: false // 禁用全屏按钮
});
// 调整视角到中国
viewer.camera.setView({
destination: Cesium.Rectangle.fromDegrees(
chinaBounds.west,
chinaBounds.south,
chinaBounds.east,
chinaBounds.north
),
orientation: {
heading: Cesium.Math.toRadians(0.0),
pitch: Cesium.Math.toRadians(-15.0)
}
});
// 创建车辆图像Primitive
let vehiclePrimitives;
const vehicleCount = 1500;
// 加载车辆SVG图像
const carSvgUrl = '/Assets/nav.svg';
function createVehiclePrimitives() {
// 清除现有primitives
if (vehiclePrimitives) {
viewer.scene.primitives.remove(vehiclePrimitives);
}
// 创建新的primitives集合
vehiclePrimitives = new Cesium.PrimitiveCollection();
// 创建1500个车辆图标
for (let i = 0; i < vehicleCount; i++) {
const position = generateRandomCoordinatesInChina();
// 创建车辆billboard
const billboardCollection = new Cesium.BillboardCollection();
const billboard = billboardCollection.add({
position: Cesium.Cartesian3.fromDegrees(position.lng, position.lat, 10),
image: carSvgUrl,
width: 24,
height: 24,
scale: 1.0,
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
color: Cesium.Color.WHITE,
rotation: Math.random() * Math.PI * 2, // 随机朝向
disableDepthTestDistance: Number.POSITIVE_INFINITY
});
vehiclePrimitives.add(billboardCollection);
}
// 添加到场景
viewer.scene.primitives.add(vehiclePrimitives);
}
// 初始化创建车辆
createVehiclePrimitives();
// 重置按钮事件
document.getElementById('resetButton').addEventListener('click', function () {
createVehiclePrimitives();
document.getElementById('countDisplay').textContent = `当前车辆数量: ${vehicleCount}`;
});
})
</script>
<style scoped>
* {
margin: 0;
padding: 0;
}
#cesiumContainer {
width: 100wh;
height: 100vh;
}
.toolbar {
position: absolute;
top: 10px;
left: 50%;
transform: translateX(-50%);
background-color: rgba(42, 42, 42, 0.8);
color: white;
padding: 8px 15px;
border-radius: 5px;
display: flex;
gap: 15px;
align-items: center;
z-index: 100;
}
.toolbar button {
background-color: #4CAF50;
border: none;
color: white;
padding: 6px 12px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 14px;
border-radius: 4px;
cursor: pointer;
transition: background-color 0.3s;
}
.toolbar button:hover {
background-color: #45a049;
}
.toolbar span {
font-size: 14px;
}
</style>
二、加载图片性能更好的方式:
<template>
<div id="cesiumContainer"></div>
</template>
<script setup>
Cesium.Ion.defaultAccessToken = '你的defaultAccessToken';
import { onMounted } from "vue";
import * as Cesium from "cesium";
import "./Widgets/widgets.css";
window.CESIUM_BASE_URL = "/"; // 设置Cesium静态资源路径(public目录)
onMounted(() => {
// ===== 初始化Viewer =====
const viewer = new Cesium.Viewer('cesiumContainer', {
sceneMode: Cesium.SceneMode.SCENE2D, // 初始二维模式
terrainProvider: Cesium.createWorldTerrain(),
baseLayerPicker: false
});
// ===== 生成1500个中国坐标 =====
const positions = [];
for (let i = 0; i < 1500; i++) {
const lon = Math.random() * 62 + 73; // 东经73°-135°
const lat = Math.random() * 35 + 18; // 北纬18°-53°
positions.push(Cesium.Cartesian3.fromDegrees(lon, lat, 0));
}
// ===== 二维模式:使用BillboardCollection加载PNG图标 =====
const billboards = new Cesium.BillboardCollection();
viewer.scene.primitives.add(billboards);
positions.forEach(pos => {
billboards.add({
position: pos,
image: '/Assets/nav.svg',
width: 32,
height: 32,
scaleByDistance: new Cesium.NearFarScalar(1e3, 1.0, 2e6, 0.2) // 视距缩放优化[3](@ref)
});
});
// ===== 性能监控(可选) =====
viewer.scene.debugShowFramesPerSecond = true;
})
</script>
<style scoped>
* {
margin: 0;
padding: 0;
}
#cesiumContainer {
width: 100wh;
height: 100vh;
}
.toolbar {
position: absolute;
top: 10px;
left: 50%;
transform: translateX(-50%);
background-color: rgba(42, 42, 42, 0.8);
color: white;
padding: 8px 15px;
border-radius: 5px;
display: flex;
gap: 15px;
align-items: center;
z-index: 100;
}
.toolbar button {
background-color: #4CAF50;
border: none;
color: white;
padding: 6px 12px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 14px;
border-radius: 4px;
cursor: pointer;
transition: background-color 0.3s;
}
.toolbar button:hover {
background-color: #45a049;
}
.toolbar span {
font-size: 14px;
}
</style>
刷新数据
<template>
<div id="cesiumContainer"></div>
<div class="toolbar">
<button id="resetButton">重新生成点</button>
<span id="countDisplay">当前车辆数量: 1500</span>
</div>
</template>
<script setup>
Cesium.Ion.defaultAccessToken = '你的defaultAccessToken';
import { onMounted } from "vue";
import * as Cesium from "cesium";
import "./Widgets/widgets.css";
window.CESIUM_BASE_URL = "/"; // 设置Cesium静态资源路径(public目录)
onMounted(() => {
// ===== 初始化Viewer =====
const viewer = new Cesium.Viewer('cesiumContainer', {
sceneMode: Cesium.SceneMode.SCENE2D, // 初始二维模式
terrainProvider: Cesium.createWorldTerrain(),
baseLayerPicker: false
});
// ===== 生成1500个中国坐标 =====
const positions = [];
for (let i = 0; i < 1500; i++) {
const lon = Math.random() * 62 + 73; // 东经73°-135°
const lat = Math.random() * 35 + 18; // 北纬18°-53°
positions.push(Cesium.Cartesian3.fromDegrees(lon, lat, 0));
}
// 创建车辆图像Primitive
let billboards;
function createVehiclePrimitives() {
// 清除现有primitives
if (billboards) {
viewer.scene.primitives.remove(billboards);
}
// 创建新的primitives集合
billboards = new Cesium.BillboardCollection();
positions.forEach(pos => {
billboards.add({
position: pos,
image: '/Assets/nav.svg',
width: 32,
height: 32,
scaleByDistance: new Cesium.NearFarScalar(1e3, 1.0, 2e6, 0.2) // 视距缩放优化[3](@ref)
});
});
// 添加到场景
viewer.scene.primitives.add(billboards);
}
// 初始化创建车辆
createVehiclePrimitives();
// 重置按钮事件
document.getElementById('resetButton').addEventListener('click', function () {
createVehiclePrimitives();
document.getElementById('countDisplay').textContent = `当前车辆数量: 1500`;
});
// ===== 性能监控(可选) =====
viewer.scene.debugShowFramesPerSecond = true;
})
</script>
<style scoped>
* {
margin: 0;
padding: 0;
}
#cesiumContainer {
width: 100wh;
height: 100vh;
}
.toolbar {
position: absolute;
top: 10px;
left: 50%;
transform: translateX(-50%);
background-color: rgba(42, 42, 42, 0.8);
color: white;
padding: 8px 15px;
border-radius: 5px;
display: flex;
gap: 15px;
align-items: center;
z-index: 100;
}
.toolbar button {
background-color: #4CAF50;
border: none;
color: white;
padding: 6px 12px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 14px;
border-radius: 4px;
cursor: pointer;
transition: background-color 0.3s;
}
.toolbar button:hover {
background-color: #45a049;
}
.toolbar span {
font-size: 14px;
}
</style>