vue+openlayers 实现台风效果 ***
实现台风效果<img id="tfImg" src="../../public/editor-0.8s-47px.gif" /><!-- 台风hover信息 --><div id="tfHoverInfo"><!-- {{tf2HoverInfo}} --><div>强度:{{ tf2HoverInfo.vti }}</div>
·
实现台风效果
<img id="tfImg" src="../../public/editor-0.8s-47px.gif" />
<!-- 台风hover信息 -->
<div id="tfHoverInfo">
<!-- {{tf2HoverInfo}} -->
<div>强度:{{ tf2HoverInfo.vti }}</div>
<div>东经:{{ tf2HoverInfo.clongitude }}</div>
<div>北纬:{{ tf2HoverInfo.clatitude }}</div>
<div>风力:{{ tf2HoverInfo.foreWd }}</div>
<div>风速:{{ tf2HoverInfo.foreWs }}</div>
<div>移动速度:{{ tf2HoverInfo.cws }}</div>
</div>
<!-- 台风过警戒线提示 -->
<div id="tf2AlterInfo">
{{ tf2AlterInfo }}
</div>
<div class="ol-legend" title="图例" @click="showLenged"></div>
<transition name="lenged-fade">
<div class="legend-container" v-show="lengedFlag">
<img :src="this.tlpng" />
</div>
</transition>
#tfImg {
position: absolute;
top: -100px;
left: -100px;
z-index: 999999;
}
#tf2AlterInfo {
display: none;
position: absolute;
width: 120px;
height: 60px;
line-height: 60px;
padding: 10px;
text-align: center;
border-radius: 8px;
border: 1px solid gray;
color: red;
background-color: yellow;
font-size: 18px;
font-weight: bold;
}
#tfHoverInfo {
position: absolute;
z-index: 9999999;
border-radius: 6px;
background-color: whitesmoke;
padding: 15px;
display: none;
overflow: auto;
}
.ol-legend {
position: absolute;
bottom: 10px;
right: 280px;
z-index: 99999;
height: 22px;
width: 23px;
background-image: url("../../public/images/tl.png");
background-repeat: no-repeat;
background-size: 100% 100%;
cursor: pointer;
}
.legend-container {
position: absolute;
bottom: 40px;
right: 320px;
}
data(){
return {
//台风
alertLine24Turf: null,
alertLine48Turf: null,
//警戒线图层
warningLineLayer: null,
//绘制台风图层和source
tf2VecLayer: null,
tf2VecSource: null,
tf2HoverFlag: 0,
tf2HoverInfo: {
vti: "1",
clatitude: "2",
clongitude: "3",
cws: "4",
cpress: "5",
// pressure: "6",
// movespeed: "7"
},
oldTf2Feature: null,
tf2AlterInfo: "",
lengedFlag: false, //图例
}
}
mounted****
//初始化绘制台风相关变量
this.tf2VecSource = new VectorSource();
this.tf2VecLayer = new VectorLayer({
source: this.tf2VecSource,
});
this.map.addLayer(this.tf2VecLayer);
console.log("台风矢量添加完成");
//地图鼠标事件****
this.map.on("pointermove", (ev) => {
//台风事件
// this.tf2HoverFlag = 100;
if (this.tf2HoverFlag == 1) {
let pixel = ev.pixel;
let feature = this.map.forEachFeatureAtPixel(pixel, function (feature) {
return feature;
});
console.log(feature, "台风");
if (feature != undefined && feature.values_._self) {
this.oldTf2Feature = feature;
// console.log(feature.getStyle(), '台风');
// console.log(this.tfHoverInfo,"??");
this.tf2HoverInfo.vti = feature.values_._self.vti;
this.tf2HoverInfo.clongitude = feature.values_._self.clongitude;
this.tf2HoverInfo.clatitude = feature.values_._self.clatitude;
this.tf2HoverInfo.cws = feature.values_._self.cws;
let dom = document.querySelector("#tfHoverInfo");
let pixel = this.lonlat2pixel({
lon: parseFloat(feature.values_._self.clongitude),
lat: parseFloat(feature.values_._self.clatitude),
});
dom.style.display = "block";
dom.style.top = pixel[1] - 200 + "px";
dom.style.left = pixel[0] - 110 + "px";
let style = feature.getStyle();
//接下来圈变大
feature.setStyle(
new Style({
image: new CircleStyle({
fill: new Fill({
color: style.image_.fill_.color_, //'#ff0000',
}),
radius: 12,
}),
})
);
} else {
document.querySelector("#tfHoverInfo").style.display = "none";
if (this.oldTf2Feature) {
//恢复
let style = this.oldTf2Feature.getStyle();
this.oldTf2Feature.setStyle(
new Style({
image: new CircleStyle({
fill: new Fill({
color: style.image_.fill_.color_, //'#ff0000',
}),
radius: 4,
}),
})
);
}
}
}
});
this.map.setView(
new View({
center: fromLonLat([130, 15]),
zoom: 5,
})
);
methods***
//台风大圈画法
generalCurveFeature(olon, olat, r, startAng, endAng, interval) {
let mianArr = [];
for (let i = startAng; i < endAng; ) {
i += interval;
let clon = r * Math.sin((i * Math.PI) / 180);
let clat = r * Math.cos((i * Math.PI) / 180);
let ec = 6356755.0 + ((6378136.49 - 6356755.0) * (90 - olat)) / 90;
let ed = ec * Math.cos((olat * Math.PI) / 180);
let jlon = ((clon / ed + (olon * Math.PI) / 180) * 180) / Math.PI;
let jlat = ((clat / ec + (olat * Math.PI) / 180) * 180) / Math.PI;
let a11 = fromLonLat([jlon, jlat]);
mianArr.push(a11);
}
mianArr.push(fromLonLat([olon, olat]));
let featuremian = new Feature({
geometry: new Polygon([mianArr]),
});
return featuremian;
},
//经纬度坐标转屏幕坐标
lonlat2pixel(opt) {
console.log(opt, "数据数据");
let pmzb = this.map.getPixelFromCoordinate(
fromLonLat([opt.lon, opt.lat])
);
return pmzb;
},
// 根据 约定的 类型的索引 判别 底图 与 注记图 需要渲染的layer类型
JudgeBaseAndNoteByType(index) {
let map = [
["vec", "cva"],
["ter", "cta"],
["img", "cia"],
];
return map[index];
},
/*创建标注样式
*@param{object} feature 标注要素
*@return {object} 返回创建的标注样式对象
*/
createLabelStyle(feature) {
//返回一个样式
return new Style({
//文本样式
text: new Text({
textAlign: "center", //对齐方式
textBaseline: "middle", //文本基线
font: "normal 18px 微软雅黑", //字体样式
text: feature.get("name"), //文本内容
offsetY: 15, // Y轴偏置
fill: new Fill({
//填充样式
color: "#ffffff",
}),
backgroundFill: new Fill({
// 填充背景
color: [0, 0, 0, 0.6],
}),
padding: [2, 5, 2, 5],
}),
// 设置层级
zIndex: 199,
});
},
//台风绘制2*****
compassesTf() {
this.tf2HoverFlag = 1;
// console.log(this.typeFun);
const dataNum = this.typeFun; //模拟json
let pointsArr = dataNum;
let featureArr = [];
let lonlatArr = [];
let lonlatArr1 = [];
for (let i = 0; i < pointsArr.length; i++) {
let ponsition = [pointsArr[i].clongitude, pointsArr[i].clatitude];
lonlatArr.push(
fromLonLat([pointsArr[i].clongitude, pointsArr[i].clatitude])
);
lonlatArr1.push([pointsArr[i].clongitude, pointsArr[i].clatitude]);
//创建feature
let featurepoint = new Feature({
geometry: new Point(fromLonLat(ponsition)),
_self: pointsArr[i],
});
//设置feature的样式
featurepoint.setStyle(
new Style({
image: new CircleStyle({
fill: new Fill({
color: this.generalColorByTfLevel(pointsArr[i].strong), //'#ff0000',
}),
radius: 4,
}),
})
);
featureArr.push(featurepoint);
}
//连线
let tf2line = new Feature({
geometry: new LineString(lonlatArr),
});
tf2line.setStyle(
new Style({
stroke: new Stroke({
color: "#FF0000",
width: 2,
}),
})
);
//风圈
let windCircleFeature = new Feature({
geometry: new Point(lonlatArr[0]),
});
let markerStyle = new Style({
// 设置icon大小
image: new Icon({
scale: 0.8,
src: this.imgUrl4, //'editor-0.8s-47px.gif' //'/typhoon.png'
windCircleFeature.setStyle(markerStyle);
this.tf2VecSource.addFeatures(featureArr); //添加点
this.tf2VecSource.addFeature(tf2line); //添加线
this.tf2VecSource.addFeature(windCircleFeature); //添加台风
// console.log(toLonLat(lonlatArr[0]), 'lonlatArr[0]lonlatArr[0]lonlatArr[0]');
//绘制台风 风圈大画法
let center = toLonLat(lonlatArr[0]);
let f = this.generalCurveFeature(center[0], center[1], 150000, 0, 90, 0.5);
let f1 = this.generalCurveFeature(center[0], center[1], 100000, 70, 190, 0.5);
let f2 = this.generalCurveFeature(center[0], center[1],60000 , 170, 290, 0.5);
let f3 = this.generalCurveFeature(center[0], center[1],90000 , 250, 370, 0.5);
let mianSource = new VectorSource({ wrapX: false });
let mianLayer = new VectorLayer({
source: mianSource,
});
// 创建显示样式
var stylemian = new Style({
fill: new Fill({
color: "rgba(27, 181, 56)",
}),
});
var stylemian2 = new Style({
fill: new Fill({
color: "rgba(168,12,1)",
}),
});
var stylemian3 = new Style({
fill: new Fill({
color: "rgba(24,36,128)",
}),
});
var stylemian4 = new Style({
fill: new Fill({
color: "rgba(66,22,14)",
}),
});
f.setStyle(stylemian);
f1.setStyle(stylemian);
f2.setStyle(stylemian);
f3.setStyle(stylemian);
mianSource.addFeature(f);
mianSource.addFeature(f1);
mianSource.addFeature(f2);
mianSource.addFeature(f3);
this.map.addLayer(mianLayer);
//计时器
let flagIndex = 0;
let tfImgDom = document.querySelector("#tfImg");
let rot = 0;
let tempInterval = setInterval(() => {
flagIndex++;
if (flagIndex == lonlatArr.length) {
clearInterval(tempInterval);
}
rot += 60;
if (rot >= 360) {
rot = 0;
}
markerStyle = new Style({
// 设置icon大小
image: new Icon({
scale: 0.8,
src: this.imgUrl4, //'/typhoon.png', //'editor-0.8s-47px.gif' //'/typhoon.png'
rotation: (Math.PI / 180) * rot,
}),
});
// markerStyle.setRotation(Math.PI/180*rot);
windCircleFeature.setStyle(markerStyle); //添加风圈样式
//更新风圈坐标
let newGeometry = new Point(lonlatArr[flagIndex]);
windCircleFeature.setGeometry(newGeometry);
// console.log(lonlatArr1[flagIndex], 'ccccccccccc');
//警戒线提示
let tfPoint = this.$turf.point([
parseFloat(lonlatArr1[flagIndex][0]),
parseFloat(lonlatArr1[flagIndex][1]),
]);
// console.log(tfPoint, "tfPoint");
console.log("this.alertLine24Turf", this.alertLine24Turf);
let isAlert24 = this.$turf.booleanPointOnLine(
tfPoint,
this.alertLine24Turf,
{ ignoreEndVertices: false, epsilon: 3 }
);
if (isAlert24) {
console.log("已过24警戒线");
//经纬度坐标转屏幕坐标 tf2AlterInfo
let pixel = this.lonlat2pixel({
lon: lonlatArr1[flagIndex][0],
lat: lonlatArr1[flagIndex][1],
});
let dom = document.querySelector("#tf2AlterInfo");
dom.style.display = "block";
dom.style.top = pixel[1] + "px";
dom.style.left = pixel[0] + "px";
this.tf2AlterInfo = "已过24警戒线";
} else {
// document.querySelector("#tf2AlterInfo").style.display = 'none';
}
let isAlert48 = this.$turf.booleanPointOnLine(
tfPoint,
this.alertLine48Turf,
{ ignoreEndVertices: false, epsilon: 6 }
);
if (isAlert48) {
// console.log("过了48警戒线");
let pixel = this.lonlat2pixel({
lon: lonlatArr1[flagIndex][0],
lat: lonlatArr1[flagIndex][1],
});
let dom = document.querySelector("#tf2AlterInfo");
dom.style.display = "block";
dom.style.top = pixel[1] + "px";
dom.style.left = pixel[0] + "px";
this.tf2AlterInfo = "已过48警戒线";
}
}, 500);
// this.map.removeLayer(newGeometry);
//警戒线方法
this.cordonFun();
},
/*
*@description: 根据台风等级类型定义锚点的颜色
*/
getTypeColor(type) {
if (type == "TD") return "#02ff02";
else if (type == "TS") return "#0264ff";
else if (type == "STS") return "#fffb05";
else if (type == "TY") return "#ffac05";
else if (type == "STY") return "#f171f9";
else if (type == "Super TY") return "#fe0202";
else return "#02ff02";
},
//根据不同的台风强度设置不同的颜色
generalColorByTfLevel(name) {
let color = "#ff0000";
switch (name) {
case "热带风暴":
color = "blue";
break;
case "热带低压":
color = "green";
break;
case "强热带风暴":
color = "yellow";
break;
case "台风":
color = "orange";
break;
case "强台风":
color = "pink";
break;
case "超强台风":
color = "salmon";
break;
}
// console.log(color, "color");
return color;
},
/*
*@description: 添加警戒线
*/
cordonFun() {
// 警戒线图层
this.warningLineLayer = new VectorLayer({
source: new VectorSource(),
name: "警戒线",
});
this.map.addLayer(this.warningLineLayer);
console.log(1);
// 台风48小时警戒线
const line48 = new Feature({
geometry: new LineString([
fromLonLat([132, 34]),
fromLonLat([132, 15]),
fromLonLat([120, 0]),
fromLonLat([105, 0]),
]),
});
line48.setStyle(this.getLineStyle("#face55", true));
this.setTextLabel(
fromLonLat([132, 28]),
"48\n小\n时\n警\n戒\n线",
"#face55"
);
this.warningLineLayer.getSource().addFeature(line48);
// 台风24小时警戒线
const line24 = new Feature({
geometry: new LineString([
fromLonLat([127, 34]),
fromLonLat([127, 22]),
fromLonLat([119, 18]),
fromLonLat([119, 11]),
fromLonLat([113, 4.5]),
fromLonLat([105, 0]),
]),
});
line24.setStyle(this.getLineStyle("#e44f26", false));
this.setTextLabel(
fromLonLat([127, 28]),
"24\n小\n时\n警\n戒\n线",
"#e44f26"
);
this.warningLineLayer.getSource().addFeature(line24);
},
/*
*@description: 设置警戒线要素
*@author: zhangyangyang
*@date: 2022-02-20 18:14:05
*/
getLineStyle(color, lineDash) {
return new Style({
stroke: new Stroke({
color: color,
width: 1,
lineDash: lineDash ? [3, 3] : undefined,
}),
});
},
/*
*@description: 设置警戒线文字标注
*/
setTextLabel(coordinate, text, color) {
let feature = new Feature({
geometry: new Point(coordinate),
});
feature.setStyle(
new Style({
text: new TextStyle({
text: text,
font: "normal 12px 宋体",
offsetX: 10,
textAlign: "center",
textBaseline: "middle",
fill: new Fill({ color: color }),
}),
})
);
this.warningLineLayer.getSource().addFeature(feature);
},
更多推荐
已为社区贡献5条内容
所有评论(0)