Cesium场景内鼠标添加模型
核心思想
最近在项目中,需要实现在cesium中双击空间内一点添加标识牌模型,其实做法也很简单:
- 监听鼠标双击事件
2.获取当前position的笛卡尔坐标 - 根据笛卡尔坐标获取经纬度与高度(高度需要地理高度,保证模型接地)
- 根据位置信息在当前位置生成一个弹窗,里面需要去设置添加模型的一些属性
- viewer.entities.add添加模型
具体做法
- 监听鼠标双击事件
var canvas=viewer.scene.canvas;
let handler = new Cesium.ScreenSpaceEventHandler(canvas);
handler.setInputAction(function (event) {
//具体功能
}, Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK)
2.获取当前position的笛卡尔坐标,然后转化成经纬度高度信息
这一块放在监听事件里
var lon;
var lat;
var height;
var cartographic;
var scene = viewer.scene;
var ellipsoid = scene.globe.ellipsoid;
var cartesian = viewer.scene.pickPosition(event.position);//笛卡尔坐标
viewer.scene.globe.depthTestAgainstTerrain = true;
console.log('笛卡尔坐标 :>> ', cartesian);
if (cartesian) {
cartographic = ellipsoid.cartesianToCartographic(cartesian);//地图坐标
lon = Cesium.Math.toDegrees(cartographic.longitude).toFixed(10);
lat = Cesium.Math.toDegrees(cartographic.latitude).toFixed(10);
//地理高度
height = (cartographic.height+1).toFixed(5);
//相机高度
// height=viewer.camera.positionCartographic.height.toFixed(0);
}
- 弹窗样式, 这里使用的是一位老哥写好的popup弹窗类,npm安装后直接用
整体效果如下
npm install cesium_custom_popup
gitee地址也放下面了
链接: https://gitee.com/giser_kangweitao/cesium_custom_popup
5. 弹窗样式
const listHtml =
`<ul style="width: 100%; height: 100%;font-size:22px;text-align: center; color:white;padding-top:30px;z-index: 10;">
<li>编号: <input type="text" id="model_id"></li>
<li>类型:<input type="text" id="model_type"></li>
<li>公路: <input type="text" id="road" list="appRoadlist">
<datalist id="appRoadlist">
<option >S228</option>
<option >S224</option>
<option>S101</option>
</datalist>
</li>
<li>标签:<input type="text" id="guidepost_label" list="appLabellist" >
<datalist id="appLabellist">
<option >国/省道标识</option>
<option >丁字路口</option>
<option >服务区</option>
<option >目的地距离</option>
<option >限速</option>
<option >收费站</option>
</datalist>
</li>
<button style="background-color: #49D182;
border-radius: 5px;
position: absolute;
top: 55%;
width: 100px;
height: 40px;
color: #FFFFFF;
"id="btn">添加模型</button>
</ul>`;
//放置弹窗
const putModel = new CustomPopup(
[lon,lat,height],
listHtml,
"interaction",
{title: "添加模型", lineHeight: 50 }
);
putModel.addTo(viewer);
7.点击弹窗事件,点击添加模型后,在当前位置插入模型
putModel.onClickPopup((e) => {
if (e.target.id === "btn") {
var position=Cesium.Cartesian3.fromDegrees(lon,lat,height);//转换为笛卡尔坐标
viewer.entities.add({
position :cartesian,
id: document.getElementById("model_id").value,
model : {
uri : './road_gltf/guidepost/20221019140613_parent_directory_路标45.gltf',
scale:(2,2,2)
},
data: {
type: document.getElementById("model_type").value,
info:{
road:document.getElementById("road").value,
lat:lat,
lng:lon,
alt:height,
road:document.getElementById("guidepost_label").value
}
}
});
}
});
完整代码
import CustomPopup from "./tag.js"; //引入popup弹窗类
var canvas=viewer.scene.canvas;
let handler = new Cesium.ScreenSpaceEventHandler(canvas);
handler.setInputAction(function (event) {
var lon;
var lat;
var height;
var cartographic;
var scene = viewer.scene;
var ellipsoid = scene.globe.ellipsoid;
var cartesian = viewer.scene.pickPosition(event.position);//笛卡尔坐标
viewer.scene.globe.depthTestAgainstTerrain = true;
console.log('笛卡尔坐标 :>> ', cartesian);
if (cartesian) {
cartographic = ellipsoid.cartesianToCartographic(cartesian);//地图坐标
lon = Cesium.Math.toDegrees(cartographic.longitude).toFixed(10);
lat = Cesium.Math.toDegrees(cartographic.latitude).toFixed(10);
//地理高度
height = (cartographic.height+1).toFixed(5);
//相机高度
// height=viewer.camera.positionCartographic.height.toFixed(0);
}
const listHtml =
`<ul style="width: 100%; height: 100%;font-size:22px;text-align: center; color:white;padding-top:30px;z-index: 10;">
<li>编号: <input type="text" id="model_id"></li>
<li>类型:<input type="text" id="model_type"></li>
<li>公路: <input type="text" id="road" list="appRoadlist">
<datalist id="appRoadlist">
<option >S228</option>
<option >S224</option>
<option>S101</option>
</datalist>
</li>
<li>标签:<input type="text" id="guidepost_label" list="appLabellist" >
<datalist id="appLabellist">
<option >国/省道标识</option>
<option >丁字路口</option>
<option >服务区</option>
<option >目的地距离</option>
<option >限速</option>
<option >收费站</option>
</datalist>
</li>
<button style="background-color: #49D182;
border-radius: 5px;
position: absolute;
top: 55%;
width: 100px;
height: 40px;
color: #FFFFFF;
"id="btn">添加模型</button>
</ul>`;
const putModel = new CustomPopup(
[lon,lat,height],
listHtml,
"interaction",
{title: "添加模型", lineHeight: 50 }
);
putModel.addTo(viewer);
putModel.onClickPopup((e) => {
if (e.target.id === "btn") {
var position=Cesium.Cartesian3.fromDegrees(lon,lat,height);//转换为笛卡尔坐标
viewer.entities.add({
position :cartesian,
id: document.getElementById("model_id").value,
model : {
uri : './road_gltf/guidepost/20221019140613_parent_directory_路标45.gltf',
scale:(2,2,2)
},
data: {
type: document.getElementById("model_type").value,
info:{
road:document.getElementById("road").value,
lat:lat,
lng:lon,
alt:height,
road:document.getElementById("guidepost_label").value
}
}
});
}
});
}, Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK)
完成效果