目录

1、台风路径信息准备与添加

1.1 数据准备,这里可以从中央气象台台风网抓取数据http://typhoon.nmc.cn/web.html

1.2 添加地图信息

2、添加台风风圈

1、使用坐标转换计算

2、使用turf.js计算台风风圈范围

3、台风路径的播放效果


1、台风路径信息准备与添加

1.1 数据准备,这里可以从中央气象台台风网抓取数据http://typhoon.nmc.cn/web.html

1.2 添加地图信息

添加台风预报路径

 function addTyLine(map, typData) {// 最后的点位添加编号名称typData.points[typData.points.length - 1].forecast.forEach((element, index) => {let coordList = [];element.forecastpoints.map(item => {coordList.push([Number(item.lng), Number(item.lat)]);});if (!map.getSource(`${typData.tfid}_typhon_route_line_${element.tm}`)) {map.addSource(`${typData.tfid}_typhon_route_line_${element.tm}`, {type: 'geojson',data: {type: 'Feature',properties: {},geometry: {type: 'LineString',coordinates: coordList,},},});}if (!map.getLayer(`typhon_route_${typData.tfid}_${index}`)) {map.addLayer({id: `typhon_route_${typData.tfid}_${index}`,type: 'line',source: `${typData.tfid}_typhon_route_line_${element.tm}`,layout: {'line-join': 'round','line-cap': 'round',},paint: {'line-color': '设定颜色','line-width': 2,'line-dasharray': [0.005, 3],},});}});
}

根据数据的格式来整理成geojson添加

预报站点信息、已测路径信息、已测站点信息同理添加

2、添加台风风圈

关于台风风圈,已知的数据有台风中心点以及台风半径,而台风半径又分为西北、西南、东南、东北四个方位角,这里在网上搜集了两种方法:

1、使用坐标转换计算

已知的中心点坐标为wgs84投影类型,也就是经纬度,需将其转换为投影坐标系来计算距离,再根据距离将其转换为经纬度来添加

let coords_7 = getCircleCoords(coordList[time], radiusData);map.addSource(`currentFill_${typData.tfid}`, {type: 'geojson',data: {type: 'Feature',properties: {name: typData.name,radius: '7',},geometry: {type: 'Polygon',coordinates: coords_7,},},});map.addLayer({id: `currentFill_${typData.tfid}`,source: `currentFill_${typData.tfid}`,type: 'fill',paint: {'fill-color': ['match', ['get', 'radius'], '7', '#ffff00', '10', '#ffa911', '#ff5341'],'fill-opacity': 0.2,'fill-outline-color': ['match', ['get', 'radius'], '7', '#ffff00', '10', '#ffa911', '#ff5341'],
},});getCircleCoords(center, radiusData) {//radiusData = {// ne: 100,//nw: 120,//sw: 120,//se: 10,//};center = proj4(proj4('EPSG:4326'), proj4('EPSG:3857'), center);let _coords = [];let _angInterval = 6;let _pointNums = 360 / (_angInterval * 4);let quadrant = {// 逆时针算角度'0': 'ne','1': 'nw','2': 'sw','3': 'se'};for (let i = 0; i < 4; i++) {let _r = parseFloat(radiusData[quadrant[i]]) * 1000; // 单位是kmif (!_r) _r = 0;for (let j = i * _pointNums; j <= (i + 1) * _pointNums; j++) {let _ang = _angInterval * j;let x = center[0] + _r * Math.cos((_ang * Math.PI) / 180);let y = center[1] + _r * Math.sin((_ang * Math.PI) / 180);var coord = proj4(proj4('EPSG:3857'), proj4('EPSG:4326'), [x, y]);_coords.push(coord);}}return [_coords];
}

传入的radiusData  需包含四个半径,格式如上;

proj4.js是坐标系转换通用的库,需单独引入;

以上方法可行,但是算出来的台风风圈经过验证存在一点误差,所以这里介绍另外一种使用turf.js计算的方法,算出来的风圈范围跟官网一致;

2、使用turf.js计算台风风圈范围

