http://typhoon.zjwater.gov.cn/default.aspx
首先先去别人的网站扒几个json文件下来测试。
绘制台风路径
/**
* 画出台风路径
* @param {fakeData} 通过json文件的假数据
* @param {diff} 新增的台风名字
*/
drawTyphoonPath: function (fakeData, diff) {
console.log(fakeData);
let data = fakeData.data[0];
// 设置 台风点的 线的 图层
const typhoonLayer = new VectorLayer({
source: new VectorSource(),
});
typhoonLayer.set(diff, true);
// 点 的 features
let featuresByPoint = [];
let pointEPSG = [];
// 取出point的 经纬度 用于根据数据点的坐标绘制点
for (let i = 0, len = data.points.length; i < len; i++) {
let curPointData = data.points[i];
let [lat, lng] = [curPointData.lat, curPointData.lng];
// fromLonLat 不设置第二个参数 默认转为EPSG3857
let position = fromLonLat([lng, lat]);
let featureByPoint = new Feature({
geometry: new Point(position),
});
let curStyle = new Style({
image: new CircleStyle({
radius: 3,
fill: new Fill({
color: this.diySetStyle(curPointData.strong),
}),
}),
});
featureByPoint.setStyle(curStyle);
featureByPoint.setId(i);
featuresByPoint.push(featureByPoint);
pointEPSG.push(position);
}
let featureByLine = new Feature({
geometry: new LineString(pointEPSG),
});
let lineStyle = new Style({
stroke: new Stroke({
color: "#000",
width: 1,
}),
fill: new Fill({
color: "#000",
width: 1,
}),
});
featureByLine.setStyle(lineStyle);
typhoonLayer.setZIndex(1002);
typhoonLayer.getSource().addFeatures(featuresByPoint);
typhoonLayer.getSource().addFeature(featureByLine);
this.map2d.addLayer(typhoonLayer);
console.log(fakeData);
},
- 这里讲述一下思路台风路径通常来说还是得根据台风的power去定义颜色的,或者是说级别去定义颜色,所以我们不能使用multiPoint 去一次性绘制所有的点再去连线,而是要一个一个的根据这个级别去生成颜色。所以我们的要素feature得再给他设置一个自定义设置的颜色。这里可以观察一下我去拿的json数据,根据strong去描述。顺带一提,我的map的坐标系使用的是EPSG:3857。所以得把这个经纬度转换一下。而fromLonLat这个函数接收一个coordinator,一个转换的EPSG,不指定的话默认就是3857。接着把这些features 加进去这个layer里面,在地图实例把这个layer增加进去。
/**
* 根据图例显示的颜色去设置展示 数据点的 颜色
* @param {powerDesc} 风的强度描述
*/
diySetStyle: function (powerDesc) {
let ret;
let colorMap = {
"热带风暴(TS)": "#58FAAC",
"强热带风暴(STS)": "#2E2EFE",
"台风(TY)": "#FA8258",
"热带低压(TD)": "#BF00FF",
"强台风(STY)": "#F7FE2E",
超强台风: "#fa3030",
};
for (let i in colorMap) {
if (i == powerDesc) {
ret = colorMap[i];
break;
}
}
return ret;
},
以上操作我们已经可以绘制台风路径了,我们可以把上述的操作意为添加,而在复选框中我们需要做的是监听变化。如何监听这个变化?我们需要保存这个变化的上一次状态,去比对这次的结果是添加还是删除。然后决定执行什么逻辑。
复选框change
// 选择台风展示 可以再这里
selectTyphoon: async function (ev) {
// 前端发送一个约定好的名字 后端返回通过该名字查询的台风数据
// 这里我已经对请求方法做了处理
let diffJson = this.diffJudge(ev);
// 只是添加台风路径 没有删除操作
if (diffJson.status == "insert") {
let layers = this.map2d.getLayers();
// 检测是否已经存在该图层 只是被隐藏起来了
for (let i = 0, len = layers.getLength(); i < len; i++) {
let curItem = layers.item(i);
if (curItem.get(diffJson.diff) == true) {
curItem.setVisible(true);
return;
}
}
let data = await testGetTyphoonData(diffJson.diff);
this.drawTyphoonPath(data, diffJson.diff);
} else {
this.deleteTyphoonPath(diffJson.diff);
}
},
/**
* 判断当前存储的已经有的台风与新增加选项的差别
* @param {allOptions} 选项卡中的值
*/
diffJudge: function (allOptions) {
let diff = null;
let status = "";
let saveArr = this.typhoonNameArray;
let saveLen = this.typhoonNameArray.length;
let optionsLen = allOptions.length;
if (saveLen < optionsLen) {
for (let i = 0; i < optionsLen; i++) {
let curName = allOptions[i];
if (saveArr.indexOf(curName) == -1) {
saveArr.push(curName);
diff = curName;
status = "insert";
}
}
} else {
for (let i = 0; i < saveLen; i++) {
let curName = saveArr[i];
if (allOptions.indexOf(curName) == -1) {
diff = curName;
status = "delete";
}
}
}
console.log(allOptions.length, this.typhoonNameArray.length);
// 保存上一个状态 没这个会报错。
this.typhoonNameArray = allOptions;
return { diff, status };
},
/**
* 伪删除台风路径
* 不删除图层 主要是避免用户来回点击产生性能开销,隐藏即可。
* @param {name} 台风layer路径的名字
*/
deleteTyphoonPath: function (name) {
let layers = this.map2d.getLayers();
for (let i = 0, len = layers.getLength(); i < len; i++) {
let curItem = layers.item(i);
if (curItem.get(name) == true) {
curItem.setVisible(false);
}
}
},
-
详细说明上面代码的逻辑:首先比对我们保存的变量(ps:这个变量保留上一次复选框的状态),如果保存的变量的length 小于复选框的length 说明我们的复选框是添加的操作,然后找出这个新添加的名字,返回一个json格式{ diff 表示 差别的名字, status 表示当前的操作是添加还是 删除 }。
-
我们应该不需要他重复生成图层,因为这个数据一般是不会变更的。我们只需要把图层显示或者隐藏。怎么做?添加的逻辑是:通过给图层设置一个独一无二的名字,接着判断该图层是否存在,如果存在,那么我们只需要把它显示,如果不,那么我们就生成一个新的图层。删除的逻辑是:获取所有的图层,找到那个图层,如果图层的设定的key 为 true 设置visible为false。
效果