首页 > 其他 > 详细

cesium 绘制台风(附代码)

时间:2021-04-02 14:49:00      阅读:41      评论:0      收藏:0      [点我收藏+]
台风的绘制,首要任务就是台风数据,没有数据,一切白搭,技术难点就台风圈绘制较为复杂,数据格式在文末
let Viewer ;
function showTFLJ(viewer,data) {//显示台风路径,包括台风圈
Viewer = viewer;
data.forEach(function (t) {
const positions = [];
        const position = [];
//对台风数据进行时间排序
let typhoonPoints = t.typhoonPoints.sort(function (a,b) {
return a.time-b.time;
});
//封装坐标点
typhoonPoints.forEach(function (p) {
positions.push(p.longitude*1);
positions.push(p.latitude*1);
positions.push(8000);
position.push(p);
})
//点画线
viewer.entities.add({
polyline: {
positions: Cesium.Cartesian3.fromDegreesArrayHeights(positions),//[113.5,14.4,113.7,14.3,113.9,14.2,114.1,14.1,114.3,14.0,114.5,13.9,114.7,13.9,115.0,13.8,115.2,13.8,115.4,13.7,115.6,13.7,115.8,13.7,116.1,13.6,116.3,13.6,116.5,13.5,116.6,13.4,116.8,13.4,116.9,13.3,117.0,13.3,117.1,13.3,117.2,13.3,117.3,13.3,117.4,13.3,117.6,13.1,117.8,13.0,117.9,13.0,118.1,12.9,118.2,12.8,118.4,12.7]
width: 1,//new Cesium.CallbackProperty(changeR3, false),
height:8000,
material: Cesium.Color.WHEAT.withAlpha(0.5)
},
});
//核心代码
position.forEach(function (p,index) {
const entity = viewer.entities.add({
describe:t.name+"_"+p.time+"_"+p.longitude+"/"+p.latitude+"_"
+p.speed+" 米/秒,"+p.power+"级("+p.strong+")"+"_"
+p.pressure+" 百帕"+"_"+p.moveSpeed+" 公里/小时,"+p.moveDir+"_"
+p.radius7+"|"+p.radius10+"|"+p.radius12+"_"+p.radius7Quad+"|"+p.radius10Quad+"|"+p.radius12Quad,//此处是为了展示明细信息,单击点弹框显示明细
position: Cesium.Cartesian3.fromDegrees(p.longitude*1,p.latitude*1,8001),
ellipse : {
semiMinorAxis : new Cesium.CallbackProperty(changeR1, false),//缩放按比例调整entity大小
semiMajorAxis : new Cesium.CallbackProperty(changeR1, false),//缩放按比例调整entity大小
height:8001,
material : Cesium.Color.BLUE.withAlpha(0.5)
}
});
//根据power 判断风力,展示不同颜色点
if(p.power*1<=7)//热带低压 TD
entity.ellipse.material = TD;
if(p.power*1>7 && p.power*1<=9)//热带风暴 TS
entity.ellipse.material = TS;
if(p.power*1>9 && p.power*1<=11)//强热带风暴 STS
entity.ellipse.material = STS;
if(p.power*1>11 && p.power*1<=13 )//台风 TY
entity.ellipse.material = TY;
if(p.power*1>13 && p.power*1<=15 )//强台风 STY
entity.ellipse.material = STY;
if(p.power*1>15 )//超强台风 SuperTY
entity.ellipse.material = SuperTY;

//核心,风圈的绘制
//画台风风圈的原理如下:以圆心为原点,以正北方向为0度,顺时针画点,1度为1个点,并连成线,并最终回到正北方向,形成封闭的多边形;然后再加以填充。由于台风半径分为东北、东南、西南、西北四个方向,每个方向距离圆心可能长度不一,于是就形成了有四个锯齿状的风圈。
if(index==position.length-1){//判断最后一个点,绘制 台风圈
let points = new Array();
if(p.radius7>0){//7级风圈
points = new Array();
getPoints([p.longitude*1,p.latitude*1], JSON.parse(p.radius7Quad).ne*1, 0);//东北方向
getPoints([p.longitude*1,p.latitude*1], JSON.parse(p.radius7Quad).se*1, 90);
getPoints([p.longitude*1,p.latitude*1], JSON.parse(p.radius7Quad).sw*1, 180);
getPoints([p.longitude*1,p.latitude*1], JSON.parse(p.radius7Quad).nw*1, 270);
if(points.length>0){
viewer.entities.add({
polygon: {
hierarchy: Cesium.Cartesian3.fromDegreesArray(points),
material: new Cesium.Color(242/255,205/255,65/255).withAlpha(0.2),
extrudedHeight: 1000,
outline: true,
outlineColor:new Cesium.Color(242/255,205/255,65/255),
outlineWidth:10
}
});
}
}
if(p.radius10>0){//10级风圈
points = new Array();
getPoints([p.longitude*1,p.latitude*1], JSON.parse(p.radius10Quad).ne*1, 0);//东北方向
getPoints([p.longitude*1,p.latitude*1], JSON.parse(p.radius10Quad).se*1, 90);
getPoints([p.longitude*1,p.latitude*1], JSON.parse(p.radius10Quad).sw*1, 180);
getPoints([p.longitude*1,p.latitude*1], JSON.parse(p.radius10Quad).nw*1, 270);
if(points.length>0){
viewer.entities.add({
polygon: {
hierarchy: Cesium.Cartesian3.fromDegreesArray(points),
material: new Cesium.Color(242/255,205/255,65/255).withAlpha(0.2),
extrudedHeight: 1000,
outline: true,
outlineColor:new Cesium.Color(242/255,205/255,65/255),
outlineWidth:20
}
});
}
}
if(p.radius12>0){//12级风圈
points = new Array();
getPoints([p.longitude*1,p.latitude*1], JSON.parse(p.radius12Quad).ne*1, 0);//东北方向
getPoints([p.longitude*1,p.latitude*1], JSON.parse(p.radius12Quad).se*1, 90);
getPoints([p.longitude*1,p.latitude*1], JSON.parse(p.radius12Quad).sw*1, 180);
getPoints([p.longitude*1,p.latitude*1], JSON.parse(p.radius12Quad).nw*1, 270);
if(points.length>0){
viewer.entities.add({
polygon: {
hierarchy: Cesium.Cartesian3.fromDegreesArray(points),
material: new Cesium.Color(242/255,205/255,65/255).withAlpha(0.2),
extrudedHeight: 1000,
outline: true,
outlineColor:new Cesium.Color(242/255,205/255,65/255),
outlineWidth:10
}
});
}
}

function getPoints(center, cradius, startAngle) {
let radius = cradius / 100;
let pointNum = 90;
let endAngle = startAngle + 90;
let sin,cos,x,y,angle;
for (let i = 0; i <= pointNum; i++) {
angle = startAngle + (endAngle - startAngle) * i / pointNum;
sin = Math.sin(angle * Math.PI / 180);
cos = Math.cos(angle * Math.PI / 180);
x = center[0] + radius * sin;
y = center[1] + radius * cos;
points.push(x,y);
}
}
const entity1 = viewer.entities.add({
position: Cesium.Cartesian3.fromDegrees(p.longitude*1,p.latitude*1,8000),
ellipse : {
semiMinorAxis : new Cesium.CallbackProperty(changeR2, false),//根据高度 缩放entity
semiMajorAxis : new Cesium.CallbackProperty(changeR2, false),//根据高度 缩放entity
height:8000,
material : Cesium.Color.BLUE
}
});
entity1.ellipse.material = new Cesium.ImageMaterialProperty({
image: new Cesium.CallbackProperty(drawCanvasImage, false),//这里是一个旋转的图标回调,做一个动态旋转效果
transparent: true
});
}
})
})

viewer.camera.flyTo({
destination: new Cesium.Cartesian3.fromDegrees(112.7383109598977, 25.658452600672697, 4200000),//相机飞入点
});
}

