使用Cesium 创建电线塔并连线
作为一个cesium小白,也记录一下自己在项目上使用的一些东西,话不多说,直接上步骤。
第一步—下载cesium包
本来想直接在Vue上开发的,但是想简单点,就直接在官网下了一个1.7的cesium包在源代码上进行了:
项目结构大致如此,忽略mars3d这些cesium外的包,后期开发别的功能的在单独记录这些。
第二步—初始化cesium
1.去掉一些不用的东西:
var viewer = new Cesium.Viewer("cesiumContainer", {
terrainProvider: Cesium.createWorldTerrain(),
shouldAnimate: true,
baseLayerPicker: false, //图层选择器
animation: false, //左下角仪表
fullscreenButton: false, //全屏按钮
geocoder: false, //右上角查询搜索
infoBox: false, //信息框
homeButton: false, //home按钮
// sceneModePicker: true, //3d 2d选择器
selectionIndicator: false, //
timeline: false, //时间轴
navigationHelpButton: false, //右上角帮助按钮
});
viewer.scene.globe.depthTestAgainstTerrain = true;
//水
viewer.scene.globe.depthTestAgainstTerrain = true;
//光照
viewer.scene.globe.enableLighting = true;
//相机飞行
// viewer.camera.flyTo({
// destination : Cesium.Cartesian3.fromDegrees(112.96244133923338, 28.187044586575954, 15000.0)
// });
var scene = viewer.scene;
- 在地图上放上几个按钮,id我这里就随便取了
<button id="btn">线路一</button>
<button id="btn1">清除</button>
<button id="btn2">新建铁塔</button>
<button id="btn3">连线</button>
第三步—写方法
- 点击线路的方法
var model;
var ddd;
//定义几条线路的数据
var data = [
{
id: 'modelMatrix1',
longLati: [112.96244133923338, 28.987044586575954],
name: 'modal1',
height: 0
},
{
id: 'modelMatrix2',
longLati: [112.85244143923338, 28.987044586575954],
name: 'modal2',
height: 0
},
{
id: 'modelMatrix3',
longLati: [113.04244133923338, 28.687044586575954],
name: 'modal3',
height: 0
},
{
id: 'modelMatrix3',
longLati: [114.04244133923338, 29.687044586575954],
name: 'modal3',
height: 0
},
{
id: 'modelMatrix3',
longLati: [115.04244133923338, 31.687044586575954],
name: 'modal3',
height: 200
}
];
document.getElementById('btn').onclick = function () {
var modelMatrix;
for (let i = 0; i < data.length; i++) {
var modelMatrix;
modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(Cesium.Cartesian3.fromDegrees(data[i].longLati[0], data[i].longLati[1], data[i].height)); //gltf数据加载位置
model = scene.primitives.add(Cesium.Model.fromGltf({
url: '../Source/dt.gltf', //如果为bgltf则为.bgltf
modelMatrix: modelMatrix,
scale: 1.0
}))
// fixGltf(model);
//贴地的线
ddd = viewer.entities.add({
model: model,
corridor: {
positions: Cesium.Cartesian3.fromDegreesArray([
data[0].longLati[0] + 0.001,
data[0].longLati[1] + 0.0015,
data[1].longLati[0] + 0.001,
data[1].longLati[1] + 0.0015,
data[2].longLati[0] + 0.001,
data[2].longLati[1] + 0.0015,
data[3].longLati[0] + 0.001,
data[3].longLati[1] + 0.0015,
data[4].longLati[0] + 0.001,
data[4].longLati[1] + 0.0015,//连线的数据,因为我转换的fltf模型有偏差,所以稍微调整了一下...
]),
width: 5,//线的宽度
material: Cesium.Color.YELLOW //颜色
}
});
}
//空中的线
var czml = [
{
id: "document",
name: "CZML Path",
version: "1.0",
clock: {
interval: "2012-08-04T10:00:00Z/2020-08-04T15:00:00Z",
currentTime: "2012-08-04T10:00:00Z",
multiplier: 10,
},
},
{
id: "path",
name: "path with GPS flight data",
description:
"<p>Hang gliding flight log data from Daniel H. Friedman.<br>Icon created by Larisa Skosyrska from the Noun Project</p>",
availability: "2012-08-04T10:00:00Z/2020-08-04T15:00:00Z",
path: {
material: {
polylineOutline: {
color: {
rgba: [255, 0, 255, 255],
},
outlineColor: {
rgba: [0, 255, 255, 255],
},
outlineWidth: 1,
},
},
width: 2,
leadTime: 10,
trailTime: 1000000000000,
resolution: 5,
},
position: {
epoch: "2012-08-04T10:00:00Z",
cartographicDegrees: [
0,
data[0].longLati[0] + 0.001,
data[0].longLati[1] + 0.0015,
400,
1,
data[1].longLati[0] + 0.001,
data[1].longLati[1] + 0.0015,
400,
2,
data[2].longLati[0] + 0.001,
data[2].longLati[1] + 0.0015,
400,
3,
data[3].longLati[0] + 0.001,
data[3].longLati[1] + 0.0015,
400,
4,
data[4].longLati[0] + 0.001,
data[4].longLati[1] + 0.0015,
600
],
},
},
];
viewer.dataSources
.add(Cesium.CzmlDataSource.load(czml))
.then(function (ds) {
// viewer.trackedEntity = ds.entities.getById("path");
viewer.camera.flyTo({
destination: Cesium.Cartesian3.fromDegrees(112.96244133923338, 28.987044586575954, 10000.0) //相机飞入点
});
});
}
效果大致如上
- 点击清除的代码,这个功能还有待优化的,上面随手定义的ddd,就是拿来测试清除的,但是没有达到我的目的,官方文档里面提到的remove和removeAll也是把整个事件给清除掉了。以至于我第二次创建就用不了了,如果各位大佬有解决办法的,不妨赐教…
document.getElementById('btn1').onclick = function () { viewer.scene.primitives.remove(model) viewer.scene.primitives.remove(ddd) lData = [] }
- 点击新建铁塔的方法,这个功能也还有待优化,后期优化再补上优化的东西:因为有高程,但是在不同角度点击同一个地方的时候,获取的高度都不一样,甚至差的离谱,在垂直角度上获取到的高度最接近真实值,所有我在新建铁塔的时候就把视角锁定了;
var canvas = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas); var isture = false; var body = document.querySelector("body") var modelMatrix1; var lData = []; var setInputActionVal = true; document.getElementById('btn2').onclick = function () { isture = !isture; if (isture) { setInputActionVal = true; btn2.innerHTML = "取消新建" btn3.style.display = "block"; body.style.cursor = "pointer" viewer.camera.setView({ // Cesium的坐标是以地心为原点,一向指向南美洲,一向指向亚洲,一向指向北极州 // fromDegrees()方法,将经纬度和高程转换为世界坐标 // destination:Cesium.Cartesian3.fromDegrees(112.9,28.9,50000.0), orientation: { // 指向 // heading:Cesium.Math.toRadians(90,0), // 视角 pitch: Cesium.Math.toRadians(-90), roll: 0.0 } }); scene.screenSpaceCameraController.enableTilt = false; canvas.setInputAction(function (event) { if (setInputActionVal) { var earthPosition = viewer.camera.pickEllipsoid(event.position, viewer.scene.globe.ellipsoid); var cartographic = Cesium.Cartographic.fromCartesian(earthPosition, viewer.scene.globe.ellipsoid, new Cesium.Cartographic()); var lat = Cesium.Math.toDegrees(cartographic.latitude); var lng = Cesium.Math.toDegrees(cartographic.longitude); var height = cartographic.height;javascript var terrainProvider = Cesium.createWorldTerrain(); var positions = [ Cesium.Cartographic.fromDegrees(lng, lat), ]; var promise = Cesium.sampleTerrainMostDetailed(terrainProvider, positions); Cesium.when(promise, function (updatedPositions) { var terrainHeight = updatedPositions[0].height console.log(updatedPositions); modelMatrix1 = Cesium.Transforms.eastNorthUpToFixedFrame(Cesium.Cartesian3.fromDegrees(lng, lat, terrainHeight)); //gltf数据加载位置 model = scene.primitives.add(Cesium.Model.fromGltf({ url: '../Source/dt.gltf', //如果为bgltf则为.bgltf modelMatrix: modelMatrix1, scale: 1.0 })); let data = { longitude: lng, latitude: lat, height: terrainHeight } lData.push(data); }); } }, Cesium.ScreenSpaceEventType.LEFT_CLICK); } else { setInputActionVal = false; btn2.innerHTML = "新建铁塔" body.style.cursor = "default" scene.screenSpaceCameraController.enableTilt = true; } }
点击取消新建就会取消锁定视角
如上图,每点击一个位置 就会生成一个电线塔
4.点击连线的方法
document.getElementById('btn3').onclick = function () {
if (lData.length < 2) {
alert('请新建两个以上的铁塔');
return false;
}
var data = []
var data1 = []
for (let i = 0; i < lData.length; i++) {
data.push(i, lData[i].longitude + 0.001, lData[i].latitude + 0.0015, lData[i].height + 350);
data1.push(lData[i].longitude + 0.001, lData[i].latitude + 0.0015);
}
viewer.entities.add({
corridor: {
positions: Cesium.Cartesian3.fromDegreesArray(data1),
width: 5,
material: Cesium.Color.YELLOW
}
});
var czml = [
{
id: "document",
name: "CZML Path",
version: "1.0",
clock: {
interval: "2012-08-04T10:00:00Z/2020-08-04T15:00:00Z",
currentTime: "2012-08-04T10:00:00Z",
multiplier: 10,
},
},
{
id: "path",
name: "path with GPS flight data",
description:
"<p>Hang gliding flight log data from Daniel H. Friedman.<br>Icon created by Larisa Skosyrska from the Noun Project</p>",
availability: "2012-08-04T10:00:00Z/2020-08-04T15:00:00Z",
path: {
material: {
polylineOutline: {
color: {
rgba: [255, 0, 255, 255],
},
outlineColor: {
rgba: [0, 255, 255, 255],
},
outlineWidth: 1,
},
},
width: 2,
leadTime: 10,
trailTime: 1000000000000,
resolution: 5,
},
position: {
epoch: "2012-08-04T10:00:00Z",
cartographicDegrees: data,
},
},
];
viewer.dataSources
.add(Cesium.CzmlDataSource.load(czml))
.then(function (ds) {
});
}
如上图,连接电线塔。
暂时先放这几个功能,首次发帖,也算是初学cesium,请大佬们多多指教。