cesium移动模型绘制轨迹
cesium移动模型绘制轨迹
之前开发过程中有这个需求,然后用czml发现效果并不是自己想要的,之后又用删除添加,发现这样太消耗性能, 网上资料真的是太难找,我想做这个都是些高冷的大神。cesium这条学习之路真的让人心酸,做了有大半年了才开始对它有一个大概的了解,下面进入正题。大佬们发现问题还请指出,第一次写文章来之不易,转载请注明出处。本次文章查了几篇拖动与绘制轨迹线的博客,感谢大佬们的分享让我有了思路。
设计过程
思路:开始 --> 添加模型 --> 移动、旋转模型 --> 实时传入坐标绘制轨迹(动态轨迹)
代码
class DrawTransformCurve {
constructor(arg) {
//设置唯一id 备用
this.viewer = arg.viewer;
this.Cesium = arg.Cesium;
this._poly = {};
this._positionsd = {};
this._polyLine = {};
this._entitys = {};
}
// 添加模型
addEntity(params) {
var entiti = this.viewer.entities.add({
position: this.Cesium.Cartesian3.fromDegrees(params.position.lon, params.position.lat, params.position.het),
orientation: Cesium.Transforms.headingPitchRollQuaternion(Cesium.Cartesian3.fromDegrees(params.position.lon, params.position.lat, params.position.het),
new Cesium.HeadingPitchRoll(Cesium.Math.toRadians(params.rotates && params.rotates.heading || 0), Cesium.Math.toRadians(params.rotates && params.rotates.pitch || 0), Cesium.Math.toRadians(params.rotates && params.rotates.roll || 0))),
model: {
uri: params.url || "./Apps/SampleData/models/CesiumAir/Cesium_Air.glb",
minimumPixelSize: params.minSize || 128,//最小的模型像素
maximumScale: params.MaxSize || 10000,//最大的模型像素
}
})
this._entitys[params.id] = entiti;
}
// 绘制移动线
addtransPolyLine(params) {
var _this = this
var Cesium = this.Cesium;
var viewer = this.viewer
var PolyLinePrimitive = (function () {
function _(positions) {
this.options = {
polyline: {
show: true,
positions: [],
material: params.color ? Cesium.Color.fromCssColorString(params.color) : Cesium.Color.RED,
width: params.width || 5
}
};
this.positions = positions;
this._init();
}
_.prototype._init = function () {
var _self = this;
var _update = function () {
return _self.positions;
};
//实时更新polyline.positions
this.options.polyline.positions = new Cesium.CallbackProperty(_update, false);
var pLine = viewer.entities.add(this.options);
_this._polyLine[params.id] = pLine;
};
return _;
})();
var fromDegposition = Cesium.Cartesian3.fromDegrees(params.position.lon, params.position.lat, params.position.alt)
if (_this._positionsd[params.id] || _this._positionsd[params.id] instanceof Array) {
if (_this._positionsd[params.id].length >= 2) {
if (!Cesium.defined(_this._poly[params.id])) {
_this._poly[params.id] = new PolyLinePrimitive(_this._positionsd[params.id]);
} else {
_this._positionsd[params.id].push(fromDegposition);
}
} else {
_this._positionsd[params.id].push(fromDegposition);
}
} else {
_this._positionsd[params.id] = [];
_this._positionsd[params.id].push(fromDegposition);
}
}
// 开始绘制移动模型轨迹
startTransfromEnt(params) {
var _this = this
var Cesium = this.Cesium;
var viewer = this.viewer
if (this._entitys[params.id]) {
var fromDegposition = Cesium.Cartesian3.fromDegrees(params.position.lon, params.position.lat, params.position.alt)
this._entitys[params.id]._position._value = fromDegposition;
if (params.ifDrawLine)
this.addtransPolyLine(params)
if (params.rotates) this.rotateEnt(params)
} else {
this.addEntity(params)
if (params.ifDrawLine)
this.addtransPolyLine(params)
}
}
// 旋转模型
rotateEnt(params) {
var _this = this
var Cesium = this.Cesium;
var viewer = this.viewer
if (this._entitys[params.id]) {
var hpr = new Cesium.HeadingPitchRoll(Cesium.Math.toRadians(params.rotates && params.rotates.heading || 0), Cesium.Math.toRadians(params.rotates && params.rotates.pitch || 0), Cesium.Math.toRadians(params.rotates && params.rotates.roll || 0));
var orientation = Cesium.Transforms.headingPitchRollQuaternion(this._entitys[params.id]._position._value, hpr);
this._entitys[params.id]._orientation._value = orientation
}
}
///删/
// 清空
clear() {
for (const key in this._entitys) {
if (this._entitys.hasOwnProperty.call(this._entitys, key)) {
const element = this._entitys[key];
this.viewer.entities.remove(element)
this.viewer.entities.remove(this._polyLine[key])
this._poly[key] = undefined;
this._positionsd[key] = undefined;
this._polyLine[key] = undefined;
this._entitys[key] = undefined;
}
}
}
}
调用方式
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>移动轨迹绘制</title>
<link href="https://cesium.com/downloads/cesiumjs/releases/1.74/Build/Cesium/Widgets/widgets.css" rel="stylesheet">
<script src="https://cesium.com/downloads/cesiumjs/releases/1.74/Build/Cesium/Cesium.js"></script>
<style>
html,
body,
#cesiumContainer {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
overflow: hidden;
}
.eventName {
position: fixed;
top: 100px;
left: 200px;
z-index: 9999;
}
</style>
</head>
<body>
<div id="cesiumContainer"></div>
<div class="eventName">
<button onclick="event2()">启航</button>
</div>
<script>
var viewer = new Cesium.Viewer("cesiumContainer", {
animation: false,
baseLayerPicker: false,
fullscreenButton: false,
geocoder: false,
homeButton: false,
infobox: false,
sceneModePicker: false,
selectionIndicator: false,
timeline: false,
scene3DOnly: true,
navigationHelpButton: false,
creditContainer: "cesiumContainer",
fullscreenButton: false,
vrButton: false,
skyAtmosphere: false,
shouldAnimate: true,
imageryProvider: new Cesium.ArcGisMapServerImageryProvider({
url: 'https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer'
}),
maximumScreenSpaceError: 16, //默认值16 用于提高细节细化级别的最大屏幕空间错误
});
viewer.camera.setView({
destination: Cesium.Cartesian3.fromDegrees(117.224, 31.819, 300.0),
orientation: {
// 指向
heading: 0.0,
// 视角
pitch: Cesium.Math.toRadians(-90),
roll: 0.0
}
})
class DrawTransformCurve {
constructor(arg) {
//设置唯一id 备用
this.viewer = arg.viewer;
this.Cesium = arg.Cesium;
this._poly = {};
this._positionsd = {};
this._polyLine = {};
this._entitys = {};
}
// 添加模型
addEntity(params) {
var entiti = this.viewer.entities.add({
id: params.id,
position: this.Cesium.Cartesian3.fromDegrees(params.position.lon, params.position.lat, params.position.het),
orientation: Cesium.Transforms.headingPitchRollQuaternion(Cesium.Cartesian3.fromDegrees(params.position.lon, params.position.lat, params.position.het),
new Cesium.HeadingPitchRoll(Cesium.Math.toRadians(params.rotates && params.rotates.heading || 0), Cesium.Math.toRadians(params.rotates && params.rotates.pitch || 0), Cesium.Math.toRadians(params.rotates && params.rotates.roll || 0))),
model: {
uri: params.url || "./Apps/SampleData/models/CesiumAir/Cesium_Air.glb",
minimumPixelSize: params.minSize || 128,//最小的模型像素
maximumScale: params.MaxSize || 10000,//最大的模型像素
}
})
this._entitys[params.id] = entiti;
}
// 绘制移动线
addtransPolyLine(params) {
var _this = this
var Cesium = this.Cesium;
var viewer = this.viewer
var PolyLinePrimitive = (function () {
function _(positions) {
this.options = {
polyline: {
show: true,
positions: [],
material: params.color ? Cesium.Color.fromCssColorString(params.color) : Cesium.Color.RED,
width: params.width || 5
}
};
this.positions = positions;
this._init();
}
_.prototype._init = function () {
var _self = this;
var _update = function () {
return _self.positions;
};
//实时更新polyline.positions
this.options.polyline.positions = new Cesium.CallbackProperty(_update, false);
var pLine = viewer.entities.add(this.options);
_this._polyLine[params.id] = pLine;
};
return _;
})();
var fromDegposition = Cesium.Cartesian3.fromDegrees(params.position.lon, params.position.lat, params.position.alt)
if (_this._positionsd[params.id] || _this._positionsd[params.id] instanceof Array) {
if (_this._positionsd[params.id].length >= 2) {
if (!Cesium.defined(_this._poly[params.id])) {
_this._poly[params.id] = new PolyLinePrimitive(_this._positionsd[params.id]);
} else {
_this._positionsd[params.id].push(fromDegposition);
}
} else {
_this._positionsd[params.id].push(fromDegposition);
}
} else {
_this._positionsd[params.id] = [];
_this._positionsd[params.id].push(fromDegposition);
}
}
// 开始绘制移动模型轨迹
startTransfromEnt(params) {
var _this = this
var Cesium = this.Cesium;
var viewer = this.viewer
if (this._entitys[params.id]) {
var fromDegposition = Cesium.Cartesian3.fromDegrees(params.position.lon, params.position.lat, params.position.alt)
this._entitys[params.id]._position._value = fromDegposition;
if (params.ifDrawLine)
this.addtransPolyLine(params)
if (params.rotates) this.rotateEnt(params)
} else {
this.addEntity(params)
if (params.ifDrawLine)
this.addtransPolyLine(params)
}
}
// 旋转模型
rotateEnt(params) {
var _this = this
var Cesium = this.Cesium;
var viewer = this.viewer
if (this._entitys[params.id]) {
var hpr = new Cesium.HeadingPitchRoll(Cesium.Math.toRadians(params.rotates && params.rotates.heading || 0), Cesium.Math.toRadians(params.rotates && params.rotates.pitch || 0), Cesium.Math.toRadians(params.rotates && params.rotates.roll || 0));
var orientation = Cesium.Transforms.headingPitchRollQuaternion(this._entitys[params.id]._position._value, hpr);
this._entitys[params.id]._orientation._value = orientation
}
}
///删/
// 清空
clear() {
for (const key in this._entitys) {
if (this._entitys.hasOwnProperty.call(this._entitys, key)) {
const element = this._entitys[key];
this.viewer.entities.remove(element)
this.viewer.entities.remove(this._polyLine[key])
this._poly[key] = undefined;
this._positionsd[key] = undefined;
this._polyLine[key] = undefined;
this._entitys[key] = undefined;
}
}
}
}
var clickPont = new DrawTransformCurve({
viewer,
Cesium
})
var timer2 = null
function event2() {
var position = {
lon: 117.224, lat: 31.819, alt: 0,
}
var rotates = {
heading: 0,
pitch: 0,
roll: 0
}
var _this = this
var fromDegposition = Cesium.Cartesian3.fromDegrees(position.lon, position.lat, position.alt)
clearInterval(timer2)
timer2 = setInterval(() => {
clickPont.startTransfromEnt({
id: 'a3-60',
position,
rotates,
ifDrawLine: true,
})
position.lon += Math.random() * 0.0001;
position.lat += Math.random() * 0.0001;
position.alt += Math.random() * 1;
rotates.heading += Math.random() * 10;
rotates.pitch += Math.random() * 10;
rotates.roll += Math.random() * 10;
}, 100)
}
</script>
</body>
</html>