// cesium 动画效果
/**
* @description 画扇形(从正北开始顺时针旋转)
* @param {Viewer} viewer - Cesium的Viewer实例
* @param {Number} d1 扇形下弧度的角度
* @param {Number} d2 扇形上弧度的角度
* @param {Number} longitude 中心点经度
* @param {Number} latitude 中心点纬度
* @param {Number} radius 扇形半径
* @param {string} id 目标id
*/
function drawSector(viewer, d1, d2, longitude, latitude, radius, id) {
var list = [Number(longitude), Number(latitude)];
for (let i = d1; i < d2; i += 1) {
var point = calculatingTargetPoints(
longitude,
latitude,
0,
(90 - i) * (Math.PI / 180),
radius,
viewer
);
list.push(point[0]);
list.push(point[1]);
}
list.push(Number(longitude));
list.push(Number(latitude));
let color = Cesium.Color.BLUE.withAlpha(1);
//蓝色扇形
var box = viewer.entities.add({
id: id + "hudu",
polygon: {
hierarchy: Cesium.Cartesian3.fromDegreesArray(list),
material: color,
outline: true, // height must be set for outlines to display
outlineColor: {
rgba: [255, 255, 255, 255],
},
},
});
}
/**
* 计算扇形的目标点经纬度
* @param {number} longitude - 中心点经度
* @param {number} latitude - 中心点纬度
* @param {number} height - 中心点高度
* @param {number} direction - 方向
* @param {number} radius - 半径
* @param {Viewer} viewer - Cesium的Viewer实例
* @returns {number[]} - 目标点经纬度数组 [longitude, latitude]
*/
function calculatingTargetPoints(
longitude,
latitude,
height,
direction,
radius,
viewer
) {
//根据位置,方位,距离求经纬度
var viewPoint = Cesium.Cartesian3.fromDegrees(longitude, latitude, height);
var webMercatorProjection = new Cesium.WebMercatorProjection(
viewer.scene.globe.ellipsoid
);
var viewPointWebMercator = webMercatorProjection.project(
Cesium.Cartographic.fromCartesian(viewPoint)
);
var toPoint = new Cesium.Cartesian3(
viewPointWebMercator.x + radius * Math.cos(direction),
viewPointWebMercator.y + radius * Math.sin(direction),
0
);
toPoint = webMercatorProjection.unproject(toPoint);
toPoint = Cesium.Cartographic.toCartesian(toPoint.clone());
var cartographic = Cesium.Cartographic.fromCartesian(toPoint);
var point = [
Cesium.Math.toDegrees(cartographic.longitude),
Cesium.Math.toDegrees(cartographic.latitude),
];
return point;
}
/**
* 在Cesium地图上添加圆形图形
* @param {Viewer} viewer - Cesium的Viewer实例
* @param {Cartesian3} centerPosition - 圆心的位置
* @param {number} defense_radius - 圆形的半径(单位:米)
* @param {Object} _this - 当前上下文对象
*/
function rotundity(viewer, centerPosition, defense_radius, _this) {
// 创建实体 - 圆形图形
let circleEntity = viewer.entities.add({
id: "shebei",
position: centerPosition,
ellipse: {
semiMinorAxis: defense_radius,
semiMajorAxis: defense_radius,
material: Cesium.Color.BLUE.withAlpha(0.1),
outline: true,
outlineColor: Cesium.Color.BLACK,
},
});
let entity = viewer.entities.add({
position: centerPosition,
name: "圆形",
ellipse: {
semiMinorAxis: new Cesium.CallbackProperty(_this.changeR1, false),
semiMajorAxis: new Cesium.CallbackProperty(
_this.changeR1,
false
) /* _this.changeR1 是一个函数 changeR1() {
this.minR = this.minR + this.deviationR;
if (this.minR > this.maxR) {
this.minR = this.minR - this.maxR + this.deviationR;
}
return this.minR;
} */,
material: new Cesium.ColorMaterialProperty(
new Cesium.CallbackProperty(
_this.color,
false
) /* _this.color 是一个函数,color() {
let x = 1 - this.minR / this.maxR;
return Cesium.Color.BLUE.withAlpha(0.3);
}
*/
),
outlineColor: Cesium.Color.BLUE,
},
});
}
/**
* 在Cesium地图上添加图形
* @param {boolean} isAreaDefense - 是否是区域防御
* @param {Viewer} viewer - Cesium的Viewer实例
* @param {string} type - 图形类型('矩形', '圆形', '多边形')
* @param {string} color - 图形的颜色(CSS颜色字符串)
* @param {number} height - 图形的高度
* @param {Array} points - 图形的点坐标数组
* @param {number} radius - 圆形的半径
*/
function addfindList(
isAreaDefense,
viewer,
type,
color,
height,
points,
radius
) {
if (isAreaDefense) {
if (type == "矩形") {
var text = points;
var positions = [
Cesium.Cartesian3.fromDegrees(text[0].lng, text[0].lat, 0),
Cesium.Cartesian3.fromDegrees(text[3].lng, text[3].lat, 0),
Cesium.Cartesian3.fromDegrees(text[1].lng, text[1].lat, 0),
Cesium.Cartesian3.fromDegrees(text[2].lng, text[2].lat, 0),
];
var rectangle = viewer.entities.add({
name: "矩形",
polygon: {
hierarchy: positions,
material: Cesium.Color.fromCssColorString(color).withAlpha(0.5),
extrudedHeight: height,
perPositionHeight: true,
},
});
} else if (type == "圆形") {
var center;
if (points != String([])) {
if (points != String([])) {
center = Cesium.Cartesian3.fromDegrees(
JSON.parse(points)[0].lng,
JSON.parse(points)[0].lat,
0
);
}
var cylinder = viewer.entities.add({
name: "圆形",
position: center,
cylinder: {
length: height,
topRadius: radius,
bottomRadius: radius,
material: Cesium.Color.fromCssColorString(color).withAlpha(0.5),
outline: false,
},
});
}
} else if (type == "多边形") {
if (points != String([])) {
var positions = [];
points.forEach(function (point) {
var position = Cesium.Cartesian3.fromDegrees(
point.lng,
point.lat,
height
);
positions.push(position);
});
// 创建多边体实体对象
var polygonEntity = viewer.entities.add({
name: "多边形",
polygon: {
hierarchy: positions,
extrudedHeight: height,
material: Cesium.Color.fromCssColorString(color).withAlpha(0.5),
outline: true,
outlineColor: Cesium.Color.BLACK,
},
});
}
}
}
}
/**
* 在Cesium地图上创建圆形小圆点
* @param {Viewer} viewer - Cesium的Viewer实例
* @param {number} longitude - 圆点的经度
* @param {number} latitude - 圆点的纬度
* @param {number} detection_radius - 圆点的检测半径(单位:米)
* @param {string} sensor_name - 圆点的名称
*/
function makeRotundity(
viewer,
longitude,
latitude,
detection_radius,
sensor_name
) {
var centerPosition = Cesium.Cartesian3.fromDegrees(longitude, latitude);
// 创建半径
var radius = detection_radius; // 单位:米
// 创建实体 - 圆形图形
var circleEntity = viewer.entities.add({
position: centerPosition,
ellipse: {
semiMinorAxis: radius,
semiMajorAxis: radius,
material: Cesium.Color.RED.withAlpha(0.5),
outline: true,
outlineColor: Cesium.Color.BLACK,
},
});
// 创建实体 - 小圆点
var dotEntity = viewer.entities.add({
position: centerPosition,
point: {
pixelSize: 10,
color: Cesium.Color.BLUE,
outlineColor: Cesium.Color.WHITE,
outlineWidth: 2,
},
});
// 创建实体 - 标签
var labelEntity = viewer.entities.add({
position: centerPosition,
label: {
text: sensor_name,
font: "14px sans-serif",
fillColor: Cesium.Color.WHITE,
outlineColor: Cesium.Color.BLACK,
outlineWidth: 1,
style: Cesium.LabelStyle.FILL_AND_OUTLINE,
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM, // 标签底部对齐
pixelOffset: new Cesium.Cartesian2(0, 30), // 将标签显示在小圆点下方
},
});
}
/**
* 设置Cesium视图的位置和姿态
* @param {Viewer} viewer - Cesium的Viewer实例
* @param {number} longitude - 目标位置的经度
* @param {number} latitude - 目标位置的纬度
* @param {number} height - 目标位置的高度(单位:米)
* @param {number} heading - 视图的方位角(单位:度)
* @param {number} pitch - 视图的俯仰角(单位:度)
* @param {number} roll - 视图的滚动角(单位:度)
*/
function setViewValue(
viewer,
longitude,
latitude,
height,
heading,
pitch,
roll
) {
viewer.camera.setView({
destination: Cesium.Cartesian3.fromDegrees(longitude, latitude, height),
orientation: {
heading: Cesium.Math.toRadians(heading),
pitch: Cesium.Math.toRadians(pitch),
roll: Cesium.Math.toRadians(roll),
},
});
}
/**
* 在Cesium中创建一个四边形柱体
* @param {Viewer} viewer - Cesium的Viewer实例
* @param {String} name - 四边形柱体的名称
* @param {Array} positions - 四边形的位置数组,包含每个顶点的经纬度坐标
* @param {String} color - 四边形的颜色,使用CSS颜色字符串表示
* @param {Number} height - 柱体的高度
*/
/*
var positions = [
Cesium.Cartesian3.fromDegrees(-75.60354, 40.03883),
Cesium.Cartesian3.fromDegrees(-75.60354, 40.04383),
Cesium.Cartesian3.fromDegrees(-75.59854, 40.04383),
Cesium.Cartesian3.fromDegrees(-75.59854, 40.03883)
]; // 四边形的位置数组,包含每个顶点的经纬度坐标
*/
function quadrilateral(viewer, name, positions, color, height) {
var rectangle = viewer.entities.add({
name: name,
polygon: {
hierarchy: positions,
material: Cesium.Color.fromCssColorString(color).withAlpha(0.5),
extrudedHeight: height,
perPositionHeight: true,
},
});
}
/**
* 在Cesium中创建一个圆形柱体
* @param {Viewer} viewer - Cesium的Viewer实例
* @param {string} name - 圆形柱体的名称
* @param {Cartesian3} center - 圆形柱体的中心位置,使用Cesium.Cartesian3表示
* @param {number} height - 圆柱体的高度
* @param {number} radius - 圆柱体的半径
* @param {string} color - 圆柱体的颜色,使用CSS颜色字符串表示
*/
function gardenShape(viewer, name, center, height, radius, color) {
var cylinder = viewer.entities.add({
name: name,
position: center,
cylinder: {
length: height,
topRadius: radius,
bottomRadius: radius,
material: Cesium.Color.fromCssColorString(color).withAlpha(0.5),
outline: false,
},
});
}
/**
* 在Cesium中创建一个多边形(柱体)
* @param {Viewer} viewer - Cesium的Viewer实例
* @param {String} name - 多边形的名称
* @param {Array} positions - 多边形的位置数组,包含每个顶点的经纬度坐标
* @param {Number} height - 柱体的高度
* @param {String} color - 多边形的颜色,使用CSS颜色字符串表示
*/
function polygon(viewer, name, positions, height, color) {
var polygonEntity = viewer.entities.add({
name: name,
polygon: {
hierarchy: positions,
extrudedHeight: height,
material: Cesium.Color.fromCssColorString(color).withAlpha(0.5),
outline: true,
outlineColor: Cesium.Color.BLACK,
},
});
}
/**
* 在Cesium中实现相机飞行动画
* @param {Viewer} viewer - Cesium的Viewer实例
* @param {Number} longitude - 目标位置的经度
* @param {Number} latitude - 目标位置的纬度
* @param {Number} height - 目标位置的高度
* @param {Number} time - 飞行持续时间(以秒为单位)
* @param {Number} heading - 方向角度(以度为单位)
* @param {Number} pitch - 俯仰角度(以度为单位)
* @param {Number} roll - 翻滚角度(以弧度为单位)
*/
function setflyTo(
viewer,
longitude,
latitude,
height,
time,
heading,
pitch,
roll
) {
viewer.camera.flyTo({
destination: Cesium.Cartesian3.fromDegrees(
longitude,
latitude,
height
) /* 相机目标位置,即要飞往的目标位置 */,
duration: time, // 转移持续时间(以秒为单位)
orientation: {
heading: Cesium.Math.toRadians(heading), // 方向角度(以弧度为单位)
pitch: Cesium.Math.toRadians(pitch), // 俯仰角度(以弧度为单位)
roll: roll, // 翻滚角度(以弧度为单位)
},
});
}
/**
* @param {any} centerPosition :中心点
* @param {any} viewer :实体
* @param {Number} id 园的id
* @param {Object} _this - 当前上下文对象
* @param {String} color :圆形颜色 'rbg'或者'rgba(255,255,255,0.3)'
*/
function diffusion(centerPosition, viewer, id, _this, color) {
viewer.entities.add({
position: centerPosition,
name: "圆形",
id: id,
ellipse: {
semiMinorAxis: new Cesium.CallbackProperty(_this.changeR1, false),
/* _this.changeR1 是一个函数 changeR1() {
this.minR = this.minR + this.deviationR;
if (this.minR > this.maxR) {
this.minR = this.minR - this.maxR + this.deviationR;
}
return this.minR;
} */
semiMajorAxis: new Cesium.CallbackProperty(_this.changeR1, false),
material: new Cesium.ColorMaterialProperty(
new Cesium.CallbackProperty(function (time, result) {
// 返回根据动态逻辑计算的颜色值
return Cesium.Color.fromCssColorString(color);
}, false)
),
outlineColor: Cesium.Color.RED,
},
});
}
// 创建两点间的线段连接(折线) 实验 (120.277754, 31.533728, 2000)
/**
* @description: 背景修改成天空盒(根据时间不同天空盒背景不同)
* @param {any} viewer :实体
* @param {Number} oldlongitude :上一个经度
* @param {Number} oldlatitude :上一个纬度
* @param {Number} oldheight :上一个高度
* @param {Number} newlongitude :当前经度
* @param {Number} newlatitude :当前纬度
* @param {Number} newheight :当前高度
* @param {String} name :名字
* @param {String} color :线的颜色
* @param {String} pointcolor :点的颜色
*/
function Polyline(
viewer,
oldlongitude,
oldlatitude,
oldheight,
newlongitude,
newlatitude,
newheight,
name,
color,
pointcolor
) {
// 上一个点的位置
var cartesianLast = Cesium.Cartesian3.fromDegrees(
oldlongitude,
oldlatitude,
oldheight
);
// 现在点的位置
var cartesianNow = Cesium.Cartesian3.fromDegrees(
newlongitude,
newlatitude,
newheight
);
var polylinePosition = [cartesianLast, cartesianNow];
viewer.entities.add({
name: "line_" + name,
polyline: new Cesium.PolylineGraphics({
show: true,
positions: polylinePosition,
width: 1,
material: Cesium.Color.fromCssColorString(color),
}),
position: cartesianNow,
point: { pixelSize: 5, color: Cesium.Color.fromCssColorString(pointcolor) },
});
}
/**
* 在Cesium中添加倒三角模型并自动旋转
* @param {Viewer} viewer - Cesium的Viewer实例
* @param {number} longitude - 模型的经度
* @param {number} latitude - 模型的纬度
* @param {number} height - 模型的高度
* @param {string} name - 模型的名称
*/
function invertedTriangle(viewer, longitude, latitude, height, name) {
var position; // 模型的位置
var heading = 0; //偏航角(Y轴)
var pitch = 0; //俯仰角(X轴)
var roll = 0; //翻滚角(Z轴)
var lon = longitude;
var lat = latitude;
var hei = height;
var flagevalue = true;
//封装改变偏航角的方法
function diaoyong() {
heading = heading + Cesium.Math.toRadians(2);
var hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll);
var orientation = Cesium.Transforms.headingPitchRollQuaternion(
position,
hpr
);
return orientation;
}
function positionvalue() {
if (height - hei < 25 && flagevalue) {
hei -= 0.2;
position = Cesium.Cartesian3.fromDegrees(lon, lat, hei);
return position;
} else if (height - hei >= 0) {
hei += 0.2;
position = Cesium.Cartesian3.fromDegrees(lon, lat, hei);
flagevalue = false;
return position;
} else {
flagevalue = true;
}
}
var zhui = viewer.entities.add({
name: name,
position: new Cesium.CallbackProperty(positionvalue, false) /* position */,
orientation: new Cesium.CallbackProperty(diaoyong, false),
model: {
uri: "/model/zhui.glb", // 模型文件的路径
scale: 40, // 模型的缩放比例
minimumPixelSize: 50, // 模型的最小像素大小
maximumScale: 200, // 模型的最大缩放比例
color: Cesium.Color.DARKCYAN.withAlpha(0.5),
},
});
}
/**
* @description: cesium 立体墙创建(高度有动画)
* @param {any} viewer :实体
* @param {Array} _positions :经纬度 [lon,lat,lon,lat....]
*/
function drawWall(viewer, _positions) {
const maximumHeights = Array(_positions.length / 2).fill(600);
const minimumHeights = Array(_positions.length / 2).fill(60);
const positions = Cesium.Cartesian3.fromDegreesArray(_positions);
const dayMaximumHeights = Array(minimumHeights.length).fill(600);
const wallEntity = new Cesium.Entity({
wall: {
positions,
maximumHeights: new Cesium.CallbackProperty(() => {
for (let i = 0; i < minimumHeights.length; i++) {
dayMaximumHeights[i] += maximumHeights[i] * 0.004;
if (dayMaximumHeights[i] > maximumHeights[i]) {
dayMaximumHeights[i] = minimumHeights[i];
}
}
return dayMaximumHeights;
}, false),
minimumHeights,
material: Cesium.Color.BLUE.withAlpha(0.3),
heightReference: Cesium.HeightReference.NONE,
},
});
viewer.entities.add(wallEntity);
}
/**
* @description: 全屏报警状态(紧急状态)
* @param {any} viewer :实体
*/
function emergencyAlarm(viewer) {
const fragmentShaderSource = `
precision highp float;
float sdRoundBox(in vec2 p, in vec2 b, in vec4 r)
{
r.xy = (p.x > 0.0) ? r.xy : r.zw;
r.x = (p.y > 0.0) ? r.x : r.y;
vec2 q = abs(p) - b + r.x;
return min(max(q.x, q.y), 0.0) + length(max(q, 0.0)) - r.x;
}
uniform sampler2D colorTexture;
varying vec2 v_textureCoordinates;
void main(void)
{
vec2 p = (gl_FragCoord.xy / (czm_viewport.zw / 2.0)) - 1.0;
float d = sdRoundBox(p, vec2(0.8, 0.7), vec4(0.1));
vec3 col = mix(vec3(0.0), vec3(1.0, 0.0, 0.0) * abs(sin(czm_frameNumber * 9.5)) * (d / 0.35), d > 0.0 ? 1.0 : 0.0);
vec3 originalColor = texture2D(colorTexture, v_textureCoordinates).rgb;
gl_FragColor = mix(vec4(originalColor, 1.0) * 2.0, vec4(col, 1.0), 0.5);
}
`;
viewer.scene.postProcessStages.add(
new Cesium.PostProcessStage({
fragmentShader: fragmentShaderSource,
})
);
}
/**
* @description: 取消报警效果
* @param {any} viewer :实体
*/
function cancelEmergencyAlarm(viewer) {
const postProcessStages = viewer.scene.postProcessStages;
const stages = postProcessStages._stages;
const fragmentShaderSource = `
precision highp float;
float sdRoundBox(in vec2 p, in vec2 b, in vec4 r)
{
r.xy = (p.x > 0.0) ? r.xy : r.zw;
r.x = (p.y > 0.0) ? r.x : r.y;
vec2 q = abs(p) - b + r.x;
return min(max(q.x, q.y), 0.0) + length(max(q, 0.0)) - r.x;
}
uniform sampler2D colorTexture;
varying vec2 v_textureCoordinates;
void main(void)
{
vec2 p = (gl_FragCoord.xy / (czm_viewport.zw / 2.0)) - 1.0;
float d = sdRoundBox(p, vec2(0.8, 0.7), vec4(0.1));
vec3 col = mix(vec3(0.0), vec3(1.0, 0.0, 0.0) * abs(sin(czm_frameNumber * 9.5)) * (d / 0.35), d > 0.0 ? 1.0 : 0.0);
vec3 originalColor = texture2D(colorTexture, v_textureCoordinates).rgb;
gl_FragColor = mix(vec4(originalColor, 1.0) * 2.0, vec4(col, 1.0), 0.5);
}
`;
for (let i = stages.length - 1; i >= 0; i--) {
const stage = stages[i];
if (stage.fragmentShader === fragmentShaderSource) {
postProcessStages.remove(stage);
}
}
}
/**
* @description: 发射线创建,可以用做信号传递
* @param {any} viewer :实体
* @param {Number} _num :数量
*/
function launchLine(viewer, _num) {
// 获取viewer对象
// const viewer = viewer;
/**
* @description: 抛物线构造函数
* @param {*} startPosition 起始位置 [lon, lat]
* @param {*} endPosition 结束位置 [lon, lat]
* @param {*} height 抛物线顶点高度
* @param {*} count 抛物线点的数量
* @return {*} 抛物线点的数组
*/
// 抛物线起始位置、结束位置和高度
const startPosition = [120.277754, 31.533728];
const endPosition = [120.277754, 31.628061];
const height = 5000;
// 创建抛物线飞线效果
const siglePositions = parabola(startPosition, endPosition, height);
for (let i = 0; i < _num; i++) {
const polylineEntity = viewer.entities.add({
polyline: {
positions: new Cesium.CallbackProperty(function () {
const currentTime = Cesium.JulianDate.now().secondsOfDay;
const timeOffset = i * 0.5; // 每个线段的时间偏移量
const index = Math.floor((currentTime + timeOffset) % 50);
return siglePositions.slice(0, index + 1);
}, false),
width: 5,
material: new Cesium.PolylineGlowMaterialProperty({
glowPower: 0.2,
color: Cesium.Color.RED,
}),
},
});
}
// 创建轨迹线
viewer.entities.add({
polyline: {
positions: siglePositions,
width: 3,
material: new Cesium.Color(1.0, 1.0, 0.0, 0.2),
},
});
/**
* @description: 抛物线构造函数(参考开源代码)
* @param {*}
* @return {*}
*/
function parabola(startPosition, endPosition, height = 0, count = 50) {
//方程 y=-(4h/L^2)*x^2+h h:顶点高度 L:横纵间距较大者
let result = [];
height = Math.max(+height, 100);
count = Math.max(+count, 50);
let diffLon = Math.abs(startPosition[0] - endPosition[0]);
let diffLat = Math.abs(startPosition[1] - endPosition[1]);
let L = Math.max(diffLon, diffLat);
let dlt = L / count;
if (diffLon > diffLat) {
let delLat = (endPosition[1] - startPosition[1]) / count;
if (startPosition[0] - endPosition[0] > 0) {
dlt = -dlt;
}
for (let i = 0; i < count; i++) {
let h =
height -
(Math.pow(-0.5 * L + Math.abs(dlt) * i, 2) * 4 * height) /
Math.pow(L, 2);
let lon = startPosition[0] + dlt * i;
let lat = startPosition[1] + delLat * i;
let point = new Cesium.Cartesian3.fromDegrees(lon, lat, h);
result.push(point);
}
} else {
let delLon = (endPosition[0] - startPosition[0]) / count;
if (startPosition[1] - endPosition[1] > 0) {
dlt = -dlt;
}
for (let i = 0; i < count; i++) {
let h =
height -
(Math.pow(-0.5 * L + Math.abs(dlt) * i, 2) * 4 * height) /
Math.pow(L, 2);
let lon = startPosition[0] + delLon * i;
let lat = startPosition[1] + dlt * i;
let point = new Cesium.Cartesian3.fromDegrees(lon, lat, h);
result.push(point);
}
}
var pon = new Cesium.Cartesian3.fromDegrees(
endPosition[0],
endPosition[1],
0
);
result.push(pon);
return result;
}
}
/**
* @description: 旋转材质
* @param {*} instance :实体
* @param {*} _stRotation : 初始材质旋转角度
* @param {*} _amount :旋转角度变化量
*/
function rotateMaterial(instance, _stRotation, _amount) {
instance.stRotation = new Cesium.CallbackProperty(function () {
_stRotation += _amount;
if (_stRotation >= 360 || _stRotation <= -360) {
_stRotation = 0;
}
return Cesium.Math.toRadians(_stRotation);
}, false);
}
/**
* @description: 等高线
* @param {any} viewer :实体
*/
function contourLine(viewer) {
let globe = viewer.scene.globe;
let contourUniforms = {};
// 使用等高线材质
let material = Cesium.Material.fromType("ElevationContour");
contourUniforms = material.uniforms;
// 线宽2.0px
contourUniforms.width = 2.0;
// 高度间隔为150米
contourUniforms.spacing = 150;
contourUniforms.color = Cesium.Color.RED;
// 设置材质
globe.material = material;
}
/**
* @description: 开启黑白视角
* @param {any} viewer :实体
*/
function blackWhite(viewer) {
var collection = viewer.scene.postProcessStages;
var silhouette = collection.add(
Cesium.PostProcessStageLibrary.createBlackAndWhiteStage()
);
silhouette.enabled = true;
silhouette.uniforms.gradations = 15.0;
}
/**
* @description: 开启夜视效果
* @param {any} viewer :实体
*/
function nightVision(viewer) {
var collection = viewer.scene.postProcessStages;
var silhouette = collection.add(
Cesium.PostProcessStageLibrary.createNightVisionStage()
);
silhouette.enabled = true;
}
/**
* @description: 开启轮廓
* @param {any} viewer :实体
*/
function makeContour(viewer) {
var collection = viewer.scene.postProcessStages;
var silhouette = collection.add(
Cesium.PostProcessStageLibrary.createSilhouetteStage()
);
silhouette.enabled = true;
silhouette.uniforms.color = Cesium.Color.YELLOW;
}
/**
* 在Cesium中以动画效果将实体模型移动到目标位置
* @param {Viewer} viewer - Cesium的Viewer实例
* @param {Cartesian3} startPosition - 实体模型的起始位置
* @param {Cartesian3} endPosition - 实体模型的目标位置
* @param {boolean} isid - 是否根据ID删除匹配的实体
*/
function moveModelToPosition(viewer, startPosition, endPosition, isid) {
if (isid) {
const modelEntity = viewer.entities.getById("无人机mmm");
if (modelEntity) {
viewer.entities.remove(modelEntity); // 删除匹配的实体
}
}
let factor = 0;
const interpolatedPosition = new Cesium.Cartesian3(); // 创建一个用于插值结果的Cartesian3对象
const cartesian = new Cesium.Cartesian3(
startPosition.x,
startPosition.y,
startPosition.z
);
const cartesian2 = new Cesium.Cartesian3(
endPosition.x,
endPosition.y,
endPosition.z
);
// 将Cartesian3转换为Cartographic
const cartographic = Cesium.Cartographic.fromCartesian(cartesian);
const cartographic2 = Cesium.Cartographic.fromCartesian(cartesian2);
// 提取经纬度值
const longitude = Cesium.Math.toDegrees(cartographic.longitude);
const longitude2 = Cesium.Math.toDegrees(cartographic2.longitude);
const latitude = Cesium.Math.toDegrees(cartographic.latitude);
const latitude2 = Cesium.Math.toDegrees(cartographic2.latitude);
// 根据距离和时间推算出速度
let arrnum = getDistance(longitude, latitude, longitude2, latitude2);
let juli = arrnum / 5000;
// 添加模型
const vehicleEntity = viewer.entities.add({
id: "无人机mmm",
position: new Cesium.CallbackProperty(function () {
if (factor > 5000) {
factor = 5000;
}
factor += juli;
// 动态更新位置
return Cesium.Cartesian3.lerp(
startPosition,
endPosition,
factor / 5000.0,
interpolatedPosition
); // 使用预先创建的Cartesian3对象
}, false),
model: {
uri: "/model/drone/aviation_航空模型.glb",
scale: 100.0,
},
orientation: Cesium.Transforms.headingPitchRollQuaternion(
startPosition,
new Cesium.HeadingPitchRoll(
getHeading(endPosition, startPosition), // 设置这个属性即可(顺时针旋转的角度值)
getPitch(endPosition, startPosition),
Cesium.Math.toRadians(0)
)
),
});
}
/**
* 计算两个经纬度坐标之间的距离
* @param {number} lng_a - 第一个点的经度
* @param {number} lat_a - 第一个点的纬度
* @param {number} lng_b - 第二个点的经度
* @param {number} lat_b - 第二个点的纬度
* @returns {number} - 两点之间的距离(单位:米)
*/
function getDistance(lng_a, lat_a, lng_b, lat_b) {
const earthRadius = 6371000; // 地球半径(单位:米)
const deltaLng = toRadians(lng_b - lng_a);
const deltaLat = toRadians(lat_b - lat_a);
const a =
Math.sin(deltaLat / 2) * Math.sin(deltaLat / 2) +
Math.cos(toRadians(lat_a)) *
Math.cos(toRadians(lat_b)) *
Math.sin(deltaLng / 2) *
Math.sin(deltaLng / 2);
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
const distance = earthRadius * c;
return distance;
}
/**
* 将角度转换为弧度
* @param {number} degrees - 角度值
* @returns {number} - 弧度值
*/
function toRadians(degrees) {
return degrees * (Math.PI / 180);
}
/**
* 计算两个经纬度坐标之间的方位角(heading)
* @param {Cartesian3} pointA - 第一个点的Cartesian3坐标
* @param {Cartesian3} pointB - 第二个点的Cartesian3坐标
* @returns {number} - 两点之间的方位角(单位:弧度)
*/
function getHeading(pointA, pointB) {
//建立以点A为原点,X轴为east,Y轴为north,Z轴朝上的坐标系
// debugger
const transform = Cesium.Transforms.eastNorthUpToFixedFrame(pointA);
//向量AB
const positionvector = Cesium.Cartesian3.subtract(
pointB,
pointA,
new Cesium.Cartesian3()
);
//因transform是将A为原点的eastNorthUp坐标系中的点转换到世界坐标系的矩阵
//AB为世界坐标中的向量
//因此将AB向量转换为A原点坐标系中的向量,需乘以transform的逆矩阵。
const vector = Cesium.Matrix4.multiplyByPointAsVector(
Cesium.Matrix4.inverse(transform, new Cesium.Matrix4()),
positionvector,
new Cesium.Cartesian3()
);
//归一化
const direction = Cesium.Cartesian3.normalize(
vector,
new Cesium.Cartesian3()
);
//heading
const heading =
Math.atan2(direction.y, direction.x) - Cesium.Math.PI_OVER_TWO;
return Cesium.Math.TWO_PI - Cesium.Math.zeroToTwoPi(heading);
}
/**
* 计算两个经纬度坐标之间的俯仰角(pitch)
* @param {Cartesian3} pointA - 第一个点的Cartesian3坐标
* @param {Cartesian3} pointB - 第二个点的Cartesian3坐标
* @returns {number} - 两点之间的俯仰角(单位:弧度)
*/
function getPitch(pointA, pointB) {
let transfrom = Cesium.Transforms.eastNorthUpToFixedFrame(pointA);
const vector = Cesium.Cartesian3.subtract(
pointB,
pointA,
new Cesium.Cartesian3()
);
let direction = Cesium.Matrix4.multiplyByPointAsVector(
Cesium.Matrix4.inverse(transfrom, transfrom),
vector,
vector
);
Cesium.Cartesian3.normalize(direction, direction);
return Cesium.Math.PI_OVER_TWO - Cesium.Math.acosClamped(direction.z);
}
/* 获取到当前经纬度并添加标示 */
function addmarked(viewer) {
function getLatLngFromMouseClick(viewer) {
var handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
function runOnce(event) {
var cartesian = viewer.camera.pickEllipsoid(
event.position,
viewer.scene.globe.ellipsoid
);
if (cartesian) {
var cartographic = Cesium.Cartographic.fromCartesian(cartesian);
var longitude = Cesium.Math.toDegrees(cartographic.longitude);
var latitude = Cesium.Math.toDegrees(cartographic.latitude);
console.log("Clicked Longitude: " + longitude);
console.log("Clicked Latitude: " + latitude);
// 创建标记的位置(Cartesian3 或 Cartographic)
var position = Cesium.Cartesian3.fromDegrees(longitude, latitude);
// 创建一个标记实体
var markerEntity = viewer.entities.add({
name: "yuanpion",
position: position,
point: {
pixelSize: 10,
color: Cesium.Color.RED,
outlineColor: Cesium.Color.WHITE,
outlineWidth: 2,
},
label: {
text: "经度:" + longitude + "\n" + "纬度:" + latitude,
font: "14px sans-serif",
fillColor: Cesium.Color.WHITE,
outlineColor: Cesium.Color.BLACK,
outlineWidth: 2,
style: Cesium.LabelStyle.FILL_AND_OUTLINE,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
pixelOffset: new Cesium.Cartesian2(0, -10),
},
});
// 移除事件处理程序,使其只运行一次
handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
}
}
handler.setInputAction(runOnce, Cesium.ScreenSpaceEventType.LEFT_CLICK);
}
getLatLngFromMouseClick(viewer);
}
export {
drawSector,
rotundity,
addfindList,
makeRotundity,
setViewValue,
quadrilateral,
gardenShape,
polygon,
setflyTo,
diffusion,
Polyline,
invertedTriangle,
drawWall,
emergencyAlarm,
cancelEmergencyAlarm,
launchLine,
rotateMaterial,
contourLine,
blackWhite,
nightVision,
makeContour,
moveModelToPosition,
addmarked,
};
cesium 效果
最新推荐文章于 2024-03-26 13:50:08 发布