我使用的版本:vue3 + vue/cli 5.0.6 + cesium1.95.0
文章目录
一、引入图片报错:Error loading image for billboard: [object Event]
解决办法:可以import或require引入一下再应用。
二、创建实体使用自定义材质时报错: export ‘文件名’ (imported as ‘Cesium’) was not found in ‘cesium/Cesium’ (possible exports:
解决办法:在引入的js文件或应用它的组件里(主要看报错的位置):
将import * as Cesium from 'cesium/Cesium’改成let Cesium = require(‘cesium/Cesium’)。
三、使用自定义属性时报错:Cannot read properties of undefined
解决办法:在引入js文件时(用到了cesium),注意在cesium渲染之后在调用,不然会导致属性未定义或在cesium上找不到该属性。
四、鼠标放置实体的位置和点击位置不一致
我的情况是:我的地球视角并不是垂直地面的,是倾斜的,所以实体的放置位置如果是有高程的,那么看起来和鼠标点击位置就是会有差距的,如果放置位置使用pickEllipsoid(无高程),就是没差的。(我现在放置模型时,像飞机什么的就是有高程的,汽车这种就是没有高程的)。
然后这个在我刚开始应用的时候真的很懵!!因为cesium获取点击处的位置信息api也太多了!像什么pick,drillPick,pickPosition,pickEllipsoid等等等,这里我根据自己理解总结一下:
1、Scene:pick和drillPick主要用来获取实体对象,pick只能获取一个实体,drillPick可以获取点击位置处的多个实体(然后通过for循环遍历出来即可);pickPosition可以获取地球上点击位置对应的世界坐标,可用于模型表面位置的选取。
2、camera:pickEllipsoid就是获取到地表即不含高程的位置坐标;getPickRay常和scene.globe.pick一起使用,适用于拾取有地形高程的点,但不可用于模型、倾斜摄影等表面高度。
/*我用的window.viewer是因为我挂载到了window上*/
//获取实体、删除实体
var pick = window.viewer.scene.pick(e.position)
if (Cesium.defined(pick)) {
console.log(pick.id.id)
window.viewer.entities.removeById(pick.id.id)
}
//采用getPickRay和globe.pick获取笛卡尔坐标,并转换成经纬度(保留了四位小数)
let ray = window.viewer.scene.camera.getPickRay(e.endPosition) //获取相机射线
let position = window.viewer.scene.globe.pick(ray, window.viewer.scene) //根据射线和场景求出在球面中的笛卡尔坐标
if (position) {
let cartographicNew = Cesium.Cartographic.fromCartesian(position)
let lon = Cesium.Math.toDegrees(cartographicNew.longitude).toFixed(4) //获取经度,保留四位小数
let lat = Cesium.Math.toDegrees(cartographicNew.latitude).toFixed(4) //获取纬度
let cameraHeight = Math.ceil(window.viewer.camera.positionCartographic.height) //获取相机的高度
}
//从笛卡尔坐标获取经度
function getLongitude(e) {
const position = window.viewer.scene.pickPosition(e.position)
const cartographicNew = Cesium.Cartographic.fromCartesian(position)
const longitude = Cesium.Math.toDegrees(cartographicNew.longitude)
return longitude
}
//获取纬度
function getLatitude(e) {
const position = window.viewer.scene.pickPosition(e.position)
const cartographicNew = Cesium.Cartographic.fromCartesian(position)
const latitude = Cesium.Math.toDegrees(cartographicNew.latitude)
return latitude
}
//获取相机的高度
function getCameraheight() {
const cameraHeight = Math.ceil(window.viewer.camera.positionCartographic.height)
return cameraHeight
}
//获取点击位置,返回在椭球上面的点的坐标(无高程)
function getClickposition(e) {
const earthPosition = window.viewer.camera.pickEllipsoid(e.position, window.viewer.scene.globe.ellipsoid)
return earthPosition
}
//获取海拔高度
function getHeight(e) {
let cartesian = window.viewer.scene.globe.pick(window.viewer.camera.getPickRay(e.position), window.viewer.scene)
let cartographic = window.viewer.scene.globe.ellipsoid.cartesianToCartographic(cartesian)
let height = window.viewer.scene.globe.getHeight(cartographic)
return height
}
五、世界坐标转为屏幕坐标wgs84ToWindowCoordinates
最近有一个需求,要在模型上方显示信息框并且要跟随模型移动,虽然模型本身可以添加label实体,但是样式就不太灵活了,自己写div,就要考虑位置如何跟随模型,查看文档后就发现了一个接口wgs84ToWindowCoordinates,它可以将世界坐标转换成屏幕坐标,于是就可以安心自己写div了。
//世界坐标转屏幕
Cesium.SceneTransforms.wgs84ToWindowCoordinates(scene, Cartesian3);
ps:个人理解,欢迎指正或补充。
也许对你有帮助(以下都是我参考过并能成功运行的):
cesium官网
cesium Github
cesium中文api文档
cesium实战系列总目录(详细实用)
Cesium模型 旋转、缩放
Cesium常用事件(点击、鼠标、相机移动)
vue+Cesium实现画线测距,画面测面积(注释写的很清楚,在总代码里摘出相应的函数直接使用即可)