展示效果,我们期待图标点是根据模型,在模型的上方展示
实现思路:
1.在二维地图和三维地图的加载的高度计算不同,需要判断
2.创建一个BillboardCollection,用来存放图标
3.在三维地图中调用getPointPostion方法,来计算图标的高度
addBillboardsPrimitivesPlush(list, dataType) {
let keyIs2D = "2D";
if (this.curKey == "2D" || (this.curKey.key && this.curKey.key == "2D")) {
keyIs2D = "2D";
} else {
keyIs2D = "3D";
}
// item = JSON.parse(JSON.stringify(item)); // 数据隔离
if (list.length === 0) {
return;
}
billboards[dataType] = null;
if (billboards[dataType] == null) {
billboards[dataType] = this.cesium_viewer.scene.primitives.add(
new Cesium.BillboardCollection(),
10
);
}
list.forEach((item) => {
// item.attrs.moid = item.moid;
if (item.geometry && item.geometry.coordinates) {
billboards[dataType].add({
id: { baseInfo: item },
position:
keyIs2D == "2D"
? Cesium.Cartesian3.fromDegrees(
Number(item.geometry.coordinates[0]),
Number(item.geometry.coordinates[1]),
1
)
: this.getPointPostion(
Number(item.geometry.coordinates[0]),
Number(item.geometry.coordinates[1])
),
image: item.imgSrc || this.getIcon(item),
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
scale: 1,
distanceDisplayCondition: new Cesium.DistanceDisplayCondition(
0.0,
1000000
),
});
} else {
// console.log("数据错误", item)
}
});
this.cesium_viewer.scene.primitives.raiseToTop(billboards[dataType]);
},
getPointPostion方法
主要就是调用sence中的**sampleHeight
**方法
sampleHeight
(position
, objectsToExclude
, width
)
返回给定制图位置的场景几何体的高度,如果没有场景几何体可从中采样高度,则返回 undefined 的高度。输入位置的高度被忽略。可用于将对象夹在地球、3D 瓷砖或场景中的图元上。
此函数仅从当前视图中渲染的地球图块和 3D 图块中采样高度。对所有其他基元的高度进行采样,无论其可见性如何。
getPointPostion(longitude, latitude) {
// 将经纬度坐标转为弧度坐标
const cart = Cesium.Cartographic.fromDegrees(longitude, latitude);
// 根据弧度坐标获取该弧度坐标在三维模型表面的高度值
const height = this.cesium_viewer.scene.sampleHeight(cart);
// console.log("heightheightheight", height);
// 返回该经纬度带有高度的坐标值,跟根据计算出来的高度,再自定义加减高度值
let heighttVal = height ? height + 0.5 : 2;
return Cesium.Cartesian3.fromDegrees(longitude, latitude, heighttVal);
},
针对于大量数据,就进行异步优化记载
runTask
方法是一个包装函数,它将一个普通的回调函数 task 转换为一个返回 Promise 的函数。这允许您以异步的方式执行任务,并能够在任务完成后使用 .then() 方法处理结果或进一步链接 Promise
// 优化地图加载,异步执行耗时任务
runTask(task) {
return new Promise((resolve) => {
this._runTask(task, resolve);
});
},
_runTask(task, callback) {
let start = Date.now();
// 防止阻塞主线程
requestAnimationFrame(() => {
// 兼容saferi,改为手动计算
if (Date.now() - start < 16.6) {
task();
callback();
} else {
this._runTask(task, callback);
}
});
},
改造代码:
addBillboardsPrimitivesPlush(list, dataType) {
if (list.length === 0) return;
const keyIs2D =
this.curKey == "2D" || (this.curKey.key && this.curKey.key == "2D");
const sign = Symbol(dataType);
billboardsAdding[dataType] = sign;
billboards[dataType] = null;
if (billboards[dataType] == null) {
billboards[dataType] = this.cesium_viewer.scene.primitives.add(
new Cesium.BillboardCollection(),
10
);
}
const distanceDisplayCondition = new Cesium.DistanceDisplayCondition(
0.0,
1000000
);
const verticalOrigin = Cesium.VerticalOrigin.BOTTOM;
const disableDepthTestDistance = Number.POSITIVE_INFINITY;
const listLength = list.length;
for (let index = 0; index < listLength; index++) {
const item = list[index];
if (item.geometry && item.geometry.coordinates) {
this.runTask(() => {
const [lng, lat] = item.geometry.coordinates;
if (billboardsAdding[dataType] !== sign) return;
billboards[dataType].add({
id: { baseInfo: item },
position: keyIs2D
? Cesium.Cartesian3.fromDegrees(lng, lat, 1)
: this.getPointPostion(lng, lat),
image: item.imgSrc || this.getIcon(item),
scale: 1,
verticalOrigin,
disableDepthTestDistance,
distanceDisplayCondition,
});
});
} else {
}
}
this.cesium_viewer.scene.primitives.raiseToTop(billboards[dataType]);
},