drawTyphoonCircle(p, radiusData) {var center = turf.point(p);let quadrant = {// 逆时针算角度0: 'ne',1: 'sw',2: 'se',3: 'nw',};if (radiusData[quadrant[0]]) {var options = { number: 2048 };var arc_ne = turf.lineArc(center, radiusData[quadrant[0]], 0, 89.9, options);var arc_se = turf.lineArc(center, radiusData[quadrant[3]], 90, 179.9, options);var arc_sw = turf.lineArc(center, radiusData[quadrant[2]], 180, 269.9, options);var arc_nw = turf.lineArc(center, radiusData[quadrant[1]], 270, 360.1, options);var arcs = [];arcs.push(arc_ne, arc_se, arc_sw, arc_nw);var typhoonCircleCoords = [];for (var i = 0; i < arcs.length; i++) {var rawCoords1 = arcs[i].geometry.coordinates;for (var j = 0; j < rawCoords1.length; j++) {typhoonCircleCoords.push(rawCoords1[j]);}}var lineAll = turf.lineString(typhoonCircleCoords);var typhoonCirclePolygon = turf.lineToPolygon(lineAll);console.log('typhoonCirclePolygon', typhoonCirclePolygon);return typhoonCirclePolygon;} else {return;}}

这里返回直接是geojson,

3、台风路径的播放效果

设置定时器,对geojson数据源定时修改,用到的核心方法是    map.getSource(`currentPoint`).setData(geojson);记得动画播放结束后要clearInterval()哦

let time = 0
updateSource[typData.tfid] = setInterval(async () => {time++;if (!typData.points[time]) {clearInterval(updateSource[typData.tfid]);updateSource[typData.tfid] = null;return;}radiusSeven = typData.points[time]?.radius7.split('|');radiusData = {ne: radiusSeven[0],nw: radiusSeven[1],sw: radiusSeven[2],se: radiusSeven[3],};// let coords_7 = getCircleCoords(coordList[time], radiusData);let coords_7 = drawTyphoonCircle(coordList[time], radiusData);const geojson_7 = await {type: 'FeatureCollection',features: [{type: 'Feature',geometry: {type: 'Polygon',coordinates: coords_7?.geometry?.coordinates,},properties: {tfid: typData.tfid,radius: '7',},},],};radiusTen = typData.points[time].radius10.split('|');radiusTenData = {ne: radiusTen[0],nw: radiusTen[1],sw: radiusTen[2],se: radiusTen[3],};let coords_10 = drawTyphoonCircle(coordList[time], radiusTenData);const geojson_10 = await {type: 'FeatureCollection',features: [{type: 'Feature',geometry: {type: 'Polygon',coordinates: coords_10?.geometry?.coordinates,},properties: {name: typData.name,radius: '10',},},],};let radiusTwelve = typData.points[time].radius12.split('|');let radiusTwelveData = {ne: radiusTwelve[0],nw: radiusTwelve[1],sw: radiusTwelve[2],se: radiusTwelve[3],};let coords_12 = drawTyphoonCircle(coordList[time], radiusTwelveData);const geojson_12 = await {type: 'FeatureCollection',features: [{type: 'Feature',geometry: {type: 'Polygon',coordinates: coords_12?.geometry?.coordinates,},properties: {name: typData.name,radius: '12',},},],};const geojson = await {type: 'FeatureCollection',features: [{type: 'Feature',geometry: {type: 'Point',coordinates: coordList[time],},},],};try {if (!coordList[time] || !typData.points[time]) {clearInterval(updateSource[typData.tfid]);updateSource[typData.tfid] = null;return;}map.getSource(`currentPoint_${typData.tfid}`).setData(geojson);map.getSource(`currentFill_${typData.tfid}`).setData(geojson_7);map.getSource(`currentFill_10_${typData.tfid}`).setData(geojson_10);map.getSource(`currentFill_12_${typData.tfid}`).setData(geojson_12);} catch (err) {// If the updateSource interval is defined, clear the interval to stop updating the source.if (updateSource) {clearInterval(updateSource[typData.tfid]);updateSource[typData.tfid] = null;}throw new Error(err);}}, 100);

类似台风路径的播放效果官网上也有所介绍,https://docs.mapbox.com/mapbox-gl-js/example/animate-point-along-route/其里面的核心内容就是设置定时器更新数据源 ,当然数据源的要求是geojson, map.getSource('pointSourceName').setData(pointGeojson);

使用mapbox 绘制台风风圈、台风路径相关推荐

  1. 中国台风计算机,台风丹娜丝或是今年以来最怪的台风了,超级计算机:不知道登中国哪里...

    原标题:台风丹娜丝或是今年以来最怪的台风了,超级计算机:不知道登中国哪里 7月17日上午,今年第5号台风丹娜丝继续在西太平洋上活动,从高清可见光卫星云图上看,它的个头仍然相当广阔,从南海到菲律宾以东都 ...

  2. html path 图标,Clippy – 轻松绘制 CSS clip-path 裁剪路径工具

    Clippy – 轻松绘制 CSS clip-path 裁剪路径工具 4月 13, 2016 评论 Sponsor Clippy 是一个 CSS clip-atch 属性绘制工具,使用它可以轻松绘制不 ...

  3. SwiftUI之深入解析如何绘制徽章视图的路径和形状

    一.创建徽章视图 创建徽章前需要使用 SwiftUI 的矢量绘画 API 创建一个徽章视图: 选择文件 -> 新建 -> 文件,然后从 iOS 文件模板列表中选择 SwiftUI View ...

  4. OL4两种绘制台风圈方式的比较

    前言:今天在一个群里面看到台风圈的,感觉很好奇,就想着能否用canvas结合OL4实现下,何为台风圈先来张图: 一.实现原理 1.先画上半圆 2.在下半圆 3.最后画半圆相接线 关于canvas画圆弧 ...

  5. Android中绘制简单几何图形和路径Path

    背景 我的博客:http://zhangsunyucong.top 马上就到2018年过年了,然后我又刚好有兴致,就来玩玩Android中的简单几何图形的绘制和使用Path类来绘制路径. Path和C ...

  6. 【MAPBOX基础功能】21、mapbox绘制自动旋转的图标

    前言 官网指引,生成accesstoken,下载相关依赖请翻阅[https://blog.csdn.net/weixin_44402694/article/details/125414381?spm= ...

  7. 【MAPBOX基础功能】09、mapbox绘制线图层并进行添加、删除、更新、显隐等操作

    前言 官网指引,生成accesstoken,下载相关依赖请翻阅[https://blog.csdn.net/weixin_44402694/article/details/125414381?spm= ...

  8. 【MAPBOX基础功能】11、mapbox绘制symbol icon图层并进行添加、删除、更新、显隐等操作

    前言 官网指引,生成accesstoken,下载相关依赖请翻阅[https://blog.csdn.net/weixin_44402694/article/details/125414381?spm= ...

  9. 绘制西北太平洋台风频数分布填色图

    研究台风路径和影响,除了直接绘制台风路径,我们还往往想知道研究的台风在海上各个经纬度的频数分布,并直观展示在地图上. 之前和大家交流过如何从台风路径数据集里提取指定条件的台风(用pandas库提取IB ...

最新文章

  1. JDBC 实例--JDBC通过工具类DBUtil连接到数据库,让我们不再恐惧操作数据库
  2. 最初学习ASP.net的时候常会遇到的问题
  3. Android WebView 和 javaScript的互相调用(二)
  4. CososJS学习笔记(1) 环境配置(填坑版,让你少走弯路!)
  5. 【STL源码剖析读书笔记】【第5章】关联式容器之set、map、multiset和multimap
  6. 带你学python基础:字符串
  7. 【Kafka】Kafka如何开启SSL 控制台消费与生产 代码消费与生产
  8. 【Dubbo源码阅读系列】服务暴露之本地暴露
  9. 练习4.1 根据后序和中序遍历输出先序遍历 (25 分)
  10. 小米手机线刷教程详解
  11. Google Earth Engine(GEE)——图表概述(记载图表库)
  12. MacOS Big Sur 11.2.3 (20D91) with Clover 5131 and OC 0.6.7 and PE 三EFI分区原版DMG黑苹果镜像
  13. 机器学习——马氏距离
  14. 统信UOS_arm64开发环境配置
  15. mysql查询每个部门的最高和最低工资_SQL数据库 计算出每个部门的平均工资 最高工资和最低工资 语法怎么写?...
  16. Pytorch、TorchVision、Python、Jetpack版本匹配问题
  17. 东辉职校计算机专业录取分数线,2016年上海东辉职校录取分数
  18. Java小游戏之掷骰子
  19. 《渡月桥 ~君想ふ~》
  20. LPDDR4x 的 学习总结(2) - SDRAM array结构浅识

热门文章

  1. Development Tools 错误解决
  2. Centos 7安装、配置SVN
  3. 微电网数字孪生 | 智能时代,部署源网荷储一体化管控平台
  4. python抓取经典评论_通过Python抓取天猫评论数据
  5. 免费个人网页制作指南Dreamweaver教程
  6. 任天堂媒体峰会召开,众多新作现场试玩
  7. LabVIEW与MATLAB混合编程——调用Matlab中.m的函数
  8. 听“元戎”首席架构师讲述华为云Serverless进化的故事
  9. Python爬虫实战(一) — Pixabay图片下载器
  10. VAPS XT航空仪表开发第一节