//展示台风明细,单击台风路径的点触发
function showTFMX(obj) {
    let DOM = document.getElementById("ZY-QX-ICON")
let c = new Cesium.Cartesian2(obj.v.mousePosition.x, obj.v.mousePosition.y);
update(c);
function update(c) {
let x = c.x - (DOM.offsetWidth) / 2;
let y = c.y - (DOM.offsetHeight) ;
DOM.style.top = y + ‘px‘;
DOM.style.left = x + ‘px‘;
DOM.style.display = "block";
}
obj.viewer.scene.postRender.addEventListener(function () {
let p = new Cesium.Cartesian3(obj.v.pickedFeature.id._position._value.x, obj.v.pickedFeature.id._position._value.y,obj.v.pickedFeature.id._position._value.z);
let c = Cesium.SceneTransforms.wgs84ToWindowCoordinates(obj.viewer.scene, p);
if(getIsHide()){//因为这里一直在刷新,可以通过setIsHide 来设置是否展示
update(c);
}else{
DOM.style.display = "none";
}
});
}
//监听单击
Ewater.SetClickEvent(viewer, function (e, v) {
    const describe = v.pickedFeature.id.describe;//上面给的明细信息
if (describe) {
CesiumTF.showTFMX({
viewer, e, v,
CurrentEnableBrand: true,
describe
});
CesiumTF.setIsHide(true);
}
});
后台封装:台风数据格式
public class TyphoonInfo {

@TableId(value="id")
String id;
@ApiModelProperty(value = "台风编码")
@TableField(value = "code")
String code;
@ApiModelProperty(value = "台风名称")
@TableField(value = "name")
String name;
@ApiModelProperty(value = "台风英文名称")
@TableField(value = "ename")
String ename;
@ApiModelProperty(value = "开始时间")
@TableField(value = "begin_time")
Date beginTime;

@ApiModelProperty(value = "结束时间")
@TableField(value = "end_time")
Date endTime;

@ApiModelProperty(value = "年度")
@TableField(value = "year")
String year;
@ApiModelProperty(value = "是否是当前台风")
@TableField(value = "is_current")
String isCurrent;
@ApiModelProperty(value = "台风路径列表")
@TableField(exist = false)
private List<TyphoonPoints> typhoonPoints;
}






