问题
需要给Cesium地形加上icon图标,使用billboard加上图标后,对于倾斜摄影的模型会出现穿模的效果,导致图标不能看见。
解决
关键代码
const cartesians1 = Cesium.Cartesian3.fromDegrees(longitude, latitude);
let result = viewer.scene.clampToHeightMostDetailed([cartesians1]);
console.log(result[0])// result[0]得到的就是其经纬度加高
完整代码
<!DOCTYPE html>
<!--Created By OSGBLab(http://www.osgblab.com)-->
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport"
content="width=device-width, initial-scale = 1, maximum-scale = 1, minimum-scale = 1, user-scalable = no">
<title>OSGBLab Cesium Data Viewer</title>
<script src="./Cesium/Cesium.js"></script>
<style>
@import url(./Cesium/Widgets/widgets.css);
html,
body,
#OSGBLab_Container {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
overflow: hidden;
}
</style>
</head>
<body>
<div id="OSGBLab_Container"></div>
</body>
<script>
window.startup = async function (Cesium) {
function IsMobile() {
var ios = /AppleWebKit/.test(navigator.userAgent) && /Mobile\/\w+/.test(navigator.userAgent);
var mobile = ios || /Android|webOS|BlackBerry|Opera Mini|Opera Mobi|IEMobile/i.test(navigator.userAgent);
return mobile;
}
Cesium.Ion.defaultAccessToken = 申请的token;
var terrain = Cesium.createDefaultTerrainProviderViewModels();
var viewer = new Cesium.Viewer('OSGBLab_Container', {
animation: false,
vrButton: true,
timeline: false,
sceneModePicker: false,
scene3DOnly: true,
infoBox: true,
terrainProviderViewModels: terrain,
selectedTerrainProviderViewModel: terrain[1],
});
viewer.scene.globe.depthTestAgainstTerrain = true;
var boundingSphere = new Cesium.BoundingSphere(Cesium.Cartesian3.fromDegrees(119.7241462, 31.20813151, 109.2607593), 7943.766259);
viewer.homeButton.viewModel.command.beforeExecute.addEventListener(function (cmd) {
viewer.camera.flyToBoundingSphere(boundingSphere);
cmd.cancel = true;
});
viewer.camera.flyToBoundingSphere(boundingSphere, { duration: 0 });
// 加载倾斜摄影地形
var tiles = viewer.scene.primitives.add(new Cesium.Cesium3DTileset({
url: '../Data/tileset.json',
maximumScreenSpaceError: 16,
maximumNumberOfLoadedTiles: IsMobile() ? 32 : 1024
}));
// 点击事件处理
viewer.screenSpaceEventHandler.setInputAction(function (movement) {
var pickedObject = viewer.scene.pick(movement.position);
if (
Cesium.defined(pickedObject) &&
Cesium.defined(pickedObject.id) &&
Cesium.defined(pickedObject.id.customProperty)
) {
var customProperty = pickedObject.id.customProperty;
// .id = pickedObject.id;
// 在这里处理自定义属性值
window.parent.postMessage({ initation: false, data: JSON.stringify(customProperty) }, "*");
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
// 添加二维返的点位数据
async function addPoint(obj) {
const promises = [];
for (const [key, value] of Object.entries(obj)) {
if (value.data.length > 0 && value.show) {
value.data.forEach((item, index) => {
const longitude = Number(item.longitude || item.lng);
const latitude = Number(item.latitude || item.lat);
const cartesians1 = Cesium.Cartesian3.fromDegrees(longitude, latitude);
promises.push(
viewer.scene.clampToHeightMostDetailed([cartesians1])
.then(clampedCartesians => {
viewer.entities.add({
position: clampedCartesians[0],
billboard: {
image: item[value.condition] ? value.icon2 : value.icon,
show: true,
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
},
customProperty: {
data: item,
type: key,
fn: item.vehicleId ? value.fn2 : value.fn,
pop: {
data: value.pop,
width: value.width,
},
},
});
})
);
});
}
}
await Promise.all(promises);
};
function removePoint() {
viewer.entities.removeAll(); //删除地图上绘制的所有的点
viewer.dataSources.removeAll(); //删除地图上面的聚合点
}
//回调函数
async function receiveMessageFromIframePage(event) {
let timer = null;
removePoint();
timer = setInterval(() => {
addPoint(JSON.parse(event.data));
}, 1000);
setTimeout(() => {
clearInterval(timer);
}, 1000);
};
window.addEventListener("message", receiveMessageFromIframePage, true);
}
window.startup(Cesium).catch((error) => {
"use strict";
console.error(error);
});
</script>
</html>