vue3+Cesium 遇到的问题及解决办法(持续更新)

我使用的版本: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、Scenepick和drillPick主要用来获取实体对象,pick只能获取一个实体,drillPick可以获取点击位置处的多个实体(然后通过for循环遍历出来即可);pickPosition可以获取地球上点击位置对应的世界坐标,可用于模型表面位置的选取。
2、camerapickEllipsoid就是获取到地表即不含高程的位置坐标;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实现画线测距,画面测面积(注释写的很清楚,在总代码里摘出相应的函数直接使用即可)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值