public class TyphoonPoints {
@TableId(value = "id")
String id;
@ApiModelProperty(value = "台风编码")
@TableField(value = "code")
String code;
@ApiModelProperty(value = "时间")
@TableField(value = "time")
Date time;
@ApiModelProperty(value = "经度")
@TableField(value = "longitude")
String longitude;
@ApiModelProperty(value = "纬度")
@TableField(value = "latitude")
String latitude;

@ApiModelProperty(value = "级别")
@TableField(value = "strong")
String strong;

@ApiModelProperty(value = "最大风力")
@TableField(value = "power")
String power;

@ApiModelProperty(value = "最大风速")
@TableField(value = "speed")
String speed;

@ApiModelProperty(value = "中心气压")
@TableField(value = "pressure")
String pressure;

@ApiModelProperty(value = "移动速度")
@TableField(value = "move_Speed")
String moveSpeed;

@ApiModelProperty(value = "移动方向")
@TableField(value = "move_Dir")
String moveDir;

@ApiModelProperty(value = "7级风圈最大半径值")
@TableField(value = "radius7")
String radius7;

@ApiModelProperty(value = "10级风圈最大半径值")
@TableField(value = "radius10")
String radius10;

@ApiModelProperty(value = "12级风圈最大半径值")
@TableField(value = "radius12")
String radius12;

@ApiModelProperty(value = "7级风圈范围")
@TableField(value = "radius7_Quad")
String radius7Quad;

@ApiModelProperty(value = "10级风圈范围")
@TableField(value = "radius10_Quad")
String radius10Quad;

@ApiModelProperty(value = "12级风圈范围")
@TableField(value ="radius12_Quad")
String radius12Quad;
}

台风数据的获取,可以去网上抓取,网上很多台风数据,附最终效果图:

技术分享图片

 

 

 

 

 

 

cesium 绘制台风(附代码)

原文:https://www.cnblogs.com/cheng-ch/p/14610051.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!