画扇形
import * as Cesium from 'cesium'
/**
* 绘制扇形。
*
* @param {*} params: {
* olon // 扇形中心经度
* olat // 扇形中心纬度
* radius // 扇形半径
* fromAngle // 扇形起始角度(从正北开始计算,单位:度)
* toAngle // 扇形结束角度(从正北开始计算,单位:度)
* step // 每隔几度计算一次
* }
*/
function calculateSectorHierarchy(viewer, params) {
const points = []
const oCartesian3 = Cesium.Cartesian3.fromDegrees(params.olon, params.olat)
points.push(oCartesian3)
const step = typeof params.step === 'undefined' ? 1 : params.step
for (let angle = params.fromAngle; angle <= params.toAngle; angle += step) {
const point = calculatePointInSector(
viewer,
params.olon,
params.olat,
params.radius,
angle
)
points.push(point)
}
return points
}
/**
* 计算扇形弧线上的各点的坐标,以绘制完整的扇形。
*
* 该函数解决的问题:已知圆心、半径,设圆心与正北方向的连线为0°,按照顺时针方向角度递增,求指定角度下的圆上的点的坐标。
*
* 注意:该函数计算的扇形弧线上的点的坐标是基于地球这个椭球体的,而非某个平面。
*
* @param {*} olon 圆心经度
* @param {*} olat 圆心纬度
* @param {*} radius 圆半径(单位:米)
* @param {*} angle 角度(单位:°)
*/
function calculatePointInSector(viewer, olon, olat, radius, angle) {
angle = Cesium.Math.toRadians(90 - angle)
const webMercatorProjection = new Cesium.WebMercatorProjection(
viewer.scene.globe.ellipsoid
)
const oMercator = webMercatorProjection.project(
new Cesium.Cartographic(
Cesium.Math.toRadians(olon),
Cesium.Math.toRadians(olat),
0
)
)
const pMercator = new Cesium.Cartesian3(
oMercator.x + radius * Math.cos(angle),
oMercator.y + radius * Math.sin(angle),
0
)
const pCartographic = webMercatorProjection.unproject(pMercator)
return Cesium.Cartographic.toCartesian(pCartographic)
}
export { calculateSectorHierarchy}
根据经纬度方位距离计算点
let mapNumberUtil = {};
// 弧度转角度
mapNumberUtil.deg = function (rad) {
return (rad * 180) / Math.PI;
};
// 角度转弧度
mapNumberUtil.rad = function (deg) {
return (deg * Math.PI) / 180;
};
mapNumberUtil.getLonAndLat = function (lng, lat, brng, dist) {
// WGS-84 椭球体参数
let a = 6378137; // 长半径
let b = 6356752.3142; // 短半径
let f = 1 / 298.257223563; // 扁率
// 将输入经纬度、方位角转换为弧度
let lon1 = this.rad(lng);
let lat1 = this.rad(lat);
let alpha1 = this.rad(brng);
let sinAlpha1 = Math.sin(alpha1);
let cosAlpha1 = Math.cos(alpha1);
// 一些中间变量的计算
let tanU1 = (1 - f) * Math.tan(lat1);
let cosU1 = 1 / Math.sqrt(1 + tanU1 * tanU1);
let sinU1 = tanU1 * cosU1;
let sigma1 = Math.atan2(tanU1, cosAlpha1);
let sinAlpha = cosU1 * sinAlpha1;
let cosSqAlpha = 1 - sinAlpha * sinAlpha;
let uSq = (cosSqAlpha * (a * a - b * b)) / (b * b);
let A = 1 + (uSq / 16384) * (4096 + uSq * (-768 + uSq * (320 - 175 * uSq)));
let B = (uSq / 1024) * (256 + uSq * (-128 + uSq * (74 - 47 * uSq)));
// 迭代计算
let sigma = dist / (b * A);
let sigmaP = 2 * Math.PI;
while (Math.abs(sigma - sigmaP) > 1e-12) {
let cos2SigmaM = Math.cos(2 * sigma1 + sigma);
let sinSigma = Math.sin(sigma);
let cosSigma = Math.cos(sigma);
let deltaSigma =
B * sinSigma * (cos2SigmaM + (B / 4) * (cosSigma * (-1 + 2 * cos2SigmaM * cos2SigmaM) - (B / 6) * cos2SigmaM * (-3 + 4 * sinSigma * sinSigma) * (-3 + 4 * cos2SigmaM * cos2SigmaM)));
sigmaP = sigma;
sigma = dist / (b * A) + deltaSigma;
}
// 计算目标点的经纬度
let tmp = sinU1 * sinSigma - cosU1 * cosSigma * cosAlpha1;
let lat2 = Math.atan2(sinU1 * cosSigma + cosU1 * sinSigma * cosAlpha1, (1 - f) * Math.sqrt(sinAlpha * sinAlpha + tmp * tmp));
let lambda = Math.atan2(sinSigma * sinAlpha1, cosU1 * cosSigma - sinU1 * sinSigma * cosAlpha1);
let C = (f / 16) * cosSqAlpha * (4 + f * (4 - 3 * cosSqAlpha));
let L = lambda - (1 - C) * f * sinAlpha * (sigma + C * sinSigma * (cos2SigmaM + C * cosSigma * (-1 + 2 * cos2SigmaM * cos2SigmaM)));
// 计算目标点的经度和纬度,并返回结果
let revAz = Math.atan2(sinAlpha, -tmp); // 最终方位角
let lngLatObj = { lng: this.deg(lon1 + L), lat: this.deg(lat2) };
return lngLatObj;
};
图片
viewer.entities.add({
position: Cesium.Cartesian3.fromDegrees(), // 传递经纬度
billboard: {
scaleByDistance: new Cesium.NearFarScalar(1.5e2, 1, 30.0e6, 0),
image:, // 图片
color: Cesium.Color.WHITE.withAlpha(0.8),
// 高度
height: 50,
width: 50,
// 逆时针旋转
// rotation: 20,
// 大小是否以米为单位
sizeInMeters: false,
// 相对于坐标的垂直位置
// verticalOrigin: Cesium.VerticalOrigin.CENTER,
// // 相对于坐标的水平位置
// horizontalOrigin: Cesium.HorizontalOrigin.LEFT,
scale: 1.0,
show: true
},
// 这里可以挂载其他属性上去
})
多边形
viewer.entities.add({
polygon: {
hierarchy: {
positions: Cesium.Cartesian3.fromDegreesArray() // 传递经纬度
// holes: 图形内需要挖空的区域
// holes: [
// {
// positions: Cesium.Cartesian3.fromDegreesArray([
// 119,
// 32,
// 115,
// 34,
// 119,
// 40
// ])
// }
// ]
},
// 边框
outline: true,
// 边框颜色
outlineColor: Cesium.Color.BLUE, // WHITE: 白色
// 边框尺寸
outlineWidth: 2,
// 填充的颜色 withAlpha透明度
material: Cesium.Color.BLUE.withAlpha(0.3),
// 是否被提供的材质填充
fill: true,
// 恒定高度
height: 50,
// 显示在距相机距离处的属性
// distanceDisplayCondition: new Cesium.DistanceDisplayCondition(
// 100,
// 10000000
// ),
// 是否显示
show: true
},
})
圆
viewer.entities.add({
position: Cesium.Cartesian3.fromDegrees(), // 经纬度
ellipse: {
semiMinorAxis: radius * 1000,
semiMajorAxis: radius * 1000,
rotation: Cesium.Math.toRadians(-40.0),
// 边框
outline: true,
// 边框颜色
outlineColor: Cesium.Color.BLUE, // WHITE: 白色
// 边框尺寸
outlineWidth: 2,
// 填充颜色
material: Cesium.Color.BURLYWOOD.withAlpha(0.3),
outerWidth: 4,
stRotation: Cesium.Math.toRadians(90)
}
})
画线
viewer.entities.add({
polyline: {
positions: Cesium.Cartesian3.fromDegreesArray(), // 两个经纬度
// 宽度
width: 2,
// 线的颜色
material: color || this.material || Cesium.Color.BLUE.withAlpha(0.3),
// 流动的线
// material: new LineFlowMaterialProperty({
// color: new Cesium.Color(1.0, 1.0, 0.0, 0.8),
// // color: Cesium.Color.BLUE.withAlpha(0.3),
// speed: 10,
// percent: 0.1,
// gradient: 0.2
// }),
// 线的顺序
zIndex: 10,
// 是否显示
show: true
},
item, // 可以挂载自己需要的一些对象
})
使用动态的线条需要使用的函数
import * as Cesium from 'cesium'
export class LineFlowMaterialProperty {
constructor(options) {
this._definitionChanged = new Cesium.Event()
this._color = undefined
this._speed = undefined
this._percent = undefined
this._gradient = undefined
this.color = options.color
this.speed = options.speed
this.percent = options.percent
this.gradient = options.gradient
}
get isConstant() {
return false
}
get definitionChanged() {
return this._definitionChanged
}
getType(time) {
return Cesium.Material.LineFlowMaterialType
}
getValue(time, result) {
if (!Cesium.defined(result)) {
result = {}
}
result.color = Cesium.Property.getValueOrDefault(
this._color,
time,
Cesium.Color.RED,
result.color
)
result.speed = Cesium.Property.getValueOrDefault(
this._speed,
time,
5.0,
result.speed
)
result.percent = Cesium.Property.getValueOrDefault(
this._percent,
time,
0.1,
result.percent
)
result.gradient = Cesium.Property.getValueOrDefault(
this._gradient,
time,
0.01,
result.gradient
)
return result
}
equals(other) {
return (
this === other ||
(other instanceof LineFlowMaterialProperty &&
Cesium.Property.equals(this._color, other._color) &&
Cesium.Property.equals(this._speed, other._speed) &&
Cesium.Property.equals(this._percent, other._percent) &&
Cesium.Property.equals(this._gradient, other._gradient))
)
}
}
Object.defineProperties(LineFlowMaterialProperty.prototype, {
color: Cesium.createPropertyDescriptor('color'),
speed: Cesium.createPropertyDescriptor('speed'),
percent: Cesium.createPropertyDescriptor('percent'),
gradient: Cesium.createPropertyDescriptor('gradient')
})
// Cesium.LineFlowMaterialProperty = LineFlowMaterialProperty;
Cesium.Material.LineFlowMaterialProperty = 'LineFlowMaterialProperty'
Cesium.Material.LineFlowMaterialType = 'LineFlowMaterialType'
Cesium.Material.LineFlowMaterialSource = `
uniform vec4 color;
uniform float speed;
uniform float percent;
uniform float gradient;
czm_material czm_getMaterial(czm_materialInput materialInput) {
czm_material material = czm_getDefaultMaterial(materialInput);
vec2 st = materialInput.st;
float t = fract(czm_frameNumber * speed / 1000.0);
t *= (1.0 + percent);
float alpha = smoothstep(t - percent, t, st.s) * step(-t, -st.s);
alpha += gradient;
material.diffuse = color.rgb;
material.alpha = alpha;
return material;
}
`
Cesium.Material._materialCache.addMaterial(
Cesium.Material.LineFlowMaterialType,
{
fabric: {
type: Cesium.Material.LineFlowMaterialType,
uniforms: {
color: new Cesium.Color(1.0, 0.0, 0.0, 1.0),
speed: 10.0,
percent: 0.1,
gradient: 0.01
},
source: Cesium.Material.LineFlowMaterialSource
},
translucent: function(material) {
return true
}
}
)
请登录后查看回